1

응용 프로그램에서 우리는 역할 기반 폼 인증을 구현했습니다. 이 작업은 RoleModule을 사용하여 수행되었습니다. 여기서는 역할 데이터를 쿠키에 저장합니다 ( ). 쿠키에서 데이터를 읽고 IPrincipal 개체를 인스턴스화 할 때마다 처리됩니다. 이 코드 Application_OnPostAcquireRequestState 방법으로 실행된다 :컨텍스트를 다시 초기화하십시오. FormsAuthenticationTicket 시간 초과 후 사용자

HttpApplication application = source as HttpApplication; 
HttpContext context = application.Context; 

if (context.User.Identity.IsAuthenticated && 
     (!Roles.CookieRequireSSL || context.Request.IsSecureConnection)) 
{ 
//Read the roles data from the Roles cookie.. 

context.User = new CustomPrincipal(context.User.Identity, cookieValue); 
Thread.CurrentPrincipal = context.User; 
} 

이것은 context.User 객체를 초기화한다. 서버에 대한 요청이있을 때마다 사용자는 위의 흐름을 사용하여 인증됩니다. Application_EndRequest에서 Roles 쿠키를 현재 주요 개체 데이터로 업데이트합니다.

우리는 Global.asax 페이지에 쿠키를 읽고 쿠키를 업데이트하고 만료 된 경우 티켓을 갱신하는 방법으로 FormsAuthentication_OnAuthenticate 방법이 있습니다. 또한이 메소드에서는 티켓이 만료 된 경우 세션 객체에 username 값을 설정하려고합니다. 여기

FormsAuthentication oldTicket = FormsAuthentication.Decrypt(context.Request.Cookies[FormsAuthentication.FormsCookieName].Value); 
if(oldTicket != null) 
{ 
    if(oldTicket.Expired) 
    { 
     try 
     { 
      HttpContext.Current.Session["UserName"] = userName; 
     } 
     catch 
     { 
      //Log error. 
     } 

    FormsAuthentication newTicket = new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, DateTime.Now, 
      DateTime.Now.AddMinutes(30), oldTicket.IsPersistent, oldTicket.UserData); 

    string encryptedTicket = FormsAuthentication.Encrypt(newTicket); 
    HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 
    if (isPersistent) 
    { 
     httpCookie.Expires = DateTime.Now.AddMinutes(300); 
    } 
} 

은 우리의 양식의 web.config에 설정되어

<forms defaultUrl="Default.aspx" domain="" loginUrl="Login.aspx" name=".ASPXFORMSAUTH" timeout="20" slidingExpiration="true" /> 

세션 제한 시간은 20 분입니다.

문제 :. 사용자가 30 분 동안 사용합니다 (FormsAuth 티켓 갱신 지속 시간이다) 인 경우, 역할 모듈은 false이며, context.UserNULL로 설정 에 context.User.Identity.IsAuthenticated 값. 이제 사용자가 페이지를 요청하면 로그인 페이지로 리디렉션됩니다. 그러나 쿠키가 아직 있습니다. 다시 사용자가 페이지를 요청하려고하면 context.User.IsAuthenticated 속성이 true으로 설정되고 사용자는 해당 페이지로 이동합니다. 또한 FormsAuthentication_OnAuthenticate 메서드에서 세션 값을 설정하려고하면 세션 객체가 NULL이므로 오류가 발생합니다.

여기서 달성하고자하는 것은 영구 쿠키의 경우 인증 티켓 시간이 초과 된 후 사용자가 로그 아웃되어서는 안되는 것입니다. 즉 사용자는 을 다시 인증 받아야합니다.

어떻게하면됩니까? 내가 잘못하지 않았다면, context.User으로 설정하면 해결되지만, 어떻게 해결할 수 있습니까?

추가 정보 : 나는에 저장된 표준 컴퓨터 키 설정을 사용하고

Event code: 4005 
Event message: Forms authentication failed for the request. Reason: The ticket supplied has expired. 
Event time: 08-02-2012 20:02:05 
Event time (UTC): 08-02-2012 14:32:05 
Event ID: 048e3238ade94fd6a7289bac36d130ef 
Event sequence: 76 
Event occurrence: 2 
Event detail code: 50202 

Process information: 
Process ID: 21692 
Process name: w3wp.exe 
Account name: IIS APPPOOL\ASP.NET v4.0 Classic 

: 티켓이 만료되고 난 페이지를 요청하려고

후, 이벤트 뷰어 오류 메시지가 표시 web.config가 아니라 자동 생성 된. 또한 모든 오류에 대해 프로세스 ID와 프로세스 ID를 확인했습니다.

답변

1

마침내 문제가 해결되었습니다. FormsAuthentication 티켓이 초과되었을 때 FormsAuthentication_OnAuthenticate은 컨텍스트를 설정할 수 없었습니다.인증하고 이벤트에 대한 MSDN documentation에 지정된 사용자 개체는 :

당신이 FormsAuthentication_OnAuthenticate 이벤트 기간 동안 사용자 속성에 대한 값을 지정하지 않으면, 쿠키 또는 URL에 폼 인증 티켓에서 제공하는 정체성이다 익숙한.

그 이유는 사용자의 사용자 이름을 ticket.Name으로 설정하지 않기 때문입니다. 빈 문자열입니다. 따라서 Authenticate 이벤트가 사용자의 ID를 가져오고 FormsIdentity 인스턴스를 생성 할 수없는 경우 일 수 있습니다. 해결 방법으로 만료 된 티켓을 갱신 할 때 GenericIdentity 개체를 만든 다음이를 사용하여 context.User을 설정합니다.

IIdentity identity = new GenericIdentity(username, "Forms"); 
context.User = new CustomPrincipal(identity);