Asp .Net Core 系列:详解授权以及实现角色、策略、自定义三种授权和自定义响应

什么是授权(Authorization)?

在 ASP.NET Core 中,授权(Authorization)是控制对应用资源的访问的过程。它决定了哪些用户或用户组可以访问特定的资源或执行特定的操作。授权通常与身份验证(Authentication)一起使用,身份验证是验证用户身份的过程,授权与身份验证相互独立, 但是,授权需要一种身份验证机制。 身份验证是确定用户标识的一个过程。 身份验证可为当前用户创建一个或多个标识。

授权类型

  • 简单授权
  • 基于角色的授权
  • 基于策略的授权

简单的授权

配置身份验证中间件

            //鉴权 (核心源码就是AuthenticationMiddleware中间件)             app.UseAuthentication();             //授权             app.UseAuthorization(); 

使用授权

ASP.NET Core 中的授权通过 [Authorize] 属性及其各种参数控制。 在其最基本的形式中,通过向控制器、操作或 Razor Page 应用 [Authorize]` 属性,可限制为仅允许经过身份验证的用户访问该组件。
要实现默认的授权行为,你可以简单地在需要限制访问的控制器或操作上使用 [Authorize] 属性,而不必指定任何特定的角色或策略。这样,只有经过身份验证的用户才能访问这些资源。

        [Authorize]         public IActionResult Info()         {             return View();         } 
  • [AllowAnonymous] 绕过授权语句。 如果将 [AllowAnonymous] 和某个 [Authorize] 属性结合使用,系统将忽略 [Authorize] 属性。 例如,如果在控制器级别应用 [AllowAnonymous]
    • 将忽略来自同一控制器上的属性 [Authorize] 或控制器上的操作方法的任何授权要求。
    • 身份验证中间件不会短路,但不需要成功。

授权原理

https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs

https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authorization/Policy/src/PolicyEvaluator.cs

 static AuthenticateResult DefaultAuthenticateResult(HttpContext context)         {             return (context.User?.Identity?.IsAuthenticated ?? false)                 ? AuthenticateResult.Success(new AuthenticationTicket(context.User, "context.User"))                 : AuthenticateResult.NoResult();         } 

基于角色的授权

创建标识时,它可能属于一个或多个角色。 例如,Tracy 可能属于 AdminUser 角色,而 Scott 只属于 User 角色。 如何创建和管理这些角色取决于授权过程的后备存储。

配置身份验证中间件

            //鉴权 (核心源码就是AuthenticationMiddleware中间件)             app.UseAuthentication();             //授权             app.UseAuthorization(); 

使用授权

仅当用户为 adminuser 角色成员时才可访问 Info

       [Authorize(Roles ="admin,user")]         public IActionResult Info()         {             return View();         } 

基于声明策略的授权

创建标识后,可为其分配一个或多个由受信任方颁发的声明。 声明是一个名称值对,表示使用者是什么,而不是使用者可以做什么。

配置策略

            builder.Services.AddAuthorization(options =>             {                 options.AddPolicy("AdminPolicy", policyBuilder =>                 {                     policyBuilder.RequireRole("admin");                 });             }); 

使用授权

        [Authorize(Policy = "AdminPolicy")]         public IActionResult Info()         {             return View();         } 

基于自定义策略的授权

在底层,基于角色的授权基于声明的授权均使用要求、要求处理程序和预配置的策略。 这些构建基块支持代码中的授权评估的表达式。 其结果为一个更丰富、可重用且可测试的授权结构。

配置策略

            builder.Services.AddAuthorization(options =>             {                 options.AddPolicy("PermissionPolicy", policyBuilder =>                 {                     policyBuilder.Requirements.Add(new PermissionRequirement());                 });             }); 

配置授权处理程序

IAuthorizationRequirement 是一项没有方法的标记服务以及用于跟踪授权是否成功的机制。

每个 IAuthorizationHandler 负责检查是否满足要求

    /// <summary>     /// IAuthorizationRequirement的接口标识     /// </summary>     public class PermissionRequirement : IAuthorizationRequirement     {      }      public class PermissionHandler : AuthorizationHandler<PermissionRequirement>     {         private readonly IHttpContextAccessor _accessor;         public PermissionHandler(IHttpContextAccessor accessor)         {             _accessor = accessor;         }         protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)         {             if (context.User == null || context.User?.Identity?.IsAuthenticated == false)             {                 //await _accessor.HttpContext.Response.WriteAsJsonAsync(new { code = 401, message = "请先登录" });                 context.Fail();             }             else             {                 var role = context.User.Claims.Where(i => i.Type == ClaimTypes.Role).FirstOrDefault();                 //查数据库                 if (role != null && role.Value == "admin")                 {                     context.Succeed(requirement);                 }                 else                 {                     context.Fail();                 }             }             await Task.CompletedTask;         }     } 

使用授权

        [Authorize(Policy= "TestPolicy")]         public IActionResult Info()         {             return View();         } 

自定义响应

应用可以注册 IAuthorizationMiddlewareResultHandler,以自定义 AuthorizationMiddleware 处理授权结果的方式。 应用可将 IAuthorizationMiddlewareResultHandler 用于:

  • 返回自定义的响应。
  • 增强默认质询或禁止响应。
    public class PermissionResultHandler : IAuthorizationMiddlewareResultHandler     {         public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)         {             //var endPoint = context.GetEndpoint();              //var controllerActionDescriptor = (ControllerActionDescriptor)endPoint.Metadata             //  .ToList().FirstOrDefault(d => d is ControllerActionDescriptor);              //var controllerName = controllerActionDescriptor.ControllerName;              //var actionName = controllerActionDescriptor.ActionName;              if (!context.User.Identity.IsAuthenticated)             {                 context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;                 await context.Response.WriteAsync("{"data":{"succeeded":false,"code":401,"message":"登录已过期,请重新登录"}}");                 return;             }              if (!authorizeResult.Succeeded)             {                 await context.Response.WriteAsync("{"data":{"succeeded":false,"code":403,"message":"您没有权限操作"}}");                 return;             }              await next(context);         }     } 

Asp .Net Core 系列:详解授权以及实现角色、策略、自定义三种授权和自定义响应

发表评论

评论已关闭。

相关文章