.net 6 Policy-based authorization 基于策略授权

发布时间 2023-06-19 17:08:53作者: 赵轶东

授权策略包含一个或多个要求。 在应用的 文件中将其注册为授权服务配置的一 Program.cs 部分:

builder.Services.AddSingleton<IAuthorizationHandler, User_Role_Url_AHandler1>();
builder.Services.AddAuthorization(options => { options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("管理组")); options.AddPolicy("User_Role_Url", policy => policy.Requirements.Add(new User_Role_Url_Requirement()) });
policyBuilder 是个形式参数,什么名字都可以。
涉及到的几个类:
User_Role_Url_Requirement继承自IAuthorizationRequirement,表示一个策略授权请求。通常包含名称和其他基本数据,结构比较简单。关键的是处理程序的定义,下面的程序演示授权请求(AuthorizationRequirement)与处理程序(AuthorizationHandler)是一对一关系。还有一对多、多对一关系。
public class User_Role_Url_AHandler1 : AuthorizationHandler<User_Role_Url_Requirement>
  {
    private readonly ILogger<LoginModel> _logger;
    //private readonly lctcenter2019Context _lctcenter2019Context;
    private readonly IConfiguration _configuration;
    public User_Role_Url_AHandler1(ILogger<LoginModel> logger, IConfiguration config)
    {
      _logger = logger;
      _configuration = config;
      //_lctcenter2019Context = pl;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, User_Role_Url_Requirement requirement)
    {
      //_logger.LogInformation("HandleRequirementAsync");
      Endpoint? endPoint = null;
      if (context != null && context.Resource != null)
      {
        DefaultHttpContext? dhc = context.Resource as DefaultHttpContext;
        if (dhc != null)
        {
          endPoint = dhc.GetEndpoint();         //Microsoft.AspNetCore.Http.Endpoint {Microsoft.AspNetCore.Routing.RouteEndpoint 大括号中是真实类型}

          if (endPoint != null)
          {
            //{/PolicyTest}   Microsoft.AspNetCore.Http.Endpoint {Microsoft.AspNetCore.Routing.RouteEndpoint}
            //_logger.LogInformation(string.Format(">>>>{0}<<<<", endPoint.DisplayName));
            var controllerActionDescriptor = endPoint!.Metadata
              .ToList().FirstOrDefault(d => d is ControllerActionDescriptor) as ControllerActionDescriptor;
            string controllerName, actionName;
            if (controllerActionDescriptor != null)
            {
              controllerName = controllerActionDescriptor.ControllerName;
              actionName = controllerActionDescriptor.ActionName;
            }
          }
        }
      }

      //&& context.User.IsInRole("Examine")
      if (context != null)
      {
        if (context.User.Identity == null || !context.User.Identity.IsAuthenticated)
        {
          context.Fail();
        }
        else
        {
          var roles_list = context.User.FindAll(ClaimTypes.Role);
          if (roles_list == null || !roles_list.Any())
          {
            //还没有角色
          }
          else
          {
            using (var connection = new SqlConnection(_configuration.GetConnectionString("sql_server_172")))
            {
              Microsoft.AspNetCore.Routing.RouteEndpoint rEdnp = endPoint as Microsoft.AspNetCore.Routing.RouteEndpoint;
              if (rEdnp == null)
              {
                context.Fail();
              }

              var r = connection.Query
                 ("select user_name,user_id,uid,role_id,role_name,url_xid,url,urltitle FROM vw_UserFunction WHERE (uid=@uid and url=@url)",
                 new { uid = context.User.Identity.Name, url = rEdnp.RoutePattern.RawText });
              if (rEdnp.RoutePattern.RawText == "MainTab" || r.Any())
              //if (endPoint != null && 0 == string.Compare(endPoint.DisplayName, "/Account/UserRole_boot5", true))
              {
                context.Succeed(requirement);
                //if (context.User.IsInRole("管理组"))                   //(roles_list.Any(z => z.Value == "管理组"))
                //{
                //  context.Succeed(requirement);
                //}
                //else
                //{
                //  context.Fail();
                //}
              }
              else
              {
                _logger.LogInformation(string.Format("HandleRequirementAsync【vw_UserFunction验证】>>>>{0},{1}<<<<", context.User.Identity.Name, rEdnp.RoutePattern.RawText));
                context.Fail();
              }
            }
            //foreach (var v in roles_list)
            //{
            //  _logger.LogInformation(v.Value);
            //}
          }
        }

      }
      return Task.CompletedTask;
      //return Task.FromResult(0);
    }
  }
核心过程HandleRequirementAsync中:
验证成功 context.Succeed(requirement);
验证失败 context.Fail();
最后:return Task.CompletedTask;