2016-06-20 2 views
6

전적으로 OWIN을 처음 접했고이 문제는 저에게 큰 방해물이었습니다. 내가 세션이 null 디버깅있을 때 왜HttpContext.Current.Session is null + OWIN

public partial class Startup 
{ 
    public void ConfigureAuth(IAppBuilder app) 
    { 
     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 
     app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
     app.UseOpenIdConnectAuthentication(
       new OpenIdConnectAuthenticationOptions 
       { 
        ClientId = OfficeSettings.ClientId, 
        Authority = OfficeSettings.Authority, 

        TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() 
        { 
         RoleClaimType = "roles" 
        }, 

        Notifications = new OpenIdConnectAuthenticationNotifications() 
        { 

        AuthorizationCodeReceived = (context) => 
         { 
         // code hidden for readability 

          if(HttpContext.Current.Session == null) 
          { 
           // It's null. Why is that? 
          } 

          var session = HttpContext.Current.Session; 
          if (session["myMockSession"] != null) 
          { 
           // Do stuff... 
          } 
         }, 

         RedirectToIdentityProvider = (context) => 
         { 
          // code hidden for readability 
         }, 

         AuthenticationFailed = (context) => 
         { 
          // code hidden for readability 
         } 
        } 
       }); 

이해가 안 :

기본적으로, 내 MVC 응용 프로그램에서 나는 시작 클래스에서 다음 있습니다. HttpContext.Current 속성이 아닙니다. Sessions + OWIN에 제약이 있습니까? 이 문제에 대한 해결 방법이 있습니까? 어떻게 접근해야합니까?

주 1

사이드 :

app.Use((context, next) => 
      { 
       // Depending on the handler the request gets mapped to, session might not be enabled. Force it on. 
       HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
       httpContext.SetSessionStateBehavior(SessionStateBehavior.Required); 
       return next(); 
      }); 

사이드 노트 2 : 나는 돈 나는 내가 SO 질문 중 하나에서 발견 한 세션이 여전히 널 (null)이 코드 조각을 추가하려고했습니다 더 이상 찾지 못하는 것 같지만 누군가가 SO 질문에 Global.asax에서 빈 메소드 Session_Start 및 Session_End (빈 메소드로)를 추가하도록 제안했습니다. 그것도 효과가 없었습니다.

나는 어떤 조언을 환영합니다. 감사합니다.

+0

비슷한 문제가 있습니다. 당신은 어떤 해결책을 찾을 수 있었습니까? – RonakThakkar

+0

안녕하세요 @RonakThakkar. 불행히도, 아직 아닙니다. 나는 어떤 해결책도 찾을 수 없었기 때문에이 일을 제쳐 놓아야했다. 아마도 우리는이 스레드에서 해결책을 얻을 수 있습니다. – AuroMetal

답변

9

당신은 입니다. 거의입니다. 세션이 여전히 null 인 이유는 미들웨어가 실행되기 전에 System.Web 세션을 초기화하도록 OWIN에 지시하지 않았기 때문입니다. 미들웨어 등록 후 .UseStageMarker (..)을 추가함으로써

실행 pipline에 기본적으로 SetSessionStateBehaviour

app.Use((context, next) => 
{ 
    var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
    httpContext.SetSessionStateBehavior(SessionStateBehavior.Required); 
    return next(); 
}); 

// To make sure the above `Use` is in the correct position: 
app.UseStageMarker(PipelineStage.MapHandler); 

을 수행해야 위치를 OWIN 말해주지, Owin 미들웨어에서 실행 이 경우 마지막 이벤트 (PipelineStage.PreHandlerExecute)가 너무 늦습니다.

이제 세션을 사용하려면 세션이 Asp.Net 런타임 의해 취득되어있다를 실행하는 미들웨어에서 작동해야합니다. 이 미들웨어는 지금처럼 PostAquireState 단계에서 실행해야합니다 :

.Use((context, next) => 
{ 
    // now use the session 
    HttpContext.Current.Session["test"] = 1; 

    return next(); 
}) 
.UseStageMarker(PipelineStage.PostAcquireState); 

Asp.Net의 카타나 워드 프로세서 미들웨어가 작동하는 방법에 대한 excellent article있다. Asp.net의 실행 순서에 대한 자세한 내용은 PiplineStage enum docs 및 HttpApplication 문서를 참조하십시오.

+0

안녕하세요 @ 조한 오, 절대적으로 환상적인 설명! 세부 사항에 대해 대단히 감사합니다. 희망 사항은 같은 문제로 우리 중 일부를 도울 것입니다. – AuroMetal