Policy-Based Authorization in ASP.NET Core
2021-01-04 12:31
标签:系统 状态 set 接口 ocs dmi await tle 接受 Authorization 在 应用软件中 可以让确保用户是否可以获取资源,执行操作,或者对资源进行操作。 Asp.Net Core 中有两种方式: 基于 Role 是文本字符串,值被 如果未指定参数,则该属性仅检查用户是否经过身份验证( 此外,Authorize属性还可以通过 这里要提到一点, 在Asp.Net 2.0 可以自定义 授权筛选器, 但最好的方式还是使用默认的筛选器依赖 角色本质上是平层概念。解决上述问题虽然可以通过创建不同的Role来实现 Asp.Net Core中, 基于 最简单的 builder对象使用各种扩展方法收集需求,然后构建 如果定义需求的预定义扩展方法都不适合,可以通过自己的断言来定义新的需求。方法如下: 请注意,如果您多次使用 定义 添加到中间件的每个 Checking Policies Programmatically Check of the policies from within a Razor view 已有的 样例 自定义 下面是向策略添加定制需求的方法 此外,您必须在 如前所述,一个 在 Asp.Net Core中, Policy-Based Authorization in ASP.NET Core 标签:系统 状态 set 接口 ocs dmi await tle 接受 原文地址:https://www.cnblogs.com/ArvinZhao/p/13620716.htmlPolicy-Based Authorization in ASP.NET Core
Role
或者 基于 Polocy
。 前者在 ASP.NET 本身就有的, 后者是Asp.Net Core 新增的。Authorize 属性
security layer
当作元数据(在IPrincipal
对象中检查是否存在) 以及在程序中给经过身份验证的用户 映射一组权限。 Asp.Net 中登录的用户是通过一个IPrincipal
对象来标识的, 在 Asp.Net Core 中真正的类为 Claims Identity
。 这个类公开一组 identity
集合, 每一个 identity
用 IIdentiy
对象标识,特别是 Claims Identity
对象, 这意味着任何登录的用户都带有一个 Claim
列表, 这实际上是用户状态的声明。 Username
和 Role
是连个在 Asp.Net Core 常用的两个 Claim
. 然而 Role
的存在需要 后台存储Identity
数据。就是说,通过 social
身份验证登录的用户看不到role
的信息。Authorization
(授权) 比 Authentication
(身份验证) 更进一步。 Authentication
是关于发现用户的Identity
, 而Authorization
定义了用户调用应用程序接口的需求。 用户的 Role
信息通常存储在数据库中,并在验证用户凭据时检索取出,在此情况下,Role
信息将以某种方式附加到用户帐户。IIdentity
接口提供了一个必须实现的Is In Role
方法。 Claims Identity
类通过检查Role Claim
是否在Authentication
过程产生的Claim
集合中可用来实现这个方法。在任何情况下,当用户尝试调用受保护的Controller
方法时,应该检查她的Role
。如果没有,则拒绝用户调用任何安全受保护的方法。Authorize
属性可以用来声明Controller
或者它的某些方法是受保护的。[Authorize]
public class CustomerController : Controller
{
...
}
Authentication
)。 不止于此, 这个属性也支持其他的属性参数,比如 Roles
。 Roles
属性是说拥有所示Roles
属性值列表中任何一个的用户都可以访问。 如果需要多个Role
, 可以多次指定 Authorize
属性, 或者自己实现filter
筛选器。[Authorize(Roles="admin, system"]
public class BackofficeController : Controller
{
...
}
ActiveAuthenticationSchemes
属性接受一个或多个身份验证方案。[Authorize(Roles="admin, system", ActiveAuthenticationSchemes="Cookie"]
public class BackofficeController : Controller
{
...
}
ActiveAuthenticationSchemes
属性是一个用都好分隔的字符串, 它列出了 Authorization
层在当前上下文context
信任的 Authentication
中间件组件。 如前所述,传递给ActiveAuthenticationSchemes
属性的字符串值必须与在应用程序启动时注册的Authentication
中间件(身份验证中间件)相匹配。Authentication
中间件被替换为一个具有多个handler
的service
。 这就造成了, 一个 Authentication
的 Schema
是一个选择 handler
的标签。 更多相关 Cookies, Claims and Authentication in ASP.NET Core"Authorization Filter (授权筛选器)
Authorize
属性提供的信息被 系统提供的 Authorization Filter
使用。 因为它是负责检测用户使用可以执行某项操作, 这个filter
会在 Asp.Net Core 中其他任何的筛选器之前执行。 没有被授权的用户, 可以停止取消该请求。Authorization
层。Roles, Permissions And Overrules
Roles
并不能满足所有当代的应用程序。 比如admin 下需要细分更多的权限,这会出现权限继承的问题。User, Admin, CustomerAdmin and ContentsAdmin
, 但是当类似的问题出现的时候,就需要不断地增长role。 这时就需要另外的授权方案--基于Policy
。
Policy
是什么Policy
的Authorization
框架是设计来解耦 Authorization
和 Application Logic
. 简单地说,Policy
是一个被设计成需求集合的实体,这些需求本身就是当前用户必须满足的条件。Policy
是对用户进行身份验证,而常见的需求是用户与给定的角色关联。另一个常见的需求是用户拥有一个特定的Claim
,或者一个具有特定值的特定Claim
。用最一般的术语来说,需求是关于用户身份的断言,该断言试图访问一个为真的方法。使用以下代码创建Policy
对象:var policy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("Cookie, Bearer")
.RequireAuthenticatedUser()
.RequireRole("Admin")
.RequireClaim("editor", "contents") .RequireClaim("level", "senior")
.Build();
Policy
实例。可以看到,需求作用于authentication status
and schemes
、role
以及通过authentication cookie
或bearer token
读取的声明的任何组合。var policy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("Cookie, Bearer")
.RequireAuthenticatedUser()
.RequireRole("Admin")
.RequireAssertion(ctx =>
{
return ctx.User.HasClaim("editor", "contents") ||
ctx.User.HasClaim("level", "senior");
})
.Build();
RequireRole
,那么用户必须拥有所有的 Role
. 如果您想表达一个OR
条件,那么可以使用断言。Registering Policies
Policy
是不够的,还必须在授权中间件中注册它们。为此,可以在Startup
类的ConfigureServices
方法中将授权中间件作为服务添加,如下所示:services.AddAuthorization(options=>
{
options.AddPolicy("ContentsEditor", policy =>
{
policy.AddAuthenticationSchemes("Cookie, Bearer");
policy.RequireAuthenticatedUser();
policy.RequireRole("Admin");
policy.RequireClaim("editor", "contents");
});
}
Policy
都有一个名称,该名称用于在控制器类的Authorize属性内引用该Policy
:[Authorize(Policy = "ContentsEditor")]
public IActionResult Save(Article article)
{
// ...
}
public class AdminController : Controller
{
private IAuthorizationService _authorization;
public AdminController(IAuthorizationService authorizationService)
{
_authorization = authorizationService;
}
public async Task
@{
@inject IAuthorizationService Authorization
var authorized = await Authorization.AuthorizeAsync(
User, "ContentsEditor"))}
@if (!authorized)
{
Custom Requirements
Requirement
基本上包括Claim
、Authentication
,并提供基于断言进行定制的通用机制, 但同时也可以自定义 Requirement
。 一个Policy Requirement
有两部分组成: 一个只保存数据 Requirement
类,以及一个针对用户验证数据的Authorization Handler
。 自定义的 Requirement
拓展了处理特定 Policy
的能力。 举例, 通过添加 Requirement
拓展 Content Editor Policy
, 让用户至少要有三年的工作经验。public class ExperienceRequirement : IAuthorizationRequirement
{
public int Years { get; private set; }
public ExperienceRequirement(int minimumYears)
{
Years = minimumYears;
}
}
public class ExperienceHandler :
AuthorizationHandler
Authorization Handler
读取与用户相关联的Claim
,并检查自定义的EditorSince Claim
。如果找不到,处理程序将返回失败。Claim
应该是以某种方式链接到用户的一条信息--例如,用户表中的一列--并保存到Authentication Cookie
中。 一旦拥有了对用户的引用,总是可以从声明中找到用户名,并对任何数据库或外部服务运行查询,以获得多少年的经验并使用处理程序中的信息。Authorization Handler
调用方法Succeed,传递当前Requirement
以通知Requirement
已成功验证。如果Requirement
没有通过,Handler
不需要做任何事情,只需要返回。但是,如果Handler
想要确定某个需求的失败,而不考虑同一Requirement
上的其他Handler
可能成功的事实,那么它将调用Authorization Context
对象上的Fail方法
。services.AddAuthorization(options =>
{
options.AddPolicy("AtLeast3Years",
policy => policy
.Requirements
.Add(new ExperienceRequirement(3)));
});
IAuthorization Handler
的范围内向DI系统注册新的Handler
:services.AddSingleton
Requirement
可以有多个Handler
。当多个Handler
对相同的Requirement
在DI系统中为Authorization
层注册时,至少有一个成功即可。Accessing the Current HTTP Context
Authorization Handler
的实现中,您可能需要检查请求属性或路由数据,如下所示:if (context.Resource is AuthorizationFilterContext mvc)
{
var url = mvc.HttpContext.Request.GetDisplayUrl(); ...
}
Authorization Handler Context
对象有一个类型为filter context
的 Resource 属性。filter context
根据所涉及的框架而不同。例如,MVC和SignalR发送它们自己的特定对象。是否进行类型转换取决于需要访问的内容。例如,用户信息总是存在的,所以您不需要为此进行强制转换,但是如果您想要特定于mvc的细节,比如路由信息,那么您就必须强制转换。
文章标题:Policy-Based Authorization in ASP.NET Core
文章链接:http://soscw.com/essay/40043.html