.NET7 API如何按Http Method动态设置不同授权策略?
实现按HTTP方法动态分配授权策略(无需逐个添加特性)
完全可以不需要给每个控制器方法添加[Authorize]特性,通过以下两种方式实现按GET/POST请求分配不同授权策略:
方法一:路由层面按HTTP方法拆分配置
直接在UseEndpoints中针对不同HTTP方法的路由分别绑定授权策略,代码示例:
app.UseEndpoints(endpoints => { // 为所有GET请求绑定"GetPolicy"授权策略 endpoints.MapControllers() .RequireAuthorization("GetPolicy") .WithMetadata(new HttpMethodMetadata(new[] { HttpMethod.Get })); // 为所有POST请求绑定"PostPolicy"授权策略 endpoints.MapControllers() .RequireAuthorization("PostPolicy") .WithMetadata(new HttpMethodMetadata(new[] { HttpMethod.Post })); // 其他HTTP方法(如PUT/DELETE)沿用原有的"MyPolicy" endpoints.MapControllers() .RequireAuthorization("MyPolicy") .WithMetadata(new HttpMethodMetadata(new[] { HttpMethod.Put, HttpMethod.Delete })); });
这种方式逻辑直观,直接通过路由元数据筛选HTTP方法,绑定对应的策略,无需修改任何控制器代码。
方法二:自定义动态授权策略
通过自定义授权要求和处理器,在统一策略中根据HTTP方法自动切换验证逻辑:
1. 定义授权要求
public class HttpMethodAuthorizationRequirement : IAuthorizationRequirement { public HttpMethod AllowedMethod { get; } public string TargetPolicy { get; } public HttpMethodAuthorizationRequirement(HttpMethod allowedMethod, string targetPolicy) { AllowedMethod = allowedMethod; TargetPolicy = targetPolicy; } }
2. 实现授权处理器
public class HttpMethodAuthorizationHandler : AuthorizationHandler<HttpMethodAuthorizationRequirement> { private readonly IAuthorizationPolicyProvider _policyProvider; private readonly IAuthorizationService _authorizationService; public HttpMethodAuthorizationHandler(IAuthorizationPolicyProvider policyProvider, IAuthorizationService authorizationService) { _policyProvider = policyProvider; _authorizationService = authorizationService; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, HttpMethodAuthorizationRequirement requirement) { if (context.Resource is not HttpContext httpContext) return; // 匹配当前请求的HTTP方法时,验证对应策略 if (httpContext.Request.Method.Equals(requirement.AllowedMethod.Method, StringComparison.OrdinalIgnoreCase)) { var targetPolicy = await _policyProvider.GetPolicyAsync(requirement.TargetPolicy); if (targetPolicy != null) { var authResult = await _authorizationService.AuthorizeAsync(context.User, httpContext, targetPolicy); if (authResult.Succeeded) context.Succeed(requirement); } } else { // 不匹配当前方法时,跳过该要求,交给其他规则处理 context.Succeed(requirement); } } }
3. 注册服务与策略
builder.Services.AddAuthorization(options => { // 注册动态策略,关联不同HTTP方法与具体策略 options.AddPolicy("DynamicHttpMethodPolicy", policy => { policy.AddRequirements( new HttpMethodAuthorizationRequirement(HttpMethod.Get, "GetPolicy"), new HttpMethodAuthorizationRequirement(HttpMethod.Post, "PostPolicy"), new HttpMethodAuthorizationRequirement(HttpMethod.Put, "MyPolicy"), new HttpMethodAuthorizationRequirement(HttpMethod.Delete, "MyPolicy") ); }); // 定义具体的授权策略逻辑 options.AddPolicy("GetPolicy", policy => policy.RequireClaim("Permission", "Read")); options.AddPolicy("PostPolicy", policy => policy.RequireClaim("Permission", "Write")); options.AddPolicy("MyPolicy", policy => policy.RequireAuthenticatedUser()); }); // 注册自定义授权处理器 builder.Services.AddScoped<IAuthorizationHandler, HttpMethodAuthorizationHandler>();
4. 应用动态策略
app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute().RequireAuthorization("DynamicHttpMethodPolicy"); });
这种方式适合需要集中管理HTTP方法与策略映射关系的场景,扩展性更强。
内容的提问来源于stack exchange,提问作者Curious George
相关产品推荐
相关产品推荐

