使用框架:dotnet Core 3.1
语言:C#
适用人群:学习授权处理的人员
原文:.net core自定义授权处理程序-League Of Programmers
Authorization 授权,有什么作用?
当一个请求到达控制器、Action时,用它来判断该请求是否能够继续执行该控制器、Action。例如:发布一篇博文,需要用户登录后才能发布,那么就使用 Authorization 来判断该请求是否有携带用户登录信息,如果没有,则不能发布。
dotnet core 里提供了授权框架,允许开发者编写自己的授权规则,下面我们来编写一个授权规则,该规则规定,只能是管理员(Administrator)才能访问Action。
首先需要了解两个接口 interface:
namespace Microsoft.AspNetCore.Authorization
{
//
// 摘要:
// Represents an authorization requirement.
// 无方法的标记服务,以及用于跟踪授权是否成功的机制
public interface IAuthorizationRequirement
{
}
}
/// <summary>
/// Classes implementing this interface are able to make a decision if authorization
/// is allowed.
/// </summary>
public interface IAuthorizationHandler
{
/// <summary>
/// Makes a decision if authorization is allowed.
/// </summary>
/// <param name="context">The authorization information.</param>
// 负责检查是否满足要求
Task HandleAsync(AuthorizationHandlerContext context);
}
接口 IAuthorizationRequirement 表示授权的要求。我们来写一个类,实现这个接口:
// 这个接口没有任何参数,仅仅表示要求是管理员,现在没有任何用处
// 所以我们需要写一个处理程序来实现这个要求,往下看
public class IsAdministratorRequirement : IAuthorizationRequirement
{
}
接口 IAuthorizationHandler 用于实现如何检查要求,我们可以使用已经实现了该接口的抽象类 AuthorizationHandler,我们写一个新的类来继承该抽象类:
// 这个类继承了抽象类 AuthorizationHandler,它的泛型参数规定了要处理哪个要求
public class IsAdministratorHandler : AuthorizationHandler<IsAdministratorRequirement>
{
// 别忘了抽象方法,我们的处理逻辑就写在这个方法里
protected override Task HandleRequirementAsync
(AuthorizationHandlerContext context, IsAdministratorRequirement requirement)
{}
}
在方法 HandleRequirementAsync (AuthorizationHandlerContext context, IsAdministratorRequirement requirement)中,参数 AuthorizationHandlerContext context 携带了用户信息 ClaimsPrincipal, 我们可以通过
var user = context.User;
来获取到当前请求中携带的用户信息。至于用户信息是如何放到 context.User 里面的,这个不是本文的内容,是 权限 (Authentication) 的范围。
怎么表示授权成功或失败?
在方法处理方法 HandleRequirementAsync 中,调用
context.Succeed(requirement);
参数中传入处理的要求,则视为授权成功,同时你可以继续执行其他操作或是直接结束这个方法。
执行
context.Fail();
视为授权失败,就算是在这之前执行过 context.Succeed(requirement) 也视为授权失败。但此时我们只是编写了授权规则,需要将他们配置为授权策略,才能够使用它们。
配置为授权策略
在 ConfigureServices 中配置授权策略,如下:
// 添加授权处理程序 IsAdministratorHandler 到DI
services.AddSingleton<IAuthorizationHandler, IsAdministratorHandler>();
// 给该授权要求一个策略名
services.AddAuthorizationCore(options =>
{
options.AddPolicy("授权策略名", policy => policy.Requirements.Add(new IsAdministratorRequirement()));
});
通过以上两句后,我们就可以通过策略名来使用这个策略了。我们直接在需要的控制器、Action上街上特性
[Authorize(policy: "授权策略名")]
public class AdministratorController
{}
如上,如果该策略授权成功,则继续执行接下来的代码,如果失败,则会直接返回 401 响应状态码。
以上只是简单的用法,更多详细的用法见
官网教程-基于策略的授权