Web.Config/customErrors for 403

Discussion in 'ASP.NET / ASP.NET Core' started by AlanH, Dec 7, 2012.

  1. Greetings –

    I have my customErrors section which works find to trap typical errors. Recently I added an ipSecurity section to deny particular addresses of foreign bots from skewing my stats. The blocking works fine, however the customError page is not:

    I created a deny of my own address for test and received the default error page “HTTP Error 403.6 – Forbidden. The IP address from which you are browsing is not permitted to access the requested Web site.”.
    I’d like to use a custom error page instead but it’s not working. Here’s the dirt:

    Code:
        <customErrors mode="On" defaultRedirect="ErrorPage.aspx">
          <error statusCode="403" redirect="ErrorPage.aspx"/>
          <error statusCode="404" redirect="Error400Page.aspx"/>
          <error statusCode="410" redirect="Error410Page.aspx"/>
          <error statusCode="500" redirect="Error500Page.aspx"/>
        </customErrors>
    …
        <security>
          <ipSecurity allowUnlisted="true">  <!-- this line allows everybody, except those listed below -->
            <clear/>  <!-- removes all upstream restrictions -->
            <!-- TEST resolves to MyTown,  USA -->
            <add ipAddress="XXX.XXX.XXX.0" subnetMask="255.255.255.0"/>
    …
          </ipSecurity>
        </security>
    Note: ipAddress is a real valid address. What am I doing wrong? :confused:
    Thank you in advance, Alan
     
  2. Bruce

    Bruce DiscountASP.NET Staff

    The one you are setting is the ASP.NET custom error. you'll have to use the IIS error page

    <system.webServer>
    <httpErrors>
    <remove statusCode="403" subStatusCode="-1" />
    <error statusCode="403" prefixLanguageFilePath="" path="/error/403.aspx" responseMode="ExecuteURL" />
    </httpErrors>
    </system.webServer>
     
  3. I appreciate the input but something is not right.

    Item 1
    Code:
        <httpErrors>
          <remove statusCode="403" subStatusCode="-1" />
          <error statusCode="403" prefixLanguageFilePath="" path="error/ErrorPage.htm" responseMode="ExecuteURL" />
        </httpErrors>
    I presume the path pointed to my web domain root and not IIS.

    Item 2
    When enabled this way, and with my IP blocked, I get a blank page.

    Item 3
    <system.web>
    <customErrors… />
    Doesn’t matter is I have the section enabled or completely commented out; the results are the same and it appears not to work.

    Item 4
    Using My.DiscountASP.NET|Web Manager|IIS Tools|Custom Errors:
    • 404/500 errors work both as ASPX and HTM files with relative path to domain root.
    • If I clear the page so that there are no entries, Custom Errors in the web.config are ignored.

    Conclusion:
    • It appears that there is a mishmash of concept that is not fully operating. It used to be that Custom Errors in the web.Config worked. I have applications dating back 10 years that suggest it did. Now, it’s ignored and I have to use the Web Manager.
    • Setting httpErrors as prescribed results in a black page. I am using a generic static HTM page for the error and there is a copy at both the root and /error subdir – yet I cannot get the page to post; it’s blank.
    • With ISS Tools|Custom Errors blank, Custom Errors in the web.Config enabled, httpErrors enabled, and my IP Addy blocked, I get the generic IIS 403.6 error.

    Something is not working to spec, or I have the configuration bullocks’d. :confused:

    Do you have more information or example of functional web.Config that includes custom errors? Please don't be cryptic: Please include an example with file path and relative path so there's no misinterpretation :)

    Thank you. Alan
     
  4. I have more information:

    • Confirmed my site is using IIS 7.
    • customErrors applied to IIS 6 and below which is why my legacy apps worked. This section has now been commented out.
    • httpErrors is for IIS 7 and above.

    Presently, I am using this code:
    Code:
        <httpErrors errorMode="DetailedLocalOnly" defaultPath="/ErrorPage.htm" defaultResponseMode="ExecuteURL">
          <remove statusCode="401" subStatusCode="-1" />
          <remove statusCode="403" subStatusCode="-1" />
          <remove statusCode="404" subStatusCode="-1" />
          <remove statusCode="410" subStatusCode="-1" />
          <remove statusCode="500" subStatusCode="-1" />
          <error statusCode="401" path="http://www.MyWebsite.com/default.aspx" responseMode="Redirect" />
          <error statusCode="403" prefixLanguageFilePath="" path="/ErrorPage.htm" responseMode="ExecuteURL" />
          <error statusCode="404" prefixLanguageFilePath="" path="/Error400Page.aspx" responseMode="ExecuteURL" />
          <error statusCode="410" prefixLanguageFilePath="" path="/Error410Page.aspx" responseMode="ExecuteURL" />
          <error statusCode="500" prefixLanguageFilePath="" path="/Error500Page.aspx" responseMode="ExecuteURL" />
        </httpErrors>
    
    Results:
    • Redirects from existing directories work - but then it's hardcoded.
    • Redirects from non-existing dirs result in a blank page.
    • Accessing non-existing content results in a blank page.
    • Accessing website whejn IP Addy is blocked results in a blank page.

    Conclusion:
    I've succeeded in redirecting to blank pages - close, but not desirable. :rolleyes:

    The search continues. Alan
     
  5. Bruce

    Bruce DiscountASP.NET Staff

    actually

    <customError> handles ASP.NET errors, ie. extension that are handled by ASP.NET, eg. aspx, asmx, etc.

    <httpErrors> however, handles, pages that are NOT handled by asp.net, ie. .html, .gif, etc.
     
  6. Gosh Bruce, you know on my localhost - you are absolutely correct and it works like a champ. It should also work on my websever hosted out in the oort cloud, but it doesn’t. :(

    The only thing I can affect is httperrors (which displays a blank page for every statuscode error), or through the Control Panel|IIS Tools|Custom Errors – which constrains me to 404 and 500; not useful for 403.X.

    The short story for me as a client being hosted is that it is really a larger fur ball of a bug and no one has solved it without codebehind or by physically changing the file on the drive. This link explains it better:

    What to expect from IIS7 custom error module

    This page was posted in 2008, so it's still broken.

    If I disable httperrors (comment it out) and rely on basic customerrors 404 & 500, it won't work. So there's two problems - one of which appears I'll need to solve in codebehind (403), and the other is something altogether different. I filed a trouble ticket with Dasp.net.

    ~Alan
     
  7. Bruce

    Bruce DiscountASP.NET Staff

    Do you mind posting your web.config (without any sensitive info)?

    This behavior depends on what version of IIS you are on as well. What is your domain name? i can double check
     
  8. Sure. Thanks for asking :)
    ~Alan

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <configSections>
        <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
            <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
              <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
              <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
              <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
              <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
            </sectionGroup>
          </sectionGroup>
        </sectionGroup>
      </configSections>
      <appSettings>
        <!-- snip -->
      </appSettings>
      <connectionStrings />
      <system.web>
        <compilation debug="true">
          <assemblies>
            <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
            <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
            <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
          </assemblies>
        </compilation>
        <authentication mode="Windows" />
        <pages>
          <controls>
            <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
            <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </controls>
        </pages>
        <httpHandlers>
          <remove verb="*" path="*.asmx" />
          <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </httpHandlers>
        <httpModules>
          <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </httpModules>
        <customErrors mode="On" defaultRedirect="~/GenericErrorPage.htm">
          <!-- I know this next line won't work -->
          <error statusCode="403.6" redirect="~/NoAccess.htm" />
          <error statusCode="404" redirect="~/404.aspx" />
          <error  statusCode="500" redirect="~/500.aspx" />
        </customErrors>
      </system.web>
      <system.codedom>
        <compilers>
          <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
            <providerOption name="CompilerVersion" value="v3.5" />
            <providerOption name="WarnAsError" value="false" />
          </compiler>
        </compilers>
      </system.codedom>
      <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <!-- suggested fix to 403 error from DiscountASP.Forum -->
        <!--<httpErrors errorMode="Custom" existingResponse="PassThrough">
          <remove statusCode="403" subStatusCode="-1" />
          <error statusCode="403" prefixLanguageFilePath="" path="~/NoAccess.htm" responseMode="ExecuteURL" />
          <remove statusCode="404" subStatusCode="-1" />
          <error statusCode="404" prefixLanguageFilePath="" path="~/404.aspx" responseMode="ExecuteURL" />
        </httpErrors>-->
    
        <security>
          <!-- snip -->
        </security>
        <modules>
          <remove name="ScriptModule" />
          <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </modules>
        <handlers>
          <remove name="WebServiceHandlerFactory-Integrated" />
          <remove name="ScriptHandlerFactory" />
          <remove name="ScriptHandlerFactoryAppServices" />
          <remove name="ScriptResource" />
          <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </handlers>
      </system.webServer>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
    
     
  9. Bruce

    Bruce DiscountASP.NET Staff

    Try this

    <httpErrors errorMode="Custom" existingResponse="PassThrough">
    <remove statusCode="403" subStatusCode="-1" />
    <error statusCode="403" prefixLanguageFilePath="" path="/NoAccess.htm" responseMode="ExecuteURL" />
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" prefixLanguageFilePath="" path="/404.aspx" responseMode="ExecuteURL" />
    </httpErrors>

    I don't think it recognize "~"
     
  10. Bruce, I get a blank page. No joy :(

    I tried both incorrect directory and incorrect filename; both result in a blank page; source below.

    HTML:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML><HEAD>
    <META content="text/html; charset=windows-1252" http-equiv=Content-Type></HEAD>
    <BODY></BODY></HTML>
    
    Weird, huh.
    ~Alan
     

Share This Page