如何在 IdentityServer 4 中配置额外的身份验证选项?

How do I configure additional authentication options in IdentityServer 4?

我有一个现有系统,它使用 Identity Server 4、OpenIDConnect 的隐式代码流和带有 MongoDbStore 的 AspNetCore Identity。当前 register/login 有用户名和密码的用户。我正在尝试允许用户使用 ID 和 PINS 登录,这些 ID 和 PINS 将针对单独的 Mongo 集合进行验证。我需要帮助确定此功能的最佳方法。这本质上是使用配置文件服务的多租户吗?我是否配置新客户端?我可以有条件地覆盖验证吗?

这是我 Startup.cs 中的 ConfigureServices 方法:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentity<ApplicationUser, ApplicationRole>(config => { config.SignIn.RequireConfirmedEmail = true; })
                .AddMongoDbStores<ApplicationUser, ApplicationRole, Guid>
                (
                    Configuration.GetSection("MongoDb:ConnectionString").Value,
                    Configuration.GetSection("MongoDb:Database").Value
                )
                .AddDefaultTokenProviders();

            services.AddServices();
            services.AddSettings(Configuration);

            services.Configure<IdentityConfig>(Configuration.GetSection("IdentityConfig"));
            services.AddScoped<IdentityConfig>(sp => sp.GetService<IOptionsSnapshot<IdentityConfig>>().Value);

            services.AddMvc();
            services.AddSession();

            IdentityConfig identityConfig = Configuration.GetSection("IdentityConfig").Get<IdentityConfig>();

            services.AddIdentityServer(options =>
            {
                if (!string.IsNullOrEmpty(identityConfig.PublicOrigin))
                {
                    options.PublicOrigin = identityConfig.PublicOrigin;
                }

                if (!string.IsNullOrEmpty(identityConfig.IssuerUri))
                {
                    options.IssuerUri = identityConfig.IssuerUri;
                }
            })
                .AddDeveloperSigningCredential()
                .AddInMemoryPersistedGrants()
                .AddInMemoryIdentityResources(GetIdentityResource(identityConfig.IdentityResources))
                .AddInMemoryApiResources(GetAPIResources(identityConfig.ApiResources))
                .AddInMemoryClients(GetClients(identityConfig.Clients))
                .AddAspNetIdentity<ApplicationUser>();
        }

登录过程是一个独立的过程,与客户端或资源无关。因此,生成的令牌不受用户登录方式的影响。因此无需更改客户端、资源或使用/更改 ProfileService。

我会做的是,使用现有的框架进行配置等,并创建您自己的商店以进行用户验证。因为您如何验证用户并不重要。

'default' 代码(来自 Account/Login)是这样的:

await _signInManager.PasswordSignInAsync(username, password, rememberLogin, true);
// If valid
var user = await _userManager.FindByNameAsync(username);

但由于您没有验证密码,使用替代商店,您可以将其替换为如下内容:

// Lookup the user first and then validate the pin
var mUser = await _mongoDbStore.FindUserByIdAsync(id);
// Your validation, e.g. by mUser or id
var isValid = await _mongoDbStore.ValidatePinAsync(id, pin);
if (isValid)
{
    // Look up the user from the Identity store,
    // using the username from the MongoDbStore.
    var user = await _userManager.FindByNameAsync(mUser.Username);

    // Sign in the user
    await _signInManager.SignInAsync(user, rememberLogin);

}

请注意,这是独立于客户端的,因为 IdentityServer 实施单点登录 (SSO)。这意味着当用户已经通过另一个客户端发起的身份验证时,用户不必登录。

如果要为每个客户端设置此项,则需要禁用 SSO(提示 = 登录)。然后您可以为每个客户端实施不同的登录方法。

如果您想为每个用户启用此功能,那么您可能希望将其实现为双因素身份验证 (2FA):AspNetUser.TwoFactorEnabled。在第二步中首先询问 Id 并验证 pin。