http module cant get correct page url - url

Hi i got a very noob question to ask . I am using http module to do a access right. Let say the user is 'admin' then he got authorized to view the page.The http module will get the access right from the database based on the page url, thereafter the http module will determine the user is allowed to access or not .
Here is my sample coding :
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(context_AcquireRequestState1);
}
void context_AcquireRequestState1(object sender, EventArgs e)
{
try
{
string requestUrl = application.Request.AppRelativeCurrentExecutionFilePath.ToString().Trim();
//return last string of .aspx
string requestAspx = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1).Trim();
}
but the httpmodule will run several time. It cant get the url correctly.
For example first time it may get ~/Module/Admin/Role/RoleManagementList.aspx.
then second time will get the wrong url ~/favicon.ico.Can anyone help me solve this problem? thank you so much

You are not getting the "wrong" url. The user's browser is simply making a different request for a different resource. You http module will execute for each http request, which will mean one for each resource in addition to the "page" such as favicons (displayed in the browsers url, and sometimes requested even if you don't have one) or images, external .css, external .js files, etc. referenced on the page (unless they are directly served by IIS bypassing the ASP.NET stack). You will need to consider all of these urls in your module.
Depending on how tightly you control your deployment environment,you may also/instead be able to exempt certain file extensions from every hitting asp.net by having IIS simply serve them directly. See http://msdn.microsoft.com/en-us/library/ms972953.aspx

Related

How can I redirect to a particular view based on url in grails

I am using grails 2.5.5 version, Suppose I am entering url as www.localhost:8080/app-name then it should open the MyHome.gsp, suppose if I give other url ex: demo1.localhost.com:8080/app-name then it should redirect to some login page like login.jsp. How can I do that?
Let me break it up for you :
Suppose I have www.localhost:8080/app-name
suppose if I give other url ex: demo1.localhost.com:8080/app-name
Your app starts here:
Case 1 :/app-name
case 2 :/app-name
The rest of that url is actually DNS and configurating binding tomcat specific or wild card urls to a given application.
So in short you need to filter entire url in the application parse url and redirect in your app accordingly.
You need to then intercept every url with grails 2 there is SecurityFilters which so far as i know works with apache-shiro may also work with spring security.
and within it you need to overall check for something like
URL url = new URL(request.getRequestURL().toString())
String subdomain=url.host
if (subdomain.contains('.')) {
subdomain= subdomain.split('.')[0]
}
that then returns your `demo1` you then redirect it another url if it matches your specific rule.
But as I said you are talking about superficial stuff here as I expressed what the address is or how somone gets to the app has nothing to do with the actual application. This is why IT is big business. Big business not because everyone tries to narrow everything down into one box doing all of this but because when situations likes this happen bigger thinking is needed i.e. do i need a load balancer something like F5 that will split traffic according to a given url and send to another app container that asks for authorisation.
subdomain= subdomain.split('.')[1] in that case then but this leaves room for errors since user could put in demo1.somedomain.com and if that resolves well it is either split by subdomain= subdomain.split('.')[0]
I would do this then
String subdomain=url.host
if (subdomain.contains('.')) {
def splitter= subdomain.split('.')
subdomain= splitter[0]
if (subdomain=='www' && splitter.size()>1) {
subdomain= splitter[1]
}
}

Web page without real files corresponding to URLs?

geniuses!
I need to make a demo page acting like DBpedia (http://dbpedia.org).
Two pages from different URLs,
http://dbpedia.org/page/Barack_Obama and
http://dbpedia.org/page/Lionel_Messi,
show different content.
I cannot really think DBpedia has million pages for all individual entities (E.g., Barack Obama and Lionel Messi).
How can I handle such URL request?
I know a bit about GET request but example URLs above do not seem like to use GET method.
Thank you in advance!
ps. Please teach me the process. Something like:
1. A user enters URL on a browser.
2. ...
When visiting http://dbpedia.org/page/Barack_Obama, your browser does send a GET request, e.g.:
GET /page/Barack_Obama HTTP/1.1
Host: dbpedia.org
The server (dbpedia.org) receives this GET request and then decides what to do. From the outside, you can’t know (for sure) how the server does something. The two common cases are:
Static web page: a file gets served that exists somewhere on the server. The URL path is often mapped to the server’s file system, but that’s not necessarily the case.
Dynamic web page: a file gets served that is generated on the fly. The content often comes from a database, but that’s not necessarily the case.
After trying some solutions, I'm now using Spring Web MVC framework.
Maybe Dynamic web page solution mentioned in unor's answer.
#Controller
public class SimpleDisplayController {
#RequestMapping("/page/{symbolicName:[!-z]+}")
public String displayEntity(HttpServletRequest hsr, Model model) {
String reqPath = (String) hsr.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String entityLb = reqPath.substring(reqPath.lastIndexOf("/"));
model.addAttribute("label", entityLb);
return "entity";
}
}
I could get request using regex as you can see at the 4th line: #RequestMapping("/page/{symbolicName:[!-z]+}").
The function above returns the string 'entity' which is the name of a HTML file serving as a template.
The following code is a body part of the example HTML template.
<body>
<p th:text="'About entity ' + ${label} + '...'" />
</body>
Since I add an attribute with the key 'label' in the controller above, the template can process ${label}.
In the example HTML template, th:text is a snytax of Thymeleaf (Java library to make an XML/XHTML/HTML5 template) which is supported by Spring.

Rails 404 handler for non-Rails URLs

I've inherited a site with hundreds of scattered HTML and non-framework PHP files, which I am porting to Ruby on Rails 3.0.
As functionality is added in the Rails app, the corresponding pages are deleted from the document root; but, because there are often links to these in Google or from external sites, simply returning a 404 is not acceptable.
A URL like '/contact.php' should redirect to '/app/contact/', for example.
For the first few cases of this, I created simple stub html files at the old locations, with Meta tags within to perform the redirect. This doesn't scale well, particularly once I start replacing product pages, of which there are thousands.
My preference is to delete the old pages, then have the 404 handler dispatch these to the new Rails app, which will examine the URL using regexes and database lookup to try to figure out what the replacement page is, then issue a 301 redirect to that new page.
In httpd.conf, I placed the directive:
ErrorDocument 404 /app/error/handle404
# /app/error is a rails url.
When I hit "http://localhost/does-not-exist", this causes my ErrorController to be invoked, as expected.
However, within the controller, I cannot find the original path ("/does-not-exist") anywhere in request, request.headers, or ENV - I've been calling likely methods like request.request_uri (which contains /app/error/handle404), and examining request.headers and ENV without finding the expected original path.
The Apache access_log shows only the request for /does-not-exist, indicating that it transparently invoked /app/error/handle404 (without doing a redirect or causing a second request to be made).
How can I get access to the original URL?
Edit: to clarify, here is the sequence of events:
User hits legacy path like http://mysite/foo.php, probably coming from some ancient link from a blog.
...but foo.php no longer exists!
this is a 404, thus Apache invokes ErrorDocument
directive is "ErrorDocument 404 /railsapp/error/handle404"
Rails routes this to ErrorController action "handle404" - this is working correctly
problem: in ErrorController, request.request.uri, request.headers do not provide any clue as to which URL the user was actually trying to get to, like "/foo.php"; I need to know the original URL to serve up an appropriate replacement page.
As I couldn't find the original, non-rewritten URL in the Rails request, I ended up doing it in PHP - plain, old-fashioned, non-framework PHP with explicit mysqli_*() calls.
The PHP error handler receives the necessary information in the $_SERVER hash; $_SERVER['REQUEST_URI'] contains the original URI that I needed.
I look this up in a database, and if I find a corresponding entry, issue a 301 redirect to the new location; if there's no entry, I simply display a 404 page to the user.
Simplified (PHP):
$url = $_SERVER['REQUEST_URI'];
$redir = lookupRedirect($url); # database stuff here
if (! $redir) {
include ('404.phtml');
} else {
header("Status: 301");
header("Location: " . $redir['new_url']);
}
It's an ugly kluge, but I just couldn't find a way to make the Rails app aware of the error URL.

Get current fragment in Route, ASP.net MVC

Is there away to get the current fragment from a route that was issued via action link. This is how I am getting the action from the route.
string currentAction = requestContext.RouteData.Values["action"] as string ?? "index";
Can I do something similar to this?
string currentFragment = requestContext.RouteData.Values["Fragment"] as string ?? "";
No, you can't do anything like this. The fragment (everything that follows the # sign in an url) is never sent to the server by the browser, so the sole fact of talking about getting the url fragment server side simply doesn't make sense.
So if you have the following url: http://example.com/foo/bar?key1=value1#abc the server will never be able to fetch abc simply because the client will never send it.
As it has already been pointed out that is not possible. Document fragments (the string after the hash as you call it) are intended for the browsers only to correctly position the viewport. They have no meaning for the server and therefore are not transmitted there.
There is however a workaround you can use. Repeat the fragment as part of your url to make it accessible for the server.
Look at the permalink to the answers in this question. For instance, the link to my answer looks like this:
http://stackoverflow.com/questions
/6285833/get-current-fragment-in-route-asp-net-mvc/6286097#6286097
See how the value 6286097 is duplicated as the last route parameter. It's intentional. You can use this technique as well.
P.S. The fragment must point to an identifier in the document (id of some HTML element). At least in XHTML only identifiers work as fragments. Valid ids may not begin with a digit therefore instead of #6286097 use something like #answer-6286097.
P.S.#2. Do not use any JavaScript trickery to get around this limitation. Basic site functionality and design must work without JavaScript - don't listen to anyone who tells you otherwise. Fragments obviously belong to the basic tool box. Use JavaScript only for advanced interactivity.
I have a workaround for you, but first of all lets get more into the problem.
The strings after the hash symbol which are called Fragment values are not query parameters but they are strings to be read by the client-side (living in the browser) and the server cannot read them because they are not sent to the server by the browser.
Some authentication providers like Google and Azure send the access token as Fragment value for security reasons so that they are not transferred over the internet after they get sent as direct response from the authentication provider.
The only way you can come around that is to use javascript to convert the fragment values to query parameters by replacing the '#' with '?' and redirecting to the endpoint in your server controller.
I suppose the easiest way is to handle all that from server, meaning you get get the request in server, send a javascript code to the browser on the fly, that replaces the '#' into '?' and redirects to your second endpoint which reads the token as strong parameter.
Here how you can do it in ASP.NET Core 3.1:
[AllowAnonymous]
[HttpGet("authredirect")]
[Produces("text/html")]
public virtual ContentResult ConvertUrlFragmentToQueryParamThenRedirect()
{
return Content("<html><script>window.location.href=window.location.href.replace('#', '?').replace('authredirect', 'authparams')</script></html>", "text/html");
}
[AllowAnonymous]
[HttpGet("authparams")]
public virtual void GetAccessToken([FromQuery] string access_token)
{
// now you have your access token server side here
}
Please remember to set your redirectUrl to the correct one, in this case 'YOUR REDIRECT URL/authredirect'.

Extending Asp.Net MVC routing mechanism

I've found a limitation in the routing mechanism for ASP.Net mvc and I'm trying to find a workaround.
I posted a related question here about the issue I was having.
The gist of the problem is that routes that end with a . (period) are never handled by the default routing mechanism. A "Resource Cannot Be Found" error is always thrown. For example it cannot handle these urls:
http://www.wikipediamaze.com/wiki/Washington,_D.C.
http://www.wikipediamaze.com/wiki/anythingendinglikethis.
if I change it to querystring parameter like this it works fine:
http://www.wikipediamaze.com/wiki/?topic=Washington,_D.C.
I'm trying to find an extensibility point in the routing mechanism that will help me resolve this issue. I've tried other solutions like this:
//Global.asax.cs
protected void Application_Error()
{
var url = HttpContext.Current.Request.RawUrl;
if(TopicRegex.IsMatch(url))
{
var fixedUrl = FixUrlPath(url);
//This throws an error
Response.Redirect(fixedUrl);
//This also throws an error
Server.Transfer(fixedUrl );
}
}
I'm guessing that the Response.Redirect and Server.Transfer throw errors because in MVC you should be calling the RedirectToAction methods from the controller. Of course I can't even get to the controller.
This seems to be a pretty big limitation considering the Apache server that Wikipedia uses handles this just fine. try it out http://en.wikipedia.org/wiki/Washington,_D.C. If anyone could please offer some help here I would appreciate it.
Could you turn of checking file exists in the routes but allow certain extensions through?
routes.RouteExistingFiles = true;
// Ignore the assets directory which contains images, js, css & html
routes.IgnoreRoute("Assets/{*pathInfo}");
// Ignore text, html, files.
routes.IgnoreRoute("{file}.txt");
routes.IgnoreRoute("{file}.htm");
routes.IgnoreRoute("{file}.html");
routes.IgnoreRoute("{file}.aspx");

Resources