0

I have a problem with owin cokies. We have a site powered by ASP.net MVC 5. And authorization is by owin middleware. Sometimes users get a white screen with 500 error. I cant reproduce it at local but a couple of times i could reproduce this case at production. Exploring logs i discovered error "System.NullReferenceException: Object reference not set to an instance of an object." Stack:

System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer.Write(BinaryWriter writer, AuthenticationTicket model) at Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer.Serialize(AuthenticationTicket model) at Microsoft.Owin.Security.DataHandler.SecureDataFormat1.Protect(TData data) 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.AuthenticationMiddleware1.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.AspNet.Identity.Owin.IdentityFactoryMiddleware2.<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.AspNet.Identity.Owin.IdentityFactoryMiddleware2.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.AspNet.Identity.Owin.IdentityFactoryMiddleware2.<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.AspNet.Identity.Owin.IdentityFactoryMiddleware2.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.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.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

A part of Startup.Auth:

app.CreatePerOwinContext(Entities.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        //owin иногда теряет куки авторизации в response, поэтому потом возникается nullreference error
        //здесь вызывается специальная библиотека, которая сохраняет куки авторизации (создана для фикса бага овина)
        app.UseKentorOwinCookieSaver();

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/newLogin"),
            LogoutPath = new PathString("/logout"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = ctx =>
                {
                    var ret = Task.Run(async () =>
                    {
                        Claim claim = null;
                        int userId = default(int);
                        User user = null;
                        try
                        {
                            claim = ctx.Identity.FindFirst("SecurityStamp");
                            if (claim == null) return;
                            var userManager = new ApplicationUserManager(DependencyResolver.Current.GetService<IUserStore<User, int>>());
                            userId = ctx.Identity.GetUserId<int>();
                            user = await userManager.FindByIdAsync(userId);

                            if (user != null && user.SecurityStamp != null && user.SecurityStamp != claim.Value)
                            {
                                var exc = new Exception("ConfigureAuth->OnValidateIdentity->Reject");
                                exc.Data.Add("claim", claim.Value);
                                exc.Data.Add("userId", userId);
                                exc.Data.Add("userStamp", user.SecurityStamp);
                                ErrorStore.LogException(exc, HttpContext.Current);
                                ctx.RejectIdentity();
                            }
                        }
                        catch (Exception ex)
                        {
                            var exc = new Exception("ConfigureAuth->OnValidateIdentity->catch", ex);
                            if (claim != null)
                            {
                                exc.Data.Add("claim", claim.Value);
                            }
                            exc.Data.Add("userId", userId);
                            if (user!=null)
                            {
                                exc.Data.Add("userStamp", user.SecurityStamp);
                            }
                            ErrorStore.LogException(exc, HttpContext.Current);
                            ctx.RejectIdentity();
                            return;
                        }
                    });
                    return ret;
                },
                OnApplyRedirect = ctx =>
                {
                    if (!IsApiRequest(ctx.Request))
                    {
                        ctx.Response.Redirect(ctx.RedirectUri);
                    }
                },
                OnException = (context =>
                {
                    ErrorStore.LogException(context.Exception, HttpContext.Current);
                    return;
                })
            }
        });

When user gets white screen, he can write into url "logout" and he will be redirected to index page. (domain.me/ru/logout). Or if he clean his cookies he wiil be redirected to index page too.

I installed nuget package "Kentor.OwinCookieSaver" because of i thought owin didn't fixed the bug. But i think it was in vain because i have the latest version of OWIN:

Microsoft.AspNet.Identity.Owin: 2.2.1
Microsoft.Owin: 3.1.0
Microsoft.Owin.Security.OAuth: 3.1.0
Microsoft.Owin.Security.Cookies: 3.1.0

However Owin.Security.Providers is 1.27.0 version because of we dont need for many providers (only facebook and linkedin).

Its a legacy project, so im not deep into it.

I need some help. Thank you.

Alex Grigorenko
  • 403
  • 4
  • 12
  • You mention you could sometimes reproduce this on production. It could help if you can tell what you did do to reproduce. Like did you remove cookies? –  Jun 01 '17 at 21:35
  • I opened 2 different browsers (or opened Incognito in Chrome) and logged in by first browser and then after several minutes by second one where i was logged in before repeating this case seveal times. Sometimes i should repeat it for a long time and its very difficult to reproduce this error. @RuardvanElburg – Alex Grigorenko Jun 08 '17 at 08:56
  • Does this answer your question? [Why is \[Owin\] throwing a null exception on new project?](https://stackoverflow.com/questions/26327092/why-is-owin-throwing-a-null-exception-on-new-project) – Michael Freidgeim Jul 11 '21 at 00:22

1 Answers1

1

Looks like this is AspNetKatana issue, for more details please see https://github.com/aspnet/AspNetKatana/issues/58

Rejected identities would still end up creating an AuthTicket without a principal. If a sliding refresh was attempted on the same request then it would NRE on the missing principal.

Yusupov
  • 382
  • 2
  • 11