外部 UserManager 和内存中 SignInManager

Posted

技术标签:

【中文标题】外部 UserManager 和内存中 SignInManager【英文标题】:External UserManager and in-memory SignInManager 【发布时间】:2021-05-31 00:11:58 【问题描述】:

我有一个相当具体的用例,我只能在互联网上找到教程或文章同时使用 UserManager 和 SignInManager,一种方式(外部)或另一种方式(内存中),但我就是找不到拥有一个使用现有数据库中的外部用户数据的 UserManager 和一个将令牌存储在内存中的 SignInManager 的方法。

更具体地说明我的用例:

    我有一个外部 SQL 数据库,它已经存储了用户和密码哈希。不允许通过 WebAPI 添加、更新或删除这些用户,所以如果 IUserStore 抛出 UnsupportedExceptions 或 InvalidOperationExceptions 之类的,完全可以。 此外,我通过 JWT 不记名令牌 (.AddJwtBearer()) 使用身份验证。这些令牌不应存储在存储用户数据的数据库中,而不应保存在内存中。如果存储的令牌在 WebAPI 服务器重启时消失了,那完全没问题。

那么,这种方法是否可行,如果可以,如何实现?

【问题讨论】:

【参考方案1】:

我能够通过创建自定义用户存储(实现IUserPasswordStore<User>IUserAuthenticationTokenStore<User>)来解决这个问题。它从所述外部数据库获取用户数据并通过@987654323 获取(以及设置)令牌数据@ 我创建了存储 IdentityUserToken<UserKeyType> 的位置。除此之外,我还需要一个 PasswordHasher,它以与外部用户数据存储相同的方式对密码进行哈希处理。

Startup.cs我再配置一下,整体如下:

services.AddDbContext<TokenDbContext>(opt => opt.UseInMemoryDatabase(databaseName: "tokens"));

services.AddIdentityCore<User>()
    .AddUserStore<ExternalUserStore>().AddSignInManager()
    .AddTokenProvider(Program.ApplicationName, typeof(DataProtectorTokenProvider<User>));

services.AddTransient<IPasswordHasher<User>, PasswordHasher>();

byte[] key = Encoding.UTF8.GetBytes("TheKeyIGotFromSomewhereTotallySafe");

services.AddAuthentication(opt =>

    opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
)
    .AddCookie("Identity.Application")
    .AddJwtBearer(opt =>
    
        opt.TokenValidationParameters = new TokenValidationParameters
        
            ValidateActor = false,
            ValidateAudience = false,
            ValidateIssuer = false,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ClockSkew = TimeSpan.Zero,
        ;
    );

【讨论】:

以上是关于外部 UserManager 和内存中 SignInManager的主要内容,如果未能解决你的问题,请参考以下文章

在接口中使用 AspNetCore.Identity RoleManager 和 UserManager

如何在 DI 中注册自定义 UserStore 和 UserManager

在类库中创建 UserManager

如何扩展/覆盖 UserManager

为啥使用 JWT 时 UserManager.GetUserAsync 返回 null?

如何在 C# 页面 ASP.NET Core MVC 上使用 SignInManager 和 Usermanager