.NET 7 Minimal API能否扩展默认授权策略?
问题描述
我正在使用.NET 7的Minimal API,已经在WebApplicationBuilder扩展类中配置了默认授权策略,要求用户已认证且满足ContinentRequirement:
private static void AddDefaultAuthorization(this WebApplicationBuilder builder) { builder.Services.AddAuthorization(options => { options.DefaultPolicy = builder.GetBasicAuthorizationPolicy(); }); } private static AuthorizationPolicy GetBasicAuthorizationPolicy(this WebApplicationBuilder builder) { var settings = builder.Services.BuildServiceProvider().GetRequiredService<AppSettings>(); return new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddRequirements( new ContinentRequirement(settings.Continent) ) .Build(); }
同时我使用RouteGroupBuilder定义了上传路由,并想通过自定义的WithPermissions扩展方法为该路由添加PermissionRequirement,但希望原有的默认授权要求仍然生效:
internal static class Upload { public static RouteGroupBuilder MapUploadImages(this RouteGroupBuilder routes) { routes.MapPost("/upload/images", () => Results.Ok()) .WithName("UploadImages") .WithPermissions(Permission.Upload); return routes; } }
当前的WithPermissions实现只会添加权限要求,不会触发默认授权:
public static RouteHandlerBuilder WithPermissions(this RouteHandlerBuilder builder, string[] permissions) { return builder .RequireAuthorization(gp => gp.AddRequirements( new PermissionRequirement(permissions)); }
想问有没有办法设置多个默认要求,或者为不同路由扩展默认授权策略?
解决方案
方案1:在扩展方法中合并默认策略
核心思路是在WithPermissions中获取默认授权策略,将其与新的权限要求合并,这样路由会同时满足默认要求和新增的权限要求:
public static RouteHandlerBuilder WithPermissions(this RouteHandlerBuilder builder, params string[] permissions) { // 获取已配置的默认授权策略 var authOptions = builder.ApplicationServices.GetRequiredService<IAuthorizationOptions>(); return builder.RequireAuthorization(new AuthorizationPolicyBuilder(authOptions.DefaultPolicy) // 在默认策略基础上添加权限要求 .AddRequirements(new PermissionRequirement(permissions)) .Build()); }
方案2:预定义基于默认策略的权限策略
如果权限类型固定,可以提前在授权配置中创建基于默认策略的权限专属策略,然后在路由上直接指定策略名称:
1. 修改授权配置代码
private static void AddDefaultAuthorization(this WebApplicationBuilder builder) { var defaultPolicy = builder.GetBasicAuthorizationPolicy(); builder.Services.AddAuthorization(options => { options.DefaultPolicy = defaultPolicy; // 基于默认策略,添加带上传权限的专属策略 options.AddPolicy("UploadPermission", policyBuilder => { policyBuilder.Combine(defaultPolicy); policyBuilder.AddRequirements(new PermissionRequirement(new[] { Permission.Upload })); }); // 可按需添加其他权限策略,比如编辑权限 options.AddPolicy("EditPermission", policyBuilder => { policyBuilder.Combine(defaultPolicy); policyBuilder.AddRequirements(new PermissionRequirement(new[] { Permission.Edit })); }); }); }
2. 路由中指定策略名称
routes.MapPost("/upload/images", () => Results.Ok()) .WithName("UploadImages") .RequireAuthorization("UploadPermission");
方案3:优化默认策略获取逻辑(可选)
原代码中GetBasicAuthorizationPolicy使用BuildServiceProvider可能导致服务重复创建,建议改用配置绑定的方式获取AppSettings,避免不必要的服务提供者构建:
private static AuthorizationPolicy GetBasicAuthorizationPolicy(this WebApplicationBuilder builder) { var settings = builder.Configuration.Get<AppSettings>() ?? throw new InvalidOperationException("未配置AppSettings"); return new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddRequirements(new ContinentRequirement(settings.Continent)) .Build(); }
内容的提问来源于stack exchange,提问作者AtlasPromotion
相关产品推荐
相关产品推荐

