【问题标题】:MVC5 Claims version of the Authorize attribute授权属性的 MVC5 声明版本
【发布时间】:2013-10-22 05:30:34
【问题描述】:

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

所以,我习惯于使用[Authorize] 属性来按角色限制操作,但我正在尝试使用基于声明/活动的授权,但我找不到它的等效属性。

是否有一个明显的我错过了,或者我需要自己推出一个?我有点期待会有一个开箱即用的。

我想我正在寻找的是类似于[Authorize("ClaimType","ClaimValue")] 的东西。

提前致谢。

【问题讨论】:

  • 只是作为一个建议,请将 UPDATE 部分作为新答案,以便每个人都清楚这是另一种方法(而不是您问题的一部分)
  • 我会这样做,但我想接受我自己的答案,..这不是绅士应该做的:-)
  • 我在 meta 上确切地问过这个问题,这是他们回复的 meta.stackexchange.com/questions/216719/… 所以似乎达成了共识;)
  • @Stimul8d 我必须同意 Gervasio - 问题是为了问题,答案是为了答案。如果您不想这样做,则不必将其标记为已接受;但它会让其他人更清楚。
  • 我认为与角色的实现相比,这项技术没有附带属性管道,这很残酷。

标签: asp.net-mvc asp.net-mvc-5 claims


【解决方案1】:

我最终只写了一个简单的属性来处理它。如果没有一堆额外的配置,我在开箱即用的框架中找不到任何东西。如下所列。

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

当然,如果您愿意以某种方式将控制器-动作-动词三元组用于声明,您可以删除类型和值参数。

【讨论】:

  • 为了向前兼容,最好使用filterContext.HttpContext.user。
  • 我最终做了几乎相同的事情,但它在应用属性方面强制了一种角色风格的心态。 @leastprivilege 支持的关注点分离看起来更强大。
  • @Stimul8d 感谢您的回答,这在我的 MVC 5 应用程序中完美解决了!对我来说,实现自己的 ClaimsAuthorizationAttribute 然后使用 ClaimsAuthorizationManager 更有意义(需要太多配置)
  • 很好的答案,尤其是因为即使我也能够理解并融入它。
  • 一个很好的答案 - 我返回了一个 HTTP 403 以防止循环回到登录页面。至于角色,您可以像使用声明一样使用它们。不要使用像 ADMIN 这样的单一业务角色,而是使用 CanSaveData 等多个角色。您需要一个将伪角色 ADMIN 映射到它所属的所有角色的自定义表。声明是您的内置方式
【解决方案2】:
  1. 您不会专门检查声明,而是检查操作/资源对。将实际声明/数据检查分解到授权管理器中。关注点分离。
  2. MVC 和 ClaimsPrincipalPermission 不匹配。它会引发 SecurityException,并且对单元测试不友好。

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

【讨论】:

  • 您的版本似乎不在最新的 MVC 5 版本中?如果是这样,哪个 Nuget 包包含它?
  • nuget.org/packages/Thinktecture.IdentityModel.SystemWeb - 并重命名为 ResourceActionAuthorizeAttribute
  • @leastprivilege 我想用有关重命名的属性和 MVC 和 Web API 2.x 的可用 nuget 包的信息更新您的blog post 是有意义的吗?如果不是这个评论部分,我不知道我应该怎么知道重命名;)
  • 我不知道这个答案是否仍然是最新的,但我仍然不知道资源是什么,也不知道它与控制器操作和我的主张有什么关系。作为一个不是 Owin 专家的人,你能把答案扩大一点吗?
  • 使用属性仍然是关注点分离,因为逻辑在属性代码内部,同时保持属性属性对开发人员来说足够接近,所以他不会忘记它。
【解决方案3】:

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

    ClaimTypes.Name

和

    ClaimTypes.Role

然后在您从 OAuthAuthorizationServerProvider 派生的类中,在您使用的 GrantXX 方法中,当您创建您的 ClaimsIdentity 时,添加这两个声明。

例子:

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

然后在任何操作上,您都可以使用[Authorize(Roles ="Admin")] 来限制访问。

【讨论】:

  • 这就是诀窍!让我感到惊讶的是在进行更改后没有重新生成令牌 - 哦!为了清楚起见,使用上面的代码,[Authorize(Roles ="Admin")] 是您需要限制对方法的访问。
【解决方案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();
}

Source.

【讨论】:

    【解决方案5】:
    [ClaimsPrincipalPermission(SecurityAction.Demand, Operation="Delete", Resource="Customer")]
    public ActionResult Delete(int id)
    {
        _customer.Delete(id);
        return RedirectToAction("CustomerList");
    }
    

    ClaimsPrincipalPermissionAttribute Class

    【讨论】:

    • 这似乎是正确的,但它需要大量的腿部工作和额外的参考,以供参考。我已经接受了答案,但请检查我的编辑。
    • 这不会抛出异常,而不是返回适当的 HTTP 响应吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多