授权的内部实现参考
动态授权参考
动态授权
基于权限的授权
1.定义权限-Permissions
public class Permissions { public const string Admin = "Admin"; public const string Users = "Users"; public const string UserCreate = Users+ ".Create"; public const string UserUpdate = Users+ ".Update"; public const string UserDelete = Users+ ".Delete"; }
2.定义权限Requirement
public class PermissionAuthorizationRequirement : IAuthorizationRequirement { //表示权限的名称与Permission中常量对应 public string Name { get; set; } public PermissionAuthorizationRequirement(string name) { Name = name; } }
3.自定义授权Handler
public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionAuthorizationRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionAuthorizationRequirement requirement) { //判断用户是否有某个角色 if (context.User.IsInRole(Permissions.Admin)) { context.Succeed(requirement); } else { //取出登录用户中ClaimType为Permission的项取出,并获取其 Value 组成一个 List<string> //var permissions = context.User.Claims.Where(p => p.Type == "Permissions").Select(p => p.Value).ToList(); var permissions = context.User.Claims.Where(p => p.Type == nameof(Permissions)).Select(p => p.Value).ToList(); //验证requirement是否满足授权(验证用户权限中是否存在requirement<请求中需要的权限>中的权限) if (permissions.Any(p => p.StartsWith(requirement.Name))) { //表示将验证成功的requirement从待验证的Requirements中移除(具体内容查看AuthorizationHandlerContext源码) context.Succeed(requirement); } } return Task.CompletedTask; } }
4.注册Handler
在Program中注册
builder.Services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
5.根据定义的权限添加权限策略
builder.Services.AddAuthorization(options => { options.AddPolicy(Permissions.Users, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(Permissions.Users))); options.AddPolicy(Permissions.UserCreate, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(Permissions.UserCreate))); options.AddPolicy(Permissions.UserUpdate, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(Permissions.UserUpdate))); options.AddPolicy(Permissions.UserDelete, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(Permissions.UserDelete))); });
6.使用授权策略
以上方式需要对每个策略去做添加过于繁琐,可以通过MVC过滤器调用IAuthorizationService来简化操作
7.自定义过滤器-PermissionAuthorizeAttribute
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple =true,Inherited =true)] public class PermissionAuthorizeAttribute : Attribute, IAsyncAuthorizationFilter { public string Name { get; set; } public PermissionAuthorizeAttribute(string name) { Name = name; } public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { var authorizationService=context.HttpContext.RequestServices.GetRequiredService<IAuthorizationService>(); //调用AuthorizeAsync方法 var authorizationResult = await authorizationService.AuthorizeAsync(context.HttpContext.User, null, new PermissionAuthorizationRequirement(Name)); if (!authorizationResult.Succeeded) { context.Result = new ForbidResult(); } } }
使用授权策略改为
标签:Core,Asp,string,context,policy,Net,PermissionAuthorizationRequirement,public,Per From: https://www.cnblogs.com/sugarwxx/p/18282062