3

We've just migrated our website to new webservers, in the process going from IIS6 to IIS8. Everything works as expected, except for one thing. Whenever a user loads a page after their session forms authentication has expired, they trigger a null reference exception.

The users themselves get redirected correctly to the login page, as we would expect, but apparently the original page loaded keeps executing, and once it reaches a part of the page that is depending on the user to be logged in, we hit a null reference exception.

On IIS6 we never had this issue, On IIS8 we get this a few hundred times a day, which is quite annoying.

This may just be a config issue, but so far my googling haven't turned up anything

Web.config (slightly redacted to protect the guilty)

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  <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>
    <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
  </configSections>
  <system.web>
    <pages enableViewStateMac="true">
      <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>
    <httpRuntime maxRequestLength="8192" executionTimeout="800" />
    <httpHandlers>
      <remove path="*.asmx" verb="*" />
      <add path="*.asmx" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
      <add path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
      <add path="ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
      <add path="BusyBoxDotNet.axd" verb="*" type="BusyBoxDotNet.ResourceHttpHandler, BusyBoxDotNet" />
      <add path="ChartAxd.axd" verb="*" type="Dundas.Charting.WebControl.ChartHttpHandler" validate="false" />
    </httpHandlers>
    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </httpModules>
    <globalization culture="en-US" />
    <sessionState mode="StateServer" timeout="480" />
    <authentication mode="Forms">
      <forms cookieless="UseCookies" domain=".stuff.topleveldomain" enableCrossAppRedirects="true" name=".morestuff" timeout="480" />
    </authentication>
    <machineKey validationKey=".." decryptionKey="..." validation="SHA1" />
    <customErrors mode="RemoteOnly" defaultRedirect="~/Public/ErrorPage.aspx">
      <error statusCode="404" redirect="~/Public/FileNotFound.htm" />
    </customErrors>
    <membership defaultProvider="CustomAspNetSqlMembershipProvider">
      <providers>
        <remove name="AspNetSqlMembershipProvider" />
        <add name="CustomAspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="Common" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="true" applicationName="stuff" requiresUniqueEmail="true" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" passwordFormat="Clear" maxInvalidPasswordAttempts="10000" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="CustomAspNetSqlRoleProvider">
      <providers>
        <clear />
        <add connectionStringName="Common" applicationName="stuff" name="CustomAspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
      </providers>
    </roleManager>
    <compilation debug="true">
      <assemblies>
        <add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
        <add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <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" />
        <add assembly="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
      </assemblies>
    </compilation>
  </system.web>
  <!-- Configuration for pages that do not require authentication -->
  <location path="public">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <location path="Images/Misc">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <location path="Images/Pics">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <location path="stylesheet">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <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>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
        <providerOption name="CompilerVersion" value="v3.5" />
        <providerOption name="OptionInfer" value="true" />
        <providerOption name="WarnAsError" value="false" />
      </compiler>
    </compilers>
  </system.codedom>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <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>
    <defaultDocument>
      <files>
        <remove value="index.php" />
        <remove value="default.aspx" />
        <remove value="iisstart.htm" />
        <remove value="index.html" />
        <remove value="index.htm" />
        <remove value="Default.asp" />
        <remove value="Default.htm" />
        <add value="login.aspx" />
      </files>
    </defaultDocument>
  </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>
Grubsnik
  • 918
  • 9
  • 25
  • Can you please post your config file here? – INDIA IT TECH Apr 26 '16 at 12:48
  • Definately, let me know if you need anything else to go on – Grubsnik Apr 26 '16 at 13:17
  • Any chance you could make a small page, as simple as possible, that reproduces the issue? For me the page never starts executing if I'm not logged in. The `FormsAuthentication` module sends me to the login page before that happens... – user1429080 Apr 27 '16 at 08:37
  • 1
    that makes me think about the endresponse parameter of the HttpResponse.Redirect method (Indicates whether execution of the current page should terminate) i would investigate this – Bombinosh Apr 27 '16 at 15:57
  • Is it possible for you to clear your web.config and test page? I mean keep only default content in web.config – INDIA IT TECH Apr 28 '16 at 11:48
  • Have you seen this: http://stackoverflow.com/questions/12357948/null-user-identity-in-iis-7-5 – antiskidwarpdrive Apr 29 '16 at 05:08
  • Were in your code is the exception coming from, is it from a global.asax event calling your code? I've seen a similar issue where logic to check if the user was authorized was in the AuthenticateRequest event instead of the AuthorizRequest event. The code was trying to get the users username based of the windows authentication IIS setting but due to the order of the event it didn't have it yet and a null error was thrown – Dax Apr 29 '16 at 17:06
  • @Bombinosh can you make an answer, so I can credit you with the bounty? – Grubsnik May 03 '16 at 09:08
  • Done. Thanks for asking. – Bombinosh May 03 '16 at 10:26

3 Answers3

2

That makes me think about the endresponse parameter of the HttpResponse.Redirect method (Indicates whether execution of the current page should terminate):

If you don't explicitely end the current request while performing a redirect, the execution flow will go on. That could be what happens in your case.

For a matter of performance, the most commonly used Redirect method, Redirect(String), call internally the Redirect(String, Boolean) override, with false as value for the endresponse parameter.

So you could try to replace the call(s) to

Response.Redirect("[login URL]");

by

Response.Redirect("[login URL]",true);

and see if it solve your problem

More informations on msdn:

https://msdn.microsoft.com/en-us/library/a8wa7sdt(v=vs.110).aspx

Bombinosh
  • 413
  • 6
  • 18
  • This was the correct solution. Apparently IIS6 and IIS8 handles this differently, or there was another difference between the servers we had missed. – Grubsnik May 06 '16 at 07:32
0

Try setting your App Pool to Class Mode vs. Integrated

APP POOL

Elim Garak
  • 1,728
  • 1
  • 16
  • 21
0

It is worth specifying the default page and login page if user is not authenticated. It will prevent executing code in other pages.

<authentication mode="Forms">
        <forms loginUrl="~/Login" timeout="480" defaultUrl="~/" />
</authentication>
gnaanaa
  • 323
  • 4
  • 18