I'm using the OWIN cookie authentication middleware in a project that was set up as an ASP.NET MVC and WebApi application (i.e. 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.
Rather than rejecting the identity replace it with an anonymous one.
context.ReplaceIdentity(System.Security.Principal.WindowsIdentity.GetAnonymous());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With