NullReferenceException only cleared up by using "runAllManagedModulesForAllRequests="true"? - asp.net

I have created an MVC5 application that works fine on my local machine, but throws a NullReferenceException when using the AuthorizeAttribute on our test server (Server 2008 and IIS 7). I can clear it up with
runAllManagedModulesForAllRequests="true" in the web.config file, but I know this is not a clean fix.
If have already found the exact same question here but no answers have been put forth yet, and I can find no suggestions anywhere else that do not involve this approach. Surely there must be a better way than runAllManagedModulesForAllRequests="true" to solve the null reference problem (although this does, indeed, clear up the error)?

IIS and IIS Express have some differing behaviors for request authentication. The HttpContext.User.Identity property may not be set when the AuthorizeAttribute.AuthorizeCore() method executes (hence the NullReferenceException), due the fact that the form authentication module does not always run.
You could change the precondition for only the FormsAuthenticationModule instead of loading all modules for all requests. By default, the FormsAuthenticationModule has: preCondition="managedHandler".
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="" />
</modules>
</system.webServer>

Related

ASP.NET MVC security and IIS allowSubDirConfig configuration

I've got informed that following the general Microsoft recommendation our web servers will be reconfigured; among other things the allowSubDirConfig setting should be set to false. Thus, our ASP.NET applications must use a single Web.config at their root level (which is quite okay for our applications by the way).
However, ASP.NET MVC uses a "non root level" configuration file (by default!) for the Views directory, which contains a simple (but important?) web server related section:
<system.webServer>
<handlers>
<remove name="BlockViewHandler" />
<add name="BlockViewHandler"
path="*"
verb="*"
preCondition="integratedMode"
type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
Regarding to a post by Phil Haack this is security related, hence important.
Since the other .NET Framework related sections still work, because the ASP.NET runtime does not obey the allowSubDirConfig setting, an ASP.NET MVC application still works too. So the ignored web server configuration doesn't really attract attention during general usage, although i've a bad feeling about it.
Isn't that a lousy idea? If web servers are configured that way (by recommendation), how vulnerable are those ASP.NET MVC applications out there?
The HttpNotFoundHandler has a path attribute which means you can add it to the root config file and point path to the Views folders and you would not be altering the security level in any way:
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="Views/*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
This will work with a basic web.config file, but beware if you are adding/removing handlers as part of your application. Handlers that come before the BlockViewHandler could still deliver content from the Views subfolder (but then I believe this is also the case with the standard web.config in the Views directory unless you remove the handler there specifically).
Generally speaking IIS will not serve .cshtml files from the Views folder (unless specifically allowed) even if the system.webServer section is missing/ignored in the Views subdirectory.
But it would serve other files (e.g. html,css,js) which would be blocked by the BlockViewHandler handler which could be regarded as reduced security.

ASP.NET MVC 5 Web.config: "FormsAuthenticationModule" or "FormsAuthentication"

Ok so this not a big deal, but it's bugging me and I can't let it go.
So I'm using MVC 5.1 with .NET 4.5.1 and OWIN authentication. So when you create a new MVC 5 project, the following is automatically added to the Web.config to get rid of the forms authentication http module because it is no longer needed when using OWIN middleware:
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
</modules>
</system.webServer>
Now since we are removing the module, that means it was previously added, so here is the entry registering this http module in C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config:
<httpModules>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
</httpModules>
And here is the entry in C:\Windows\System32\inetsrv\config\applicationHost.config for IIS 8.5 that tells my application to use the module:
<system.webServer>
<modules>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
</modules>
</system.webServer>
So what is automatically added to my web config at the application level has a name attribute of "FormsAuthenticationModule" while the entries in the two server level/asp.net level config files use name attribute "FormsAuthentication". So what is going on here? It seems to me that the module won't be removed since the name attribute doesn't match. I would simply think this was a typo, but after searching online, everyone seems to be using "FormsAuthenticationModule" in the application web.config. Was this a recent change in the newer version of asp.net / iis or am I missing something?
You're right -- that's a typo in the template.
A major side effect of this "typo" is it will leave FormsAuthentication on causing loginpath of owin to be ignored and calls to authenticated pages going to /login.aspx

ASP.NET Web API application gives 404 when deployed at IIS 7

I have an ASP.NET Web API which works fine when running on "IIS Express" with localhost:1783
But when I uncross the "Use IIS Express" and then press "Create Virtual Directory"...
...I just get 404 errors:
Any ideas whats wrong? Thanks!
All you really need to add to the web.config file is:
<handlers>
<!-- Your other remove tags-->
<remove name="UrlRoutingModule-4.0"/>
<!-- Your other add tags-->
<add name="UrlRoutingModule-4.0" path="*" verb="*" type="System.Web.Routing.UrlRoutingModule" preCondition=""/>
</handlers>
Note that none of those have a particular order, though you want your removes before your adds.
The reason that we end up getting a 404 is because the Url Routing Module only kicks in for the root of the website in IIS. By adding the module to this application's config, we're having the module to run under this application's path (your subdirectory path), and the routing module kicks in.
For me, in addition to having runAllManagedModulesForAllRequests="true" I also had to edit the "path"
attribute below. Previously my path attribute was "*." which means it only executed on url's containing a dot
character. However, my application's url's don't contain a dot. When I switched path to "*" then it worked.
Here's what I have now:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
You may need to install Hotfix KB980368.
This article describes a update that enables certain Internet Information Services (IIS) 7.0 or IIS 7.5 handlers to handle requests whose URLs do not end with a period. Specifically, these handlers are mapped to "." request paths. Currently, a handler that is mapped to a "." request path handles only requests whose URLs end with a period. For example, the handler handles only requests whose URLs resemble the following URL:
http://www.example.com/ExampleSite/ExampleFile.
After you apply this update, handlers that are mapped to a "*." request path can handle requests whose URLs end with a period and requests whose URLs do not end with a period. For example, the handler can now handle requests that resemble the following URLs:
http://www.example.com/ExampleSite/ExampleFile
http://www.example.com/ExampleSite/ExampleFile.
After this patch is applied, ASP.NET 4 applications can handle requests for extensionless URLs. Therefore, managed HttpModules that run prior to handler execution will run. In some cases, the HttpModules can return errors for extensionless URLs. For example, an HttpModule that was written to expect only .aspx requests may now return errors when it tries to access the HttpContext.Session property.
This issue can also happen due to the following
1.In the Web.Config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
2.Make sure the following are available in the bin folder on the server where the Web API is deployed
•System.Net.Http
•System.Net.Http.Formatting
•System.Web.Http.WebHost
•System.Web.Http
These assemblies won't be copied in the bin folder by default if the publish is through Visual Studio because the Web API packages are installed through Nuget in the development machine. Still if you want to achieve these files to be available as part of Visual Studio publish then you need to set CopyLocal to True for these Assemblies
Some people say runAllManagedModulesForAllRequests="true" will have performance issues and MVC routing issues.
They suggest to use the following:
http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html
http://bartwullems.blogspot.com/2012/06/optimize-performance-of-your-web.html
I have been battling this problem for a couple of days trying all kinds of things suggested. My dev machine was working fine, but the new machine I was deploying to was giving me the 404 error.
In IIS manager, I compared the handler mappings on both machines to realize that a lot of handlers were missing. Turns out that ASP.Net 5 was not installed on the machine.
For me, this issue was slightly different than other answers, as I was only receiving 404s on OPTIONS, yet I already had OPTIONS specifically stated in my Integrated Extensionless URL Handler options. Very confusing.
As others have stated, runAllManagedModulesForAllRequests="true" in
the modules node is an easy way to blanket-fix most Web API 404 issues - although I prefer #DavidAndroidDev 's answer which is much less intrusive. But there was something additional in my case.
Unfortunately, I had this set in IIS under Request Filtering in the site:
By adding the following security node to the web.config was necessary to knock that out - full system.webserver included for context:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<security>
<requestFiltering>
<verbs>
<remove verb="OPTIONS" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
Although it's not the perfect answer for this question, it is the first result for "IIS OPTIONS 404" on Google, so I hope this helps someone out; cost me an hour today.
I had this problem with Blazor and .Net Core and found that incorporating the NavManagers "baseUrl" into my calls to the controller solved the issue regardless of using a Virtual Directory or the root website.
This worked for me!
string baseUrl = NavigationManager.BaseUri.ToString();
NavigationManager.NavigateTo(**baseUrl** + $"api/Download/DownloadFile?FileName="
+ sFilename, true);
I you are using Visual Studio 2012, download and install Update 2 that Microsoft released recently (as of 4/2013).
Visual Studio 2012 Update 2
There are some bug fixes in that update related to the issue.
I had as same problem . afer lot of R&D i found the problem.
but as long as your configuration are finne mean that aspnet 64 bit and the IIS well then
the only problem i saw is the path " web api taking the local directiry path" so that you need to avid it. by like this.. ~../../../api/products/
thank you very much for posting the problem. i leanred alot abt iis and other setting in config file.
For me I received a 404 error on my websites NOT using IIS Express (using Local IIS) while running an application that WAS using IIS Express. If I would close the browser that was used to run IIS Express, then the 404 would go away. For me I had my IIS Express project calling into Local IIS services, so I converted the IIS Express project to use Local IIS and then everything worked. It seems that you can't run both a non-IIS Express and Local IIS website at the same time for some reason.
Spend a whole week, after all the following setting worked ! and finally saved.
Removing the UrlScan from ISAPI fileters in IIS fixes the problem in our case

HttpHandler not being called

I need to write a HttpHandler that will serve up JavaScript files which are embedded resources in .DLLs in my project. A reference in a view cannot directly see such a resource, so I planned to use a HttpHandler module that would intercept any request with a path /js/[file] , find a matching embedded file and return the script.
The problem is that my HttpHandler code is never called, despite trying lots of different settings in the section of web.config. I'm obviously missing something but with no error messages I cannot see what that is. All I ever get is a 404 from the static file handler.
Q1) Am I missing something obvious?
Q2) Is there a way to get IIS to tell me why it is not calling my handler?
Summary: I am testing on IIS Express (v8) for an ASP.NET MVC 4 application.
I created a simple library that implements IHttpHandler and added a reference to this in my test MVC application, and the following lines in web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="true" />
<handlers>
<add name="ejs" path="js/*" verb="*" type="EmbeddedJsHandler.EmbeddedJsHandler, EmbeddedJsHandler" preCondition="integratedMode" />
The library is there, but it is never called. Any request with /js/test.js or whatever just results in a 404 error.
So far I've tried lots of different configurations and settings in the handler code. I've tried preCondition, resourceType="Unspecified", modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll"
I've tried paths:
js/*.js
js/*
js/*.*
I've checked the integrated mode settings section (in system.webServer) is being used, and confirmed it is.
I've searched stack overflow for similar cases, and tried many of the possible solutions.. still no joy.
Heck even Jon Skeet has these sort of problems!
Why isn't my IHttpHandler being called?
Finally figured it out by accident - it was a missing routes.IgnoreRoute() in the RouteConfig.cs file - the MVC routing engine wasn't configured to ignore this path, so was passing it to the static file handler.
Doh!
Check this:
How to: Register HTTP Handlers:
To register an HTTP handler for IIS 7.0 running in Integrated Mode:
Compile the HTTP handler class and copy the resulting assembly to the Bin folder under the application's root folder.
In the application's Web.config file, create a handlers element in the system.webServer section.
The following example shows how to register an HTTP handler that responds to requests for the SampleHandler.new resource. The handler is defined as the class SampleHandler in the assembly SampleHandlerAssembly.
<configuration>
<system.webServer>
<handlers>
<add name="SampleHandler" verb="*"
path="SampleHandler.new"
type="SampleHandler, SampleHandlerAssembly"
resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
Note: The resourceType attribute performs the same function as the Verify file exists option in IIS manager for IIS 6.0.
For IIS 7.0 running in Integrated mode, only the registration in the handlers element is required.
I cannot tell you directly why your handler isn't working, but I will give you an example of a handler we use and works for us:
<system.webServer>
<handlers>
<add name="JS handler" path="*.js" verb="*" type="Handlers.Minifiers.JSMinify" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
We also have this segment, which is at least necessary for running in Cassini
<system.web>
<httpHandlers>
<add verb="*" path="*.js" type="Handlers.Minifiers.JSMinify" validate="false"/>
</httpHandlers>
</system.web>
If this doesn't help, have tou tried using path="/js/*"?

How to make static Html page go through HttpModule in IIS7.0?

I have created a simple HttpModule which removes whitespaces from response before sending it to the client. This works fine for an aspx page on IIS7.0 but if i create a static html page and call it, the HttpModule does not kick in (the way i know is because the source contains whitespaces, which otherwise should have been removed). Apparently there is something i m not doing right, but dont know what.
My website is in an Application Pool with .NET 4.0 and ManagedPipelineMode = Integrated.
I have added my module as a ManagedModule and refers to an strong-name-key assembly from GAC.
thanks
Edit- here is the system.webserver part from web.config
<system.webServer>
...
<modules runAllManagedModulesForAllRequests="true">
<add name="RemoveWhitespaceHttpModule"
type="HttpModules.Modules.RemoveWhitespaceHttpModule, HttpModules,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=8a83u4bi47o9fo0d"
preCondition="" />
</modules>
<defaultDocument>
<files>
<add value="TestForm.aspx" />
</files>
</defaultDocument>
</system.webServer>
Edit- Fixed it. For anyone interested, this is how my module checks the response and then decides whether to proceed with whitespace removal or not
if (contentType.Equals("text/html")
&& httpContext.Response.StatusCode == 200
&& httpContext.CurrentHandler != null)
{ ... }
The problem was with the third condition above httpContext.CurrentHandler != null. when calling this module for static .html pages, the currentHandler was null and hence the code never went inside to manipulate html. i have removed this third condition and it works now. thanks for your answers everyone
This should do the trick, in the web.config:
<modules runAllManagedModulesForAllRequests="true"></modules>
This is a quick and easy solution, but can cause issues / performance issues.
You need to look at the Handler Mapping in your IIS.
How a handler works is that on IIS, the handler is registered and supposed to handle a particuler type of page. You can look at the "Handler Mappings" in the IIS [In the run command type inetmgr and hit enter. IIS Manager will pop up and look for Handler Mappings in the IIS section.]

Resources