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

如何在ASP.NET Core 5中借助Identity实现两层独立身份认证授权?

方案可行性结论

ASP.NET Core Identity 完全支持你要求的两层独立认证授权架构,不需要做过度改造即可满足「第一层内存存储、第二层DB存储」的合规要求,两层逻辑完全隔离,可分别对应客户端自动接入、用户人工登录的流程。

落地实现步骤

第一层:客户端接入认证授权(内存存储)

  • 不复用Identity默认的用户体系,基于ASP.NET Core多认证方案机制,单独注册一套客户端专属的认证方案,和第二层用户认证完全隔离:
// Program.cs 中注册客户端认证方案
builder.Services.AddAuthentication()
    // 单独注册客户端接入认证方案,不要和用户认证共用
    .AddScheme<ClientAccessTokenAuthOptions, ClientAccessTokenAuthHandler>("ClientAccess", opt => { });

// 注册全局单例的客户端会话管理器,所有数据仅存内存
builder.Services.AddSingleton<IClientSessionManager, ClientSessionManager>();
  • 客户端会话、在线计数全在内存中维护,自己实现IClientSessionManager单例服务,内部用ConcurrentDictionary存储合法接入的客户端ID、角色、过期时间,用原子操作Interlocked统计在线数量,超过license阈值直接拒绝接入:
public class ClientSessionManager : IClientSessionManager
{
    private readonly ConcurrentDictionary<string, ClientSession> _validSessions = new();
    private int _onlineClientCount;
    // 按实际license额度配置
    private const int LicenseUpperLimit = 500;

    public (bool IsAllowed, string AccessToken) TryCreateClientSession(ClientType clientType)
    {
        // 原子计数避免并发问题
        if (Interlocked.Increment(ref _onlineClientCount) > LicenseUpperLimit)
        {
            Interlocked.Decrement(ref _onlineClientCount);
            return (false, string.Empty);
        }
        var accessToken = Guid.NewGuid().ToString("N");
        _validSessions.TryAdd(accessToken, new ClientSession
        {
            ClientRole = clientType.ToString(),
            ExpireAt = DateTime.Now.AddHours(2)
        });
        return (true, accessToken);
    }
}
  • 客户端角色校验直接用原生授权特性实现,需要客户端接入才能访问的接口直接标注[Authorize(AuthenticationSchemes = "ClientAccess", Roles = "公众客户端,员工客户端,管理员客户端")],校验逻辑全在内存执行,不需要落库。
  • 客户端认证通过后,将客户端角色存入Claim,后续第二层用户登录时可直接读取该Claim限制用户登录类型,符合你的业务规则要求。

第二层:用户身份认证授权(DB存储)

  • 这一层直接用ASP.NET Core Identity原生实现即可,注册默认的IdentityUser、IdentityRole体系,配置EF Core关联业务DB,密码哈希、角色校验、登录态管理等能力直接复用原生功能,不需要额外改造:
// Program.cs 中注册Identity用户认证
builder.Services.AddDbContext<ApplicationDbContext>(opt => 
    opt.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
builder.Services.AddIdentityCore<IdentityUser>(opt => { })
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();
  • 接口授权可配置双认证方案校验,业务接口要求同时通过客户端接入认证和用户认证才能访问:
// 全局授权策略配置
builder.Services.AddAuthorization(opt =>
{
    opt.AddPolicy("BizAccess", policy =>
    {
        policy.AddAuthenticationSchemes("ClientAccess", IdentityConstants.ApplicationScheme);
        policy.RequireAuthenticatedUser();
    });
});
// 业务接口直接加特性即可
[Authorize(Policy = "BizAccess")]
public class OrderController : ControllerBase {}
  • 用户登录逻辑中新增客户端角色校验:用户提交登录请求时,先从第一层认证的Claims中读取当前客户端角色,比如客户端是公众客户端时仅允许公众用户账号登录,是员工客户端时仅允许员工账号登录,不符合要求直接返回登录失败。
核心注意事项
  • 第一层给客户端返回的AccessToken要设置过期时间,配套后台定时任务(IHostedService)定期清理过期的客户端会话,同步扣减在线计数,避免客户端异常退出导致license额度被占满。
  • 第一层的所有会话数据不要写入任何持久化存储,包括日志、分布式缓存,完全限定在服务端进程内存中,满足你的安全要求。
  • 客户端凭证不要硬编码,每次接入成功下发临时AccessToken,避免凭证泄露被恶意复用。

内容的提问来源于stack exchange,提问作者Sam Carleton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:09:03