如何添加具有多个范围的授权策略?

时间:2020-03-04 13:32:31

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

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

如何将“或”添加到策略范围?

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

1 个答案:

答案 0 :(得分: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"));

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

拥有范围意味着 client 被授权访问资源,无论哪个用户使用该客户端。

作用域标记了执行特定任务的资源的一部分,换句话说,它具有某些功能。

假设一个CRUD AccountController:

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

  2. 您可以为每种方法授权 client ,例如account.read Index 方法,account.write Create Update 方法以及account.delete删除方法。由于功能上的差异,合并范围不太可能。

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

什么是适合您的设计?

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

在这种情况下,应允许客户的 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. 您可以按照每种方法授权 client ,例如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范围。

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