Blazor Webassembly中如何实现动态参数化授权策略
解决方案
你需要用到ASP.NET Core授权体系内置的IAuthorizationPolicyProvider扩展点,配合自定义授权特性即可实现动态参数授权,不需要提前注册上百个固定策略,你已经编写的AccessFunctionRequirement和MyAuthHandler无需修改,只需新增以下内容:
1. 实现动态策略提供器
继承默认的策略提供器,按约定规则动态生成对应权限的授权策略:
public class AccessFunctionPolicyProvider : DefaultAuthorizationPolicyProvider { public AccessFunctionPolicyProvider(IOptions<AuthorizationOptions> options) : base(options) { } public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName) { // 匹配我们约定的权限策略前缀 if (policyName.StartsWith("HasAccess:", StringComparison.OrdinalIgnoreCase)) { var functionName = policyName["HasAccess:".Length..]; // 解析出权限枚举值 if (Enum.TryParse<AuthFunctions.AccessFunctions>(functionName, out var accessFunc)) { // 动态构建带对应需求的策略 return new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddRequirements(new AccessFunctionRequirement(accessFunc)) .Build(); } } // 不匹配约定规则的策略走默认逻辑 return await base.GetPolicyAsync(policyName); } }
2. 注册相关服务
在Program.cs中注册动态策略提供器和你自己实现的授权处理器:
// 注册自定义动态策略提供器 builder.Services.AddSingleton<IAuthorizationPolicyProvider, AccessFunctionPolicyProvider>(); // 注册你实现的功能权限授权处理器 builder.Services.AddScoped<IAuthorizationHandler, MyAuthHandler>();
3. 自定义授权特性简化调用
封装自定义特性,避免手动拼接策略名称字符串:
public class HasAccessAttribute : AuthorizeAttribute { private const string PolicyPrefix = "HasAccess:"; public HasAccessAttribute(AuthFunctions.AccessFunctions accessFunc) { Policy = $"{PolicyPrefix}{accessFunc}"; } }
4. 实际使用
4.1 控制器/接口授权
直接在控制器或者Action上标注特性即可:
[HasAccess(AuthFunctions.AccessFunctions.用户管理)] public class UserController : ControllerBase { [HasAccess(AuthFunctions.AccessFunctions.删除用户)] public IActionResult DeleteUser(int userId) { // 业务逻辑 } }
4.2 Blazor组件授权
整组件授权
在组件顶部添加特性:
@attribute [HasAccess(AuthFunctions.AccessFunctions.订单导出)]
细粒度元素/字段授权
用AuthorizeView组件包裹需要控制的内容,实现按钮、字段级别的权限控制:
<!-- 只有拥有手机号编辑权限的用户可以看到输入框,否则只能看到脱敏文本 --> <AuthorizeView Policy="@($"HasAccess:{AuthFunctions.AccessFunctions.用户手机号编辑}")"> <Authorized> <InputText @bind-Value="CurrentUser.Phone" /> </Authorized> <NotAuthorized> <span>@CurrentUser.DesensitizedPhone</span> </NotAuthorized> </AuthorizeView>
你之前的疑问本质上是遗漏了IAuthorizationPolicyProvider这个官方提供的动态策略扩展点,这套方案完全适配成百上千个权限点的场景,不需要提前静态注册所有策略。
内容的提问来源于stack exchange,提问作者nobba
相关产品推荐
相关产品推荐

