【问题标题】:What's the technical advantage of claim/role/policy authorization as opposed to plain check of a user's ID?与简单检查用户 ID 相比,声明/角色/策略授权的技术优势是什么?
【发布时间】:2021-10-13 09:50:04
【问题描述】:

我使用 Identity Server 和受保护的端点以及策略和角色。这些都反映在我分发给客户端的访问令牌中。今天,我得到建议,而不是保护这样的方法:

[Authorize(Policy = "Elevated"), HttpGet("metadata")]
public IActionResult GetTenantMetadata() { ... }

我们可以跳过 JWT 的 role 部分,只执行以下操作。

[Authorize, HttpGet("metadata")]
public IActionResult GetTenantMetadata() { ... }

然后,在 Startup.cs 中,我们会像这样注册一个自定义处理程序。

services.AddHttpContextAccessor();
services.AddTransient<IAuthorizationHandler, HeaderHandler>();

然后将根据令牌中的sub 值在处理程序中执行实际的安全性。没有角色,没有范围,什么都没有。对我来说,直觉上不明智的做法是让我承担很多责任来创建保护逻辑,而不是依赖 IDS 和比我更聪明的人。我见过的所有解决方案都使用声明和角色来处理安全问题。所以我的直觉告诉我这是个坏主意。

protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        CustomRequirement requirement)
    {
        HttpRequest request = Accessor.HttpContext.Request;
        string param = request.Headers.SingleOrDefault(a => a.Key == "param1");
        string someAccess = dbContext.GetAccess(param, context.User.GetUserId());

        bool authorized = SomeEvaluation(param, someAccess);
        if (authorized) context.Succeed(requirement);
        else context.Fail();

        return Task.CompletedTask;
    }

但是,我无法激发我的选择(除了胆量和其他人的样本),所以最后我不确定了。我很谦虚地理解,如果我无法解释原因,那么也许我错了。

我搜索了 基于声明的安全性角色策略安全性 等,但我可以为建议的替代方案找到一个名称。因此,我没有找到任何讨论该问题的材料。

这种自定义授权方法叫什么,它的优点/警告是什么?

【问题讨论】:

  • sub 只是一个声明:用户的标识符。通过索赔授权,您可以使用更多索赔来构建您的保单。您可以使用用户 ID 获取声明,但这并不总是可行的(您手头可能没有用户信息,或者可能正在使用第 3 方 idprovider)或可行(高流量)。这就是为什么您将其中一些声明卸载到 access_token(或由受信任的 IdP 提供给您),而不必为每个请求进行数据库查找。
  • 使用自定义 AuthorizationHandler 对于简单的索赔检查来说可能有点过头了。它对于复杂的需求或如果您尝试进行基于资源的授权(“用户可以查看此特定记录”)很有用,除了我会努力保持简单。身份验证很困难。

标签: c# asp.net-core authorization identityserver4


【解决方案1】:

它仍然是声明授权,只是不是一个好的/实用的:你只是在使用sub 声明。没有理由放弃/不使用由受信任的身份提供者提供的完美声明。

首先,让客户端通过标头发送用户 ID 存在安全风险。你怎么知道它是否没有被篡改,并且用户没有假装是管理员?您不能,这就是为什么您要求 ID 提供者对用户进行身份验证并签署令牌以进行身份​​验证。

其次,在运行时从数据库或 API 中挑选用户 ID 并获取其他用户声明可能有效,但可能并不总是可行(应用不保留用户数据/将身份验证委托给第 3 方)或可行(高流量的应用程序,太多的数据库查找)。

要授权操作,您可以使用断言声明策略。但对于更高级或命令式的检查,您可以选择实施 AuthorizationHandler 并命令式地允许/阻止操作。
它对于基于资源的授权很有用,但如果访问令牌中已经提供了您需要的声明,那么这将是单行代码的过度杀伤。

更多信息

【讨论】:

    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 2011-09-22
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 2020-05-18
    相关资源
    最近更新 更多