2012-12-04 1 views
1

내가 자신의 양식 기반 로그인을 구현하는 웹 사이트를 가지고 요청하고이 같은 인증 쿠키를 만듭니다

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userID, DateTime.UtcNow, expiration, isPersistent, userFunctions); 
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)); 
    cookie.Expires = expiration; 
    HttpContext.Current.Response.Cookies.Add(cookie); 

변수 "userFunctions"는 포함을 사용자가 구성원으로있는 쉼표로 구분 된 역할 목록 내 Global.asax 파일에서

나는 다음과 같은 방법으로 그 사용자 기능을 검색 해요 :이 모든 큰 노력

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
{ 
    if (HttpContext.Current.User != null) 
    { 
     if (HttpContext.Current.User.Identity.IsAuthenticated) 
     { 
      if (HttpContext.Current.User.Identity is FormsIdentity) 
      { 
       FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 

       string[] roles = id.Ticket.UserData.Split(','); 
       HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles); 
      } 
     } 
    } 
} 

. 또는 완전히 새로운 사용자를 위해 변경해야 할 때까지였습니다. 새 사용자의 문제는 "userFunctions"변수가 실제로 길어질 수 있고 쿠키에 저장하기에는 너무 길다는 것입니다 (이는 크기가 4k와 같은 것으로 제한됩니다).

"userFunctions"를 세션에 저장하도록 코드를 변경하지만 세션을 Application_AuthenticateRequest에 사용할 수 없습니다. 아마도 응용 프로그램 캐시 (아마도 키/값 쌍)에 데이터를 저장할 수는 있지만 응용 프로그램 캐시가이 데이터를 넣을 '올바른 위치'로 보이지 않기 때문에 나는 주저합니다.

아마도 응용 프로그램 캐시에 넣을 것이지만, 전에는 누구에게 더 나은 대안이 있는지 묻고 싶다고 생각했습니다.

+0

사용자가 속한 역할 목록을 쿠키에 추가하는 이유는 무엇입니까? – Jeroen

+0

이 목록을 클라이언트 (쿠키)로 보내면 최종 사용자가 쿠키를 변경할 수 있습니까? 네가 이걸 원할 것 같지 않은데. 당신이 전화 사이에이 목록을 유지하려고한다면 나는 그것이 서버에 남아있을 것을 제안 할 것이다. – PeteH

+0

동의합니다. 이것은 확실히 서버 측 기능처럼 들립니다. 어쩌면 당신은 이것을 달성하기 위해 인증/권한 부여 기능을 나눌 수 있습니다 ... – CalC

답변

1

세션을 사용하여 사용자 역할을 저장할 수 없다는 것을 감안할 때 (권한 부여가 수행되기 전에 검색 할 수 없기 때문에) 모든 페이지 요청에서 데이터베이스를 방문하는 데 드는 비용을 원하지 않았습니다.

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
{ 
    if (HttpContext.Current.User != null) 
    { 
     if (HttpContext.Current.User.Identity.IsAuthenticated) 
     { 
      if (HttpContext.Current.User.Identity is FormsIdentity) 
      { 
       FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 

       string[] roles; 
       string cachedRoles = (string)HttpContext.Current.Cache.Get("UserFunctions" + id.Name.ToLower()); 
       if (cachedRoles == null) 
       { 
        // Reload UserFunctions and add back in to Cache. 

        cachedRoles = [...code to get UserFunctions from database...]; 

        HttpContext.Current.Cache.Insert("UserFunctions" + id.Name.ToLower(), cachedRoles, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 20, 0), System.Web.Caching.CacheItemPriority.NotRemovable, null); 

       } 

       roles = cachedRoles.Split(','); 

       HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles); 
      } 
     } 
    } 
} 

아직까지는 테스트가 제한되어 있지만 제대로 작동하는 것으로 보입니다.

+2

이런 식으로 캐시를 사용하는 것이 매우 합리적인 해결책입니다. 그러나 global.asax 코드를 넣는 대신 사용자 지정 RoleProvider를 구현하여이 작업을 수행합니다. 이 작업을 수행하는 방법에 대한 자세한 내용은 다음 문서를 참조하십시오. http://msdn.microsoft.com/en-us/library/8fw7xh74(v=vs.100).aspx – Joe