2011-03-15 4 views
8

how to set up custom user roles을 기술하는 SO에 대한 훌륭한 답을 발견했으며 프로젝트에서 동일한 결과를 보았습니다. 내 로그인 서비스 그래서 나는이 : 사용자가 "admin"역할을하고 있지만 [Authorize (Roles = "admin")]이 인증되지 않습니다

public ActionResult Login() { 
    // password authentication stuff omitted here 
    var roles = GetRoles(user.Type); // returns a string e.g. "admin,user" 
    var authTicket = new FormsAuthenticationTicket(
        1, 
        userName, 
        DateTime.Now, 
        DateTime.Now.AddMinutes(20), // expiry 
        false, 
        roles, 
        "/"); 
    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, 
    FormsAuthentication.Encrypt(authTicket)); 
    Response.Cookies.Add(cookie); 
    return new XmlResult(xmlDoc); // don't worry so much about this - returns XML as ActionResult 
} 

그리고 Global.asax.cs에서

, 나는 (다른 답변에서 그대로 복사) 한 :

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { 
    var authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie != null) { 
    var authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
    var roles = authTicket.UserData.Split(new Char[] { ',' }); 
    var userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles); 
    Context.User = userPrincipal; 
    } 
} 

그런 다음 내 ServicesController 수업 시간에, 내가 가진 :

[Authorize(Roles = "admin")] 
//[Authorize] 
public ActionResult DoAdminStuff() { 
    ... 
} 

"admin"역할을 가진 사용자로 로그인하면 작동합니다. 그런 다음/services/doadminstuff를 호출하면 Global.asax.cs에 중단 점을 넣을 때 "admin"이 포함 된 역할을 볼 수 있지만 액세스가 거부됩니다. 첫 번째 Authorize 속성 (역할 포함)을 주석 처리하고 일반 바닐라 Authorize 만 사용하면 서비스에 액세스 할 수 있습니다.

내가 여기 뭔가 중요한 것을 놓치고 있어야합니다. 다음

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] 
public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     string cookieName = FormsAuthentication.FormsCookieName; 

     if (!filterContext.HttpContext.User.Identity.IsAuthenticated || 
      filterContext.HttpContext.Request.Cookies == null || 
      filterContext.HttpContext.Request.Cookies[cookieName] == null 
     ) 
     { 
      HandleUnauthorizedRequest(filterContext); 
      return; 
     } 

     var authCookie = filterContext.HttpContext.Request.Cookies[cookieName]; 
     var authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
     string[] roles = authTicket.UserData.Split(','); 

     var userIdentity = new GenericIdentity(authTicket.Name); 
     var userPrincipal = new GenericPrincipal(userIdentity, roles); 

     filterContext.HttpContext.User = userPrincipal; 
     base.OnAuthorization(filterContext); 
    } 
} 

과 :

[CustomAuthorize(Roles = "admin")] 
public ActionResult DoAdminStuff() 
{ 
    ... 
} 

또한 매우 중요한 것은 당신이 로그인 할 때 인증 쿠키가 있는지 확인하는 것입니다

답변

15

난 당신이 사용자 지정 권한 부여 대신 Application_AuthenticateRequest의 속성을 사용하는 것이 좋습니다 것입니다 XML 파일을 반환하기 때문에 생성됩니다. /services/doadminstuff에 액세스하려고 시도 할 때 인증 쿠키가 제대로 전송되는지 FireBug를 사용하여 검사하십시오.

+3

효과가있었습니다. 고맙습니다! 왜이 작품이 Global.asax.cs의 작품은 아니 었는지 말해 주시겠습니까? –

+1

다시 도움 주셔서 감사합니다! 어쩌면 당신은 또한이 관련된 문제에 대해 밝힐 수 있습니다 : http://stackoverflow.com/q/6586156/7850 –

+0

덕분에, 그것은 작동합니다. 어떻게 표시하고 올바른 메시지로 추가 페이지를 제어 할 수 있습니까? – Timeless

0

나는 처음에 교장 할당을 변경합니다 : ASP.NET 문서 스탠드

Thread.CurrentPrincipal = userPrincipal; 
if (HttpContext.Current != null) 
{ 
    HttpContext.Current.User = userPrincipal; 
} 

한다.

관련 문제