代码柴郡猫

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用框架: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 响应状态码。

以上只是简单的用法,更多详细的用法见
官网教程-基于策略的授权

posted on 2020-10-12 17:58  myfor  阅读(923)  评论(0编辑  收藏  举报