MVC5声明Authorize属性的版本


77

我正在尝试使用MVC5和新的OWIN身份验证中间件在VS2013 RC中进行一些新操作。

因此,我习惯于使用该[Authorize]属性按角色来限制操作,但是我尝试使用基于声明/活动的授权,但找不到与其等效的属性。

是否有明显的我想念的东西,还是我需要自己动手?我有点希望开箱即用。

我要寻找的具体是[Authorize("ClaimType","ClaimValue")]我所想的东西。

提前致谢。


1
只是作为建议,请把UPDATE部分作为新的答案,以便所有人都清楚这是另一种方法(而不是您的问题的一部分)
g3rv4

我会这样做的,但是然后我想接受自己的回答,..那不是绅士所做的:-)
AugustyOne Unite 2015年

1
我确切地问了关于meta的问题,这是他们回答的内容meta.stackexchange.com/questions/216719/…所以似乎达成了共识;)
g3rv4

@ Stimul8d我必须同意Gervasio-问题是疑问,答案是答案。如果您不想这样做,则不必将其标记为已接受。但这会使其他人更清楚。
dav_i 2015年

2
与Roles的实现相比,该技术没有附带属性的管道是残酷的。
匹兹堡DBA 2015年

Answers:


73

我最终只是编写了一个简单的属性来处理它。没有大量额外的配置,我无法在框架中找到任何东西。下面列出。

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);
        }
    }
}

当然,如果您愿意以某种方式将controller-action-verb三元组用于声明,则可以删除类型和值参数。


6
为了向前兼容,最好使用filterContext.HttpContext.user
Erik Philips

1
我最终做了几乎相同的事情,但是在应用属性方面,这迫使人们采用一种角色风格的心态。@leastprivilege支持的关注分离看起来更加强大。
匹兹堡DBA 2015年

2
@ Stimul8d感谢您的回答,这在我的MVC 5应用程序中完美实现了!对我来说,实现自己的ClaimsAuthorizationAttribute然后再与ClaimsAuthorizationManager一起使用(需要太多配置)更有意义
landsteven '16

1
好的答案,尤其是因为即使我也能够理解和合并它。
瓦西里大厅

一个很好的答案-我返回了HTTP 403,以防止循环回到登录页面。至于角色,您可以使用它们类似于声明。可以使用许多角色(例如CanSaveData)来代替ADMIN等单个业务角色。您需要一个自定义表,它将伪角色ADMIN映射到它所属的所有角色。
自称

30
  1. 您无需特别检查声明,而可以检查动作/资源对。将实际的索赔/数据检查纳入授权管理器。关注点分离。
  2. MVC和ClaimsPrincipalPermission不是很好的匹配。它抛出SecurityException,并且不适合单元测试。

我的版本在这里:http : //leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/


2
您的版本似乎不是最新的MVC 5版本?如果是这样,哪个Nuget软件包包含它?
Brian Mains 2014年

2
nuget.org/packages/Thinktecture.IdentityModel.SystemWeb-并将其重命名为ResourceActionAuthorizeAttribute
Minimumprivilege 2014年

4
@leastprivilege我想用有关重命名属性和MVC和Web API 2.x可用的nuget包的信息来更新您的博客文章是否有意义?我不知道该如何修改本名,否则我应该怎么知道;)
Lasse Christiansen

4
我不知道这个答案是否仍然是最新的,但是我仍然不知道什么是资源,或者它与控制器动作和我的主张有什么关系。作为不是Owin专家的人来做这个,您能否请您扩展一下答案?
Craig Brett

1
使用属性仍然是一个需要关注的问题,因为逻辑位于属性代码内部,同时使属性对开发人员而言足够接近,因此他不会忘记它。
Softlion

9

我发现您仍然可以将Authorization属性用于角色和用户以及声明。
为此,您的ClaimsIdentity必须包括2种特定的索赔类型:

    ClaimTypes.Name

    ClaimTypes.Role

然后,在派生自OAuthAuthorizationServerProvider的类中,在使用ClaimsIdentity时,在使用的GrantXX方法中添加这2个声明。

例:

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

然后,您可以执行任何操作[Authorize(Roles ="Admin")]来限制访问。


这可以解决问题!引起我注意的是在进行更改后没有重新生成令牌-哎呀!为了清楚起见,使用上面的代码,您需要限制[Authorize(Roles =“ Admin”)]的访问权限。
Kinetic

4

在ASP.NET Core 3中,您可以像这样配置安全策略:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
    });
}

然后使用AuthorizeAttribute要求用户满足特定策略的要求(换句话说,满足支持该策略的声明)。

[Authorize(Policy = "EmployeeOnly")]
public IActionResult VacationBalance()
{
    return View();
}

来源


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

ClaimsPrincipalPermissionAttribute类


2
这似乎是对的,但是它需要大量的工作和额外的参考资料,这些内容本应包含在内。我已经接受了答案,但请检查我的编辑。
八十一号联合

1
这不是引发异常,而是返回适当的HTTP响应吗?
罗尼·欧弗比
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.