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

.NET Core 3.1如何按配置开关全局启用/禁用认证授权

解决.NET Core 3.1根据配置全局开关API认证的问题

问题原因

你之前通过条件判断仅在启用认证时注册AddAuthentication和AddAuthorization,但控制器上的[Authorize]特性依然存在。当AuthValidationEnabled为false时,授权中间件仍会执行,但此时无任何认证方案配置,导致找不到默认ChallengeScheme,进而抛出异常。

推荐解决方案:全局调整授权策略

无需移除认证服务注册,而是通过配置授权策略,根据开关动态控制认证要求。这种方式无需修改控制器上的[Authorize]特性,全局生效且符合.NET授权体系。

步骤1:始终注册认证服务

不管开关状态,都注册JWT认证服务(保留原有JWT配置),避免中间件依赖缺失:

services.AddControllers();

// 始终注册JWT认证服务
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 从appSettings读取JWT验证配置
        var jwtSettings = Configuration.GetSection("JwtSettings");
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtSettings["Issuer"],
            ValidateAudience = true,
            ValidAudience = jwtSettings["Audience"],
            ValidateLifetime = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["SecretKey"]))
        };
    });

步骤2:根据开关配置授权策略

注册授权服务时,依据AuthValidationEnabled的值设置默认授权策略:

services.AddAuthorization(options =>
{
    if (!serviceConfigurations.AuthValidationEnabled)
    {
        // 关闭认证时,默认策略允许所有请求通过
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAssertion(_ => true)
            .Build();
    }
    else
    {
        // 开启认证时,使用原有授权规则(如要求已认证用户+指定角色)
        options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser()
            // 可添加角色验证,例如 .RequireRole("Admin", "Editor")
            .Build();
    }
});

替代方案:中间件层面跳过认证

若不想始终注册认证服务,可在授权中间件前添加自定义中间件,当开关关闭时直接标记用户为已认证,绕过授权检查:

在Configure方法中添加中间件(注意顺序):

app.UseRouting();

// 自定义中间件:关闭认证时跳过授权检查
app.Use(async (context, next) =>
{
    if (!serviceConfigurations.AuthValidationEnabled)
    {
        // 设置空的已认证用户,让授权中间件认为用户已通过验证
        context.User = new ClaimsPrincipal(new ClaimsIdentity());
        await next();
        return;
    }
    await next();
});

// 仅在开启认证时注册认证中间件
if (serviceConfigurations.AuthValidationEnabled)
{
    app.UseAuthentication();
}
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

原方案失败的核心原因

当你条件注册AddAuthentication时,关闭认证状态下UseAuthorization中间件仍会运行,但此时无任何认证方案配置。授权中间件验证失败时会尝试触发Challenge操作,没有默认ChallengeScheme就会抛出异常。上面两种方案分别通过策略允许所有请求、提前标记用户为已认证,避免了这个问题。

内容的提问来源于stack exchange,提问作者Marcel James

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:43:25