How do I found the routing http modules loaded? - asp.net

I am using the traditional Asp.Net website in which I am using the System.Web.Routing module. I want to find the way in which I know that the routing http modules is loaded or not?

All you need to know is the module's name as you have it configured in your web.config file
for example mine is named: "UrlRoutingModule" as you can see from this snippet here (formatted for StackOverflow):
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule, System.Web.Routing,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
once you have that, all you need to do is check the application's Modules property (which is of type HttpModuleCollection for your module's name and verify that it's not null. If you want to do some extra checking you can check the type of the object too (not shown).
// From Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
if (Modules.AllKeys.Contains("UrlRoutingModules")
&& Modules["UrlRoutingModule"] != null)
{
// the module is loaded
}
}

Related

Add custom response header to web.config

I have a website that is susceptible to a clickjacking vulnerability. Doing some research, it looks like one of the simple approaches is to simply add the X-Frame-Options: SAMEORIGIN to the response header. This is a very old web application (ca. last update was 2004), and is running IIS 6 with ASP.NET 2.0.
In newer versions, I could simply add the following section to the web.config
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
And that would be the end of it. However, I can't seem to be able to verify that this is possible using IIS 6.
Is this possible with IIS 6 and ASP.NET 2.0 to be done in only the web.config file? If so, how? If not, what code changes would I have to make in order to achieve the same result? Would simply adding
Context.Response.AddHeader("X-Frame-Options", "SAMEORIGIN");
to the Global.asax#Application_EndRequest be sufficient?
I don't believe that you'll be able to accomplish this solely by updating the web.config since you are targeting II6 (as support for the <customHeaders> section was added in IIS7+).
What you would likely need to do would be to create a custom HttpModule similar to the approach mentioned in this blog post that would handle actually adding the Header which might look something like this :
public class SameOriginHeaderModule : IHttpModule
{
private HttpApplication _application;
public void Init(HttpApplication context)
{
_application = context;
context.PreSendRequestHeaders += OnPreSendRequestHeaders;
}
void context_EndRequest(object sender, EventArgs e)
{
// If your request exists, add the header
if (_application.Context != null)
{
var response = _application.Response;
response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
}
}
public void Dispose()
{
}
}
You would then need to register this module within your web.config file as seen below :
<configuration>
<system.web>
<httpModules>
<add name="SameOriginHeaderModule" type="SameOriginHeaderModule" />
</httpModules>
</system.web>
</configuration>

ASP.NET MVC5 Customised Inbound Routing

I'm "playing" around with custom inbound URL routing and have came across a problem.
When I pass my custom route a URL to examine, that ends in *.+, my class is not fired when i submit the request.
An example URL would be "~/old/windows.html"
When I step through this in the debugger, my RouteBase implementation doesn't fire. If i edit the url that i pass to the constructor of my route to try to match against "~/old/windows", my implemetation is fired as expected.
Again, If i change the url ro examine to "~/old/windows." the problem reoccurs.
My Route Implementation is below :-
public class LegacyRoute : RouteBase
{
private string[] _urls;
public LegacyRoute(string[] targetUrls)
{
_urls = targetUrls;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath;
if (_urls.Contains(requestedURL, StringComparer.OrdinalIgnoreCase))
{
result = new RouteData(this, new MvcRouteHandler());
result.Values.Add("controller", "Legacy");
result.Values.Add("action","GetLegacyURL");
result.Values.Add("legacyURL", requestedURL);
}
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
In the RoutesConfig file I have registered my route like so :-
routes.MapMvcAttributeRoutes();
routes.Add(new LegacyRoute(new[]{"~/articles/windows.html","~/old/.Net_1.0_Class_Library"}));
Can anyone point out why there is a problem?
By default, the .html extension is not handled by .NET, it is handled by IIS directly. You can override by adding the following section in Web.config under <system.webServer> -
<handlers>
<add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
As pointed out here. The above will route EVERY .html file request to .NET, you might want to be more specific by providing a more complete path if you don't want your routing to handle every .html file.
I've found the problem, and I'm sure this will help out a lot of fellow developers.
The problem is with IIS Express that is running via Visual Studio.
There is a module configured in the applicationhost.config called :-
UrlRoutingModule-4.0
This is how it looks in file :-
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
You need to set the preCondition Parameter to "".
To do this :-
Run you app via Visual Studio
Right click on IIS Express in your system tray, select "Show All Applications"
Click on the project you wish to edit, then click the config URL.
Open the file with Visual Studio, Locate the module and ammend.
Hope this helps anyone else, who ran into a similar problem.

Fastest way to rewrite only one subpath

I have a website developed in Classic ASP.NET and running on IIS 7.5. It works okay. But now I have the task to add affiliate program to my website. I want my reflink to looks like www.mywebsite.com/r/userid. Well, I googled around and found I can:
Use UrlRewrite third-party HttpModules. As I understand, they are based on runAllManagedModulesForAllRequests="true" web.config setting. Theoretically, I can:
Set runAllManagedModulesForAllRequests="true" and do RewritePath in Application_BeginRequest manually. But my Application_BeginRequest already contains a bit of code. It is too heavy to send all pages, images etc. to Application_BeginRequest because of one rarely called URL.
So, the question is how can I rewrite only subpath that starts with www.mywebsite.com/r/, and do not call Application_BeginRequest for every image, css etc.? Best if no third-party things.
Well, finished up with HttpModule.
web.config:
<system.webServer>
<modules>
<add name="ReflinkModule" preCondition="" type="www.ReflinkModule" />
</modules>
</system.webServer>
ReflinkModule.cs:
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginRequest);
}
public void BeginRequest(Object source, EventArgs e)
{
if (HttpContext.Current == null)
return;
if (HttpContext.Current.Request == null)
return;
if (HttpContext.Current.Request.RawUrl == null)
return;
string start = "/r/";
if (!HttpContext.Current.Request.RawUrl.StartsWith(start))
return;
string key = HttpContext.Current.Request.RawUrl.Substring(start.Length);
HttpContext.Current.RewritePath("~/Xxxxx.aspx?r=" + key);
}

Http Handler is working in iis express and not working in iis server

I am going to implement HttpHandler in order to allow file downloading from my site based on session values. If the session exist allow the user to download the file otherwise redirect to index page which is the login page for the site. My code is working perfect in iis express when I run my website in iis server the handler is not working.
For IIS express the web.config file has the following sections which I have added. The below configuration is working in iis express.
<system.web>
<httpHandlers>
<add verb="*" path="*.pdf" type="QDMS.FileHandler" />
Same add tag for all the files to restrict downloading without session.
</httpHandlers>
</system.web>
The configurations for IIS servers which is not working is below.
<system.webServer>
<handlers>
<add name="Files" path="*.pdf,*.doc,*.docx,*.rar,*.zip,*.ppt,*.pptx,*.jpg,*.png,*.bmp,*.gif,*.html,*.htm,*.pps" verb="*" type="QDMS.FileHandler" resourceType="Unspecified" requireAccess="script" />
</handlers>
</system.webServer>
My File handler is below
using System;
using System.Web;
using System.Web.SessionState;
using QDMS.Old_App_Code;
namespace QDMS
{
public class FileHandler : IHttpHandler, IReadOnlySessionState
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
if (!CheckWetherTheRequestForFileExistOrNot(context)) return;
if (CheckUsersForFileDownloading(context))
context.Response.Redirect("~/index.aspx");
else
{
var rawURL = context.Request.RawUrl;
var dotIndex = rawURL.LastIndexOf(".", System.StringComparison.Ordinal);
var ext = rawURL.Substring(dotIndex);
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentType = MIMEEType.Get(ext);
context.Response.AddHeader("Content-Disposition", "attachment");
context.Response.WriteFile(rawURL);
context.Response.Flush();
}
}
public bool CheckWetherTheRequestForFileExistOrNot(HttpContext context)
{
string url = context.Request.RawUrl.ToLower().Trim();
if (url.Contains(".pdf") || url.Contains(".xls") || url.Contains(".xlsx") || url.Contains(".jpg") ||
url.Contains(".bmp") || url.Contains(".rar") || url.Contains(".doc") || url.Contains(".docx") ||
url.Contains(".png") || url.Contains(".gif") || url.Contains(".pptx") || url.Contains(".zip") ||
url.Contains(".ppt") || url.Contains(".pps") || url.Contains(".htm") || url.Contains(".html"))
return true;
else
return false;
}
public bool CheckUsersForFileDownloading(HttpContext context)
{
return (context.Session["FrontHiddenID"] == null) && (context.Session["HiddenID"] == null);
}
}
}
I am sure that in the section in the web.config file is not correct that is why it is not working. So I need suggestions to rectify my handlers section in web.config file.
Any advice and help regarding this issue will be higly appreciated
Your IIS handler should be like this :
<add name="Files" path="*.pdf" verb="*" type="QDMS.FileHandler" resourceType="Unspecified" requireAccess="Script" />
Two differences with your version :
only one file mask, you should register a handler for each file type
requireAccess="Script" with 'Script' having an upper-case 'S'
Hope this will help
To map a file-name extension in IIS 7.0 running in Classic mode
Open IIS Manager.
Expand the node for the Web server computer, expand Sites, and then expand Default Web Site.
Select the node for your application.
The Features View pane is displayed.
In Features View, double-click Handler Mappings.
On the Actions pane, click Add Script Map.
The Add Script Map dialog box is displayed.
In the Add Script Map dialog box, specify the following:
o Request Path. The name or file-name extension to map.
o Executable. The path of the .exe or .dll file that will handle the request. For Classic mode, specify the ASP.NET ISAPI extension (Aspnet_isapi.dll).
o Name. A descriptive name.
Click OK to close the Add Script Map dialog box.
Open the Web.config file for the application.
Locate the httpHandlers element of the system.web section and add an entry for the file-name extension.
To map a file-name extension in IIS 7.0 running in Integrated mode
Follow steps 1 through 3 of the previous procedure.
On the Actions pane, click Add Managed Handler.
The Add Managed Handler dialog box is displayed.
In the Add Managed Handler dialog box, specify the following:
o Request Path. The file name or file-name extension to map.
o Type. The type (class) name of the managed handler. If the handler is defined in the App_Code folder of the ASP.NET application, its type name will appear in the drop-down list.
o Name. A descriptive name.
Click OK to close the Add Managed Handler dialog box.

ASP.NET response.redirect with IIS7

I have a site that is up and running on IIS6 in Windows 2003, and a development environment in XP. Everything works just fine.
I have been forced to create a new development environment in Windows 7.
Since using this, I have found that Reponse.Redirect no longer works... in some situations!
I have the following code:
Response.Redirect(Globals.NavigateURL( PortalSettings.ActiveTab.TabID ));
It works fine on IIS6.
It also works fine in most of the site on IIS7.5. However in some pages, it's not.
I have looked at the returning header, and can see there is a GET response in the Request header, which is for the correct page it should redirect too, but it's not!
There is an RadAjaxPanel around the buttons used to fire this redirect, but in a parent control. The buttons not working are in a separate ascx control.
I have the following in my Web.Config that I've found from other similar posts:
<system.webServer>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
And
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
(both have ending tags)
But this hasn't helped.
Can anyone think of anything to try to get these working?
Have you tried
Response.Redirect(Globals.NavigateURL( PortalSettings.ActiveTab.TabID ), false);
This is not the perfect solution but a workaround -
private void Redirect(string url)
{
// Define the name and type of the client script on the page.
String csName = "RedirectScript";
Type csType = this.GetType();
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
// Check to see if the client script is already registered.
if (!cs.IsClientScriptBlockRegistered(csType, csName))
{
StringBuilder csText = new StringBuilder();
csText.Append("<script type=\"text/javascript\"> ");
csText.Append("window.location.href = {0} </", url);
csText.Append("script>");
cs.RegisterClientScriptBlock(csType, csName, csText.ToString());
}
}
Call from a page -
Redirect(Globals.NavigateURL( PortalSettings.ActiveTab.TabID ));
This will use JavaScript to let your page redirect.
You can move above method in a common utility class.

Resources