我有一个现有的系统,它使用Identity Server 4,OpenIDConnect的隐式代码流和带有MongoDbStore的AspNetCore Identity。用户当前使用用户名和密码注册/登录。我正在尝试允许用户使用ID和PIN登录,这些ID和PIN将根据单独的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>();
}
登录进程是一个单独的进程,与客户端或资源无关。因此,生成的令牌不受用户登录方式的影响。因此,无需更改客户端,资源或使用/更改配置文件服务。
我要做的是,使用现有的框架进行配置等,并创建自己的商店进行用户验证。因为如何验证用户并不重要。
"默认"代码(来自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 并在第二步中验证引脚。