views:

222

answers:

2

I have written a custom forms authentication module and when I add it to the web.config of my MVC2 application and run under IIS7.5 I get the HTTP 403.14 error. If I try to navigate to any of the routed Urls then I simply get a 404 error. The annoying thing is that I did all the testing using Cassini with no problems at all. I have applied all of the fixes from all similar issues to no avail. The problem seems to be that with my module registered Mvc Routing stops working. Clearly it would seem to implicate my module but why has it worked all this time using the built-in webserver? Here is the System.x parts of my web.config:

  <system.web>
    <compilation debug="true" defaultLanguage="c#" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
                <add assembly="Ewdev.Gatekeeper.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=02ca582b160d0e09" />
            </assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms defaultUrl="/" loginUrl="/Authentication/Login" enableCrossAppRedirects="true" name=".GKAUTH" path="/" requireSSL="false" timeout="1440" />
    </authentication>
        <membership defaultProvider="GatekeeperMembershipProvider" userIsOnlineTimeWindow="120">
      <providers>
        <clear />
        <add name="GatekeeperMembershipProvider" type="Ewdev.Security.MembershipProviders.GatekeeperMembershipProvider, Ewdev.Gatekeeper.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=02ca582b160d0e09" connectionStringName="Ewdev Database" minRequiredPasswordLength="7" minRequiredAlphabeticCharacters="3" minRequiredAlphabeticCaseChanges="1" minRequiredNumericCharacters="1" minRequiredNonAlphanumericCharacters="0" passwordWordsPolicy="true" passwordHistoryPolicy="13" enablePasswordRetrieval="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" minRequiredUserNameLength="6" minRequiredUserNameAlphabeticCharacters="1" minRequiredUserNameNumericCharacters="0" userNameEnableNonAlphanumeric="true" userNameWordsPolicy="true" />
      </providers>
    </membership>
    <customErrors mode="On" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Linq" />
        <add namespace="System.Collections.Generic" />
      </namespaces>
    </pages>
        <trace enabled="false" mostRecent="true" />
  </system.web>
    <system.webServer>
        <validation validateIntegratedModeConfiguration="true" />
        <modules runAllManagedModulesForAllRequests="true">
            <remove name="FormsAuthentication" />
            <add name="FormsAuthentication" type="Ewdev.Security.GatekeeperFormsAuthenticationModule" preCondition="" />
        </modules>
        <handlers>
            <remove name="MvcHttpHandler" />
            <add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler" />
            <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </handlers>
    </system.webServer>

This is all running on my Windows 7 x64 desktop with VS2010, .NET 4 and Mvc2. I have ASP.NET4 installed/registered in IIS. I suspect you will probably want to know what is in the module but the source is rather long so I do not know which bit would be relevant. It is built to the same API specification as the built-in one but apart from redirecting to the Login page when needed there are no other alterations to the request Url and the error appears when trying to display the home page which is open to everyone. I have read that it might be something to do with non-aspx resources such as script, css, image files as modules are set to be applied to all resource types? Other ideas have been along the lines of my module being called after the Url routing module, but I am not convinced about that one, and thirdly that the Global.asax might not be being called? I am in my 3rd day tearing my hair out on this one, mainly because I estimated 1hr to install the website onto IIS... Doh!

Would appreciate any help I can get and quite happy to rewrite my module if only I could work out what bit IIS does not like. Cassini loves it :-(

A: 

My guess is that you set your MvcHttpHandler wrong. The path attribute should be * instead of *.mvc

ZippyV
No this was a red herring the MvcHttpHandler was an MVC 1 thing and is no longer used for MVC 2 but I was trying anything, especially if it had anything to do with routing.
A: 

I have a solution at last! But it was obscure to the extreme and has taken me best part of a week to guess.

I was convinced the problem had something to do with routing and many people were saying that you needed to add the HTTP Redirection special role. I had already added that as well as HTTP Error and Static Content Compression. The solution in the end was to re-install these 3 roles! It would suggest that the order of installing things in the IIS world is very important because I had already set up IIS7.5 before installing MVC2 (via VS2010 install) and even though I had done the other fix many many times (aspnet_regiis -i for ASP.NET 4.0 x86 and x64) this had not fixed the routing issue. Had I installed VS2010 first (with MVC2 included) and then installed IIS7.5 I suspect I would not have had the problem. Except that, believe it or not, a full re-install of IIS7.5 did NOT fix the problem as I had already tried that several days ago. So to recap and include any other necessary configuration the following are the important fixes:

  1. Ensure you have run aspnet_regiis -i for both Framework/v4... and Framework64/v4...

  2. Ensure you have allowed ASP.NET v4 for both 32-bit and 64-bit in IIS (via the IIS Manager, click on the Server entry in the tree and go to ISAPI and CGI Restrictions)

  3. Ensure you have HTTP Error and HTTP Redirection common HTTP IIS special roles and Static Content Compression performance IIS special role installed. And if you have then un-install and re-install, this is what eventually fixed the issue for me.

Please note: This is also the case for IIS7 as I had to do exactly the same procedure on the production Windows 2008 server. I hope that this helps others to a speedy solution. I will probably now lose my contract as I am so far behind because of this problem.

My original web.config turned out to have several uneccessary entries in it, because I was trying any and every solution that people were coming up with, so the following is the System.x parts of my current and working web.config:

  <system.web>
    <compilation debug="true" defaultLanguage="c#" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <add assembly="Ewdev.Gatekeeper.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=02ca582b160d0e09" />
      </assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms defaultUrl="/" loginUrl="/Authentication/Login" enableCrossAppRedirects="true" name=".GKAUTH" path="/" requireSSL="false" timeout="1440" />
    </authentication>
    <membership defaultProvider="GatekeeperMembershipProvider" userIsOnlineTimeWindow="120">
      <providers>
        <clear />
        <add name="GatekeeperMembershipProvider" type="Ewdev.Security.MembershipProviders.GatekeeperMembershipProvider, Ewdev.Gatekeeper.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=02ca582b160d0e09" connectionStringName="Ewdev Database" minRequiredPasswordLength="7" minRequiredAlphabeticCharacters="3" minRequiredAlphabeticCaseChanges="1" minRequiredNumericCharacters="1" minRequiredNonAlphanumericCharacters="0" passwordWordsPolicy="true" passwordHistoryPolicy="13" enablePasswordRetrieval="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" minRequiredUserNameLength="6" minRequiredUserNameAlphabeticCharacters="1" minRequiredUserNameNumericCharacters="0" userNameEnableNonAlphanumeric="true" userNameWordsPolicy="true" />
      </providers>
    </membership>
    <customErrors mode="On" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Linq" />
        <add namespace="System.Collections.Generic" />
      </namespaces>
    </pages>
    <trace enabled="false" mostRecent="true" />
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="true" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="FormsAuthentication" />
      <add name="FormsAuthentication" type="Ewdev.Security.GatekeeperFormsAuthenticationModule" />
    </modules>
  </system.webServer>