【问题标题】:How to add an authorization policy with multiple scopes?如何添加具有多个范围的授权策略?
【发布时间】:2020-06-17 00:26:27
【问题描述】:
options.AddPolicy("Account", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account"));
options.AddPolicy("AccountWrite", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account.write"));
options.AddPolicy("AccountRead", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account.read"));

如何将 OR 添加到策略范围?

  • 范围为“帐户”时的“帐户”策略(读取、写入和删除)
  • 当范围为“account”或“account.write”(读取和写入)时的“AccountWrite”策略
  • 范围为“account.read”时的“AccountRead”策略(只读)

【问题讨论】:

    标签: asp.net asp.net-core asp.net-web-api authorization identityserver4


    【解决方案1】:

    要回答您的问题,您可以在 RequireClaim 语句中添加多个参数。作为documented

    RequireClaim(String, String[])

    claimType 字符串

    要求的声明类型。

    allowedValues IEnumerable

    声明必须处理一个或多个的值以进行评估 成功。

    在你的情况下是这样的:

    options.AddPolicy("Account", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.read", "account.write", "account.delete"));
    options.AddPolicy("AccountWrite", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.write"));
    options.AddPolicy("AccountRead", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.read"));
    

    但这对于示波器来说有点奇怪。

    拥有范围意味着客户端有权访问资源,而不管哪个用户使用客户端。

    范围标记资源中执行特定任务的部分,换句话说,具有特定功能。

    假设一个 CRUD AccountController:

    1. 您可以授权 客户端 访问整个控制器,在这种情况下使用控制器顶部的 account 范围。

    2. 您可以根据方法授权 客户端,例如account.read Index 方法,account.write CreateUpdate 方法和 account.delete Delete 方法.由于功能的不同,范围不太可能混用。

    两者都可以,因为用户需要被授权才能使用资源。客户端将用户带到资源并代表用户执行请求。但是将两者结合起来是没有意义的。

    什么是适合你的设计?

    假设您有一个管理应用程序,允许用户在其中管理帐户。客户拥有自己的应用并希望使用该应用访问资源,但您不希望允许从该应用进行全面管理。

    在这种情况下,客户的 client 应用程序应该只允许请求 account.read 范围。因为,如果允许用户管理帐户,那么您需要确保只有使用您的应用才能做到这一点。

    因此您可以“规范化”政策。

    1.

    options.AddPolicy("Account", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account"));
    

    对于 2.

    options.AddPolicy("AccountDelete", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account.delete"));
    options.AddPolicy("AccountWrite", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account.write"));
    options.AddPolicy("AccountRead", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account.read"));
    

    想想看,基于上面提到的客户应用,还有第三种选择:

    1. 您可以根据方法授权 客户端,例如AccountRead Index 方法和 Account 用于其他方法。其中AccountRead 必须包含帐户范围。

    政策将如下所示:

    // policy to allow client access to write and delete functionality
    options.AddPolicy("Account", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account"));
    // policy to allow client access to read functionality only
    options.AddPolicy("AccountRead", policy => 
        policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.read"));
    

    管理应用只需请求account 范围,而客户应用可以请求account.read 范围。

    请注意,最后一部分没有回答您原来的问题,但可能会回答 cmets 中提出的问题。

    【讨论】:

    • 不应该是这样的吗? options.AddPolicy("Account", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account")); options.AddPolicy("AccountWrite", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.write")); options.AddPolicy("AccountRead", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.read"));
    • @001 这只是一个展示可能性的例子。我不确定你是如何设计的。特别是帐户范围和政策。如果我有 account.read、account.write 和 account.delete 范围,我不会使用帐户范围。帐户政策也有点“奇怪”。我不会使用帐户策略来保护功能,而是将其替换为 AccountDelete,从而产生以下策略:读取、写入、删除。帐户范围无处不在(如图所示)与相应范围相结合。
    • @001 如果您只想为帐户范围提供单独的功能,那么您应该使用您已评论的行。其中帐户还可以访问受 AccountRead 和 AccountWrite 保护的代码。
    • 如果我按照你的方式做,为什么我们需要“帐户”作为范围?为什么不只是“account.read”、“account.write”、“account.delete”?
    • 就像这样... options.AddPolicy("Account", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account.read", "account.write", "account.delete" )); options.AddPolicy("AccountWrite", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account.read", "account.write")); options.AddPolicy("AccountRead", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account.read"));
    猜你喜欢
    • 1970-01-01
    • 2016-06-07
    • 2021-03-28
    • 2021-12-27
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多