.net 6 Policy-based authorization 基于策略授权
策略授权包含一个或多个要求(Requirement)。 在应用的 文件中将其注册为授权服务配置的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;