如何添加具有多个作用域的授权策略?

How to add an authorization policy with multiple scopes?

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 添加到策略范围?

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

RequireClaim(String, String[])

claimType String

The claim type required.

allowedValues IEnumerable

Values the claim must process one or more of for evaluation to succeed.

在你的情况下是这样的:

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 删除 方法。由于功能不同,不可能混合使用作用域。

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

什么样的设计适合您?

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

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

因此您可以 'normalize' 政策。

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 范围。

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