Authorize attribute not working with roles

2019-01-23 20:45发布

I'm having trouble in getting the Authorize attribute to work with roles. This is how I've decorated my controller:

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

and this is how I log a user in:

string roles = "admin";
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1,
    username,
    DateTime.Now,
    DateTime.Now.AddMinutes(30),
    false,
    roles
);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));
HttpContext.Current.Response.Cookies.Add(cookie);

But my user is still denied access. Where am I going wrong?

1条回答
戒情不戒烟
2楼-- · 2019-01-23 21:28

I stumbled upon a similar example of your code: the highest voted answer of MVC - How to store/assign roles of authenticated users.

The AuthorizeAttribute calls the IsInRole method on the IPrincipal instance stored in HttpContext.User. By default IPrincipal has no roles, and in this case IsInRole will always return false. This is why access to your action is denied.

Since you have stored the user's roles into the FormsAuthenticationTicket's UserData property, you must extract the roles from the auth cookie and into a IPrincipal instance yourself. The highest voted answer of MVC - How to store/assign roles of authenticated users provides the code that you can add directly into your global.asax.cs file to do just this. I have repeated it below:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
      FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
      string[] roles = authTicket.UserData.Split(',');
      GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
      Context.User = userPrincipal;
    }
}
查看更多
登录 后发表回答