2011-03-15 30 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() 
{ 
    ... 
} 

また、非常に重要なことは、あなたがログインしたときに認証Cookieがあることを確認することです

答えて

15

私は、カスタムのauthorize代わりApplication_AuthenticateRequestの属性を使用することをお勧めしますあなたがXMLファイルを返すので発生します。 FireBugを使用して、URL /services/doadminstuffにアクセスしようとすると、認証Cookieが正しく送信されているかどうかを調べます。

+3

これは機能しました。ありがとうございました!なぜ、この仕事はしたのですか、Global.asax.csの仕事はしていませんでしたか? –

+1

もう一度お世話になりました!たぶんあなたはまた、この関連する問題についていくつかの光を当てることができます:http://stackoverflow.com/q/6586156/7850 –

+0

ありがとう、それは動作します。どのページをどのページに表示し、正しいメッセージで制御することができますか? – Timeless

0

私が最初に元本のアサインを変更します

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

ASP.NETのドキュメントスタンドとして。

関連する問題