简体   繁体   中英

Owin cookie authentication occasionally throws NullReferenceException

I'm using the OWIN cookie authentication middleware in a project that was set up as an ASP.NET MVC and WebApi application (ie I added OWIN).

Every now and then, when I made some changes and start the debugging, I get an exception which happens on every request for a good minute or so until the website suddenly works without any issues again. I host the application in my local IIS.

System.NullReferenceException: Object reference not set to an instance of an object.
   at FooWeb.Startup.<>c.<Configuration>b__0_3(CookieExceptionContext context) in C:\ws\Foo\Main\Main\FooWeb\Startup.cs:line 138
   at Microsoft.Owin.Security.Cookies.CookieAuthenticationHandler.<ApplyResponseGrantAsync>d__f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.<RunApp>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.<DoFinalWork>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar)
   at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously);

I set up the middleware like so:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = "Cookies",
    LoginPath = new PathString("/Account/Login"),
    LogoutPath = new PathString("/Account/Logoff"),
    CookieName = "FooWebCookieAuth",
    SlidingExpiration = true,
    ExpireTimeSpan = TimeSpan.FromMinutes(10),
    CookieSecure = CookieSecureOption.Always,

    Provider = new CookieAuthenticationProvider()
    {
        OnValidateIdentity = async context =>
        {
            // Validate access token
            if (context == null)
            {
                return;
            }

            if (context.Identity == null || !context.Identity.IsAuthenticated)
            {
                return;
            }

            if (context.Identity.Claims == null)
            {
                context.RejectIdentity();
            }

            var accessTokenClaim = context.Identity.Claims.FirstOrDefault(x => x.Type == FooClaimTypes.Token);
            var accessToken = (accessTokenClaim == null) ? null : accessTokenClaim.Value;
            if (accessToken == null)
            {
                context.RejectIdentity();
            }
            else
            {
                var client = new IntrospectionClient(
                    SecurityTokenServiceEndpoints.Introspection,
                    "FooScope", 
                    "FooSecret");
                var validationResult = await client.SendAsync(new IntrospectionRequest()
                {
                    Token = accessToken
                });

                if (validationResult.IsError || !validationResult.IsActive)
                {
                    context.RejectIdentity();
                }
            }
        },
        OnException = context =>
        {
            // exception is thrown here (so that debugging stops). Without this it just faults
            throw context.Exception;
        },
    },
});

Update this seems to be related to the cookie or at least the browser - because I have one session in a browser where it will consistently throw that exception while other browsers (that were previously logged in also) can access it just fine.

而不是拒绝身份取代它与匿名身份。

context.ReplaceIdentity(System.Security.Principal.WindowsIdentity.GetAnonymous());

We've encountered the same issue. Couple things:

  1. Make sure that you're using at least 1.15.0 version of Owin.Security.Providers.
  2. Use Kentor.OwinCookieSaver .

You may find the following post useful: http://panuoksala.blogspot.fi/2015/03/aspnet-mvc-and-owin.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM