2015-12-18 4 views
3

Я использую промежуточное программное обеспечение проверки подлинности cookie OWIN в проекте, который был настроен как приложение ASP.NET MVC и WebApi (т. Е. Я добавил OWIN).Проверка подлинности cookie Owin иногда выбрасывает NullReferenceException

Время от времени, когда я вносил некоторые изменения и начинал отладку, я получаю исключение, которое происходит по каждому запросу в течение хорошей минуты или около того, пока веб-сайт не будет снова работать без каких-либо проблем. Я размещаю приложение в своем локальном 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); 

настроить промежуточное так:

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 это, видимо, связано с печенья или по крайней мере, в браузере - потому что у меня есть один сеанс в браузере, где он будет последовательно выкидывать это исключение, в то время как другие браузеры (которые ранее были также зарегистрированы) могут получить к нему доступ просто отлично.

+0

[Что такое 'NullReferenceException' и как это исправить?] (Http://stackoverflow.com/q/4660142/447156) –

+1

Я не вижу никакого кода, где я хотел бы получить доступ к объекту или свойство объекта, который является нулевым. Исключение не похоже на мой собственный код. Кроме того, даже если бы я это сделал, отладка остановилась бы на этом конкретном исключении. – urbanhusky

ответ

0

Мы столкнулись с той же проблемой. Пара вещей:

  1. Убедитесь, что вы используете, по крайней мере 1.15.0 версию Owin.Security.Providers.
  2. Использование Kentor.OwinCookieSaver.

Вы можете найти следующий пост полезным: http://panuoksala.blogspot.fi/2015/03/aspnet-mvc-and-owin.html

+0

Пробовал оба, но это не помогло – urbanhusky

1

Вместо того, чтобы отвергнуть идентичность заменить его анонимным один.

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