做文案需要用到的网站,嘉兴建站公司,做网站昆明,Wordpress禁止搜索内容本文主要介绍 Sang.AspNetCore.RoleBasedAuthorization[1] 库如何通过中间件实现对用户 Claim 的添加。背景前面我们介绍了通过对自定义授权策略和自定义授权处理程序的使用实现了基本的RBAC权限设计#xff0c;将大量的用户可访问资源及操作的标识直接放到用户的 JWT Token 中…本文主要介绍 Sang.AspNetCore.RoleBasedAuthorization[1] 库如何通过中间件实现对用户 Claim 的添加。背景前面我们介绍了通过对自定义授权策略和自定义授权处理程序的使用实现了基本的RBAC权限设计将大量的用户可访问资源及操作的标识直接放到用户的 JWT Token 中显然并不合适这篇文章我们主要介绍通过中间件如何根据用户的角色添加用户的 Claim。实现角色获取首先我们需要提供一个接口 IRolePermission ,需要用户自行实现 GetRolePermissionClaimsByName 通过角色名获取用户的 ListClaim。这里当然也可将用户自身拥有的特定 Claim 也加入进去。public interface IRolePermission
{/// summary/// 获取角色的所有 Permission /// /summary/// param nameroleName/param/// returns/returnsTaskListClaim GetRolePermissionClaimsByName(string roleName);
}中间件核心逻辑创建中间件 RolePermissionMiddleware ,通过 DI 注入 IRolePermission rolePermission。核心的执行逻辑为/// summary
/// 自定义中间件要执行的逻辑
/// /summary
/// param namecontext/param
/// returns/returns
public async Task Invoke(HttpContext context)
{
}要确保用户信息存在if (context.User is null)
{await _next(context);return;
}这里我们提供了一个可选的参数使中间件可以单独使用也可以仅在含有ResourceAttribute标记时执行。var endpoint context.Features.GetIEndpointFeature()?.Endpoint;
if (endpoint is null)
{await _next(context);return;
}
var endpointMetaData endpoint!.Metadata;
bool hasResourceAttribute endpointMetaData.Any(x x is ResourceAttribute);
if (!hasResourceAttribute)
{await _next(context);return;
}该中间件主要的核心逻辑为读取用户所有的角色然后查询角色对应的权限将其放入。// 获取用户的所有角色
var roles context.User.FindAll(ClaimTypes.Role);
// 逐个获取角色的 claims 并添加给 User
foreach (var role in roles.ToList())
{var roleclaims await _rolePermission.GetRolePermissionClaimsByName(role.Value);if (roleclaims.Count() 0){context.User.AddIdentity(new ClaimsIdentity(roleclaims));}
}中间件注册中间件的注册提供了可选的参数同时需要添加用户角色查询服务。添加RolePermissionExtensions/// summary
/// 添加根据角色名为 User 加入角色 Permission 的中间件
/// /summary
/// param nameapp/param
/// param nameconfigureOptions/param
/// returns/returns
public static IApplicationBuilder UseRolePermission(this IApplicationBuilder app, ActionRolePermissionOptions configureOptions)
{var options new RolePermissionOptions();configureOptions(options);return app.UseMiddlewareRolePermissionMiddleware(options);
}/// summary
/// 添加根据角色名为 User 加入角色 Permission 的中间件
/// /summary
/// param nameapp/param
/// returns/returns
public static IApplicationBuilder UseRolePermission(this IApplicationBuilder app)
{return app.UseMiddlewareRolePermissionMiddleware(new RolePermissionOptions());
}/// summary
/// 添加角色权限查询服务
/// /summary
/// typeparam nameRolePermission获取角色权限的实现/typeparam
/// param nameServices/param
public static void AddRolePermissionRolePermission(this IServiceCollection Services) where RolePermission : class, IRolePermission
{Services.AddSingletonIRolePermission, RolePermission();
}最后需要特别注意的是这个中间件启用的位置。需要在 UseAuthentication 之后 UseAuthorization 之前也就是说要在验证了用户后开始检查用户权限前将用户的角色权限赋予给 context.User。本文介绍的相关代码已经提供 Nuget 包并开源了代码感兴趣的同学可以查阅 https://github.com/sangyuxiaowu/Sang.AspNetCore.RoleBasedAuthorization如有错漏之处敬请指正。References[1] Sang.AspNetCore.RoleBasedAuthorization: https://www.nuget.org/packages/Sang.AspNetCore.RoleBasedAuthorization