You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:32:16