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

Asp.Net Core 服务器运行时如何增删改authentication schemes

结论

可以在Asp.Net Core服务不重启的状态下完成认证方案(authentication schemes)的新增、修改、删除操作,但默认的内置实现不支持运行时变更,需要通过替换官方的IAuthenticationSchemeProvider实现来完成需求。

实现原理

Asp.Net Core默认的AuthenticationSchemeProvider会将服务启动时注册的所有认证方案存储在内部的只读字典中,初始化后不允许修改。我们只需要自定义该接口的实现,用线程安全的可变集合存储认证方案,再替换掉默认的服务注册即可。

核心实现步骤

1. 自定义动态认证方案提供器

using Microsoft.AspNetCore.Authentication;
using System.Collections.Concurrent;

public class DynamicAuthenticationSchemeProvider : IAuthenticationSchemeProvider
{
    // 线程安全字典存储所有动态+静态认证方案
    private readonly ConcurrentDictionary<string, AuthenticationScheme> _schemeCache = new();
    // 可自行扩展字段存储各类默认方案配置
    private AuthenticationScheme? _defaultAuthenticateScheme;

    public Task<AuthenticationScheme?> GetSchemeAsync(string name)
    {
        _schemeCache.TryGetValue(name, out var scheme);
        return Task.FromResult(scheme);
    }

    public Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync()
    {
        return Task.FromResult(_schemeCache.Values.AsEnumerable());
    }

    public Task<AuthenticationScheme?> GetDefaultAuthenticateSchemeAsync()
    {
        return Task.FromResult(_defaultAuthenticateScheme);
    }

    // 剩余默认方案接口(Challenge、Forbid、SignIn、SignOut)可根据自身业务需求实现,也可直接复用默认逻辑
    public Task<AuthenticationScheme?> GetDefaultChallengeSchemeAsync() => GetDefaultAuthenticateSchemeAsync();
    public Task<AuthenticationScheme?> GetDefaultForbidSchemeAsync() => GetDefaultAuthenticateSchemeAsync();
    public Task<AuthenticationScheme?> GetDefaultSignInSchemeAsync() => GetDefaultAuthenticateSchemeAsync();
    public Task<AuthenticationScheme?> GetDefaultSignOutSchemeAsync() => GetDefaultAuthenticateSchemeAsync();

    // 扩展新增方案方法
    public Task AddSchemeAsync(AuthenticationScheme scheme)
    {
        if (scheme == null) throw new ArgumentNullException(nameof(scheme));
        _schemeCache.AddOrUpdate(scheme.Name, scheme, (key, old) => scheme);
        return Task.CompletedTask;
    }

    // 扩展删除方案方法
    public Task RemoveSchemeAsync(string schemeName)
    {
        _schemeCache.TryRemove(schemeName, out _);
        return Task.CompletedTask;
    }

    // 扩展设置默认方案方法
    public void SetDefaultAuthenticateScheme(AuthenticationScheme scheme)
    {
        _defaultAuthenticateScheme = scheme;
    }
}

2. 替换默认服务注册

在Program.cs中注册认证服务后,替换默认的IAuthenticationSchemeProvider实现:

var builder = WebApplication.CreateBuilder(args);

// 原有认证注册逻辑保留
builder.Services.AddAuthentication(options =>
{
    // 初始默认方案配置按需填写
})
.AddJwtBearer()
.AddCookie();

// 替换为自定义动态实现
builder.Services.AddSingleton<IAuthenticationSchemeProvider, DynamicAuthenticationSchemeProvider>();

// 其他服务注册、中间件配置逻辑不变

3. 运行时新增认证方案示例

可在业务代码(如控制器接口、后台服务)中直接调用自定义提供器的方法操作方案:

[ApiController]
[Route("api/auth-scheme")]
public class AuthSchemeController : ControllerBase
{
    private readonly DynamicAuthenticationSchemeProvider _dynamicSchemeProvider;

    public AuthSchemeController(IAuthenticationSchemeProvider schemeProvider)
    {
        _dynamicSchemeProvider = (DynamicAuthenticationSchemeProvider)schemeProvider;
    }

    [HttpPost("add-jwt")]
    public async Task<IActionResult> AddJwtScheme(string schemeName, string authority, string audience)
    {
        // 构造新的JWT认证配置
        var jwtOptions = new JwtBearerOptions
        {
            Authority = authority,
            Audience = audience,
            TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true
            }
        };

        // 构造认证方案对象,指定对应的Handler类型
        var newScheme = new AuthenticationScheme(schemeName, typeof(JwtBearerHandler), jwtOptions);
        await _dynamicSchemeProvider.AddSchemeAsync(newScheme);

        return Ok($"认证方案{schemeName}已添加,无需重启服务即可使用");
    }
}
注意事项
  • 动态添加的认证方案默认不会持久化,服务重启后会丢失。如果需要持久化,可将方案配置存储在数据库、配置中心等介质,服务启动时批量加载到自定义提供器中即可。
  • 涉及OAuth、OpenIdConnect等需要回调地址的第三方认证方案时,要确保动态添加的方案对应的回调路径没有冲突。
  • 多线程操作时无需额外加锁,ConcurrentDictionary已经保证了线程安全。

内容的提问来源于stack exchange,提问作者Roi Shabtai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:06:04