MVC5 Claims version of the Authorize attribute

2019-01-07 03:26发布

问题:

I'm trying out some of the new stuff in VS2013 RC with MVC5 and the new OWIN authentication middleware.

So, I'm used to using the [Authorize] attribute to limit actions by role but I'm trying to use claims/activity based authorization, and I can't find an equivalent attribute for it.

Is there an obvious one I'm missing or do I need to roll my own? I kinda expected there to be one out of the box.

What I'm looking for specifically is something along the lines of [Authorize("ClaimType","ClaimValue")] I suppose.

Thanks in advance.

回答1:

I ended up just writing a simple attribute to handle it. I couldn't find anything in the framework right out of the box without a bunch of extra config. Listed below.

public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
    private string claimType;
    private string claimValue;
    public ClaimsAuthorizeAttribute(string type, string value)
    {
        this.claimType = type;
        this.claimValue = value;
    }
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var user = filterContext.HttpContext.User as ClaimsPrincipal;
        if (user != null && user.HasClaim(claimType, claimValue))
        {
            base.OnAuthorization(filterContext);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

Of course, you could remove the type and value params if you were happy to use the controller-action-verb triplet for claims somehow.



回答2:

  1. You wouldn't check for claims specifically, but rather for action/resource pairs. Factor out the actual claims / data checks into an authorization manager. Separation of concerns.
  2. MVC and ClaimsPrincipalPermission is not a good match. It throws a SecurityException and is not unit testing friendly.

My version is here: http://leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/



回答3:

I found that you can still use the Authorization attribute with roles and users, with claims.
For this to work, your ClaimsIdentity have to include 2 specific claim types:

    ClaimTypes.Name

and

    ClaimTypes.Role

Then in your class derived from OAuthAuthorizationServerProvider, in the GrantXX methods you use, when you create your ClaimsIdentity, add these 2 claims.

Example:

    var oAuthIdentity = new ClaimsIdentity(new[]
    {
        new Claim(ClaimTypes.Name, context.ClientId),
        new Claim(ClaimTypes.Role, "Admin"),
    }, OAuthDefaults.AuthenticationType);

Then on any action you can use [Authorize(Roles ="Admin")] to restrict access.



回答4:

[ClaimsPrincipalPermission(SecurityAction.Demand, Operation="Delete", Resource="Customer")]
public ActionResult Delete(int id)
{
    _customer.Delete(id);
    return RedirectToAction("CustomerList");
}

ClaimsPrincipalPermissionAttribute Class