执行客户端证书 X.509 身份验证后,如何针对数据库中的 AspNetUsers 表验证客户端证书 ID。
如果我将 SignInManager与 OnValidateTCertificate 放在一起,则会在每个请求上调用它,并且 SignInManager 会在每个请求上对用户进行签名。
请告知如何仅调用一次 SignInManager 以使用 AspNetUsers 进行身份验证。请注意,客户端证书 ID 在 AspNetUsers 中存储为用户名。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.Events = new CertificateAuthenticationEvents
{
OnValidateCertificate = context =>
{
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer),
new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer)
};
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
context.Success();
return Task.CompletedTask;
}
};
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
}
根据以下URL的Barry Dorrans回复
https://github.com/blowdart/idunno.Authentication/issues/29
哦,有趣。是否有原因使证书不能包含用户信息,并且需要转到数据库来替换生成的主体?标识不是要在 cookie 身份验证之外使用的。
您在这里遇到的问题是,是的,每个请求都会调用证书验证。这是一个不幸的副作用,试图使这个交叉兼容,并且可以在正常的 asp.net 核心样式中配置。
我唯一能想到的就是将你从身份的登录管理器中获取的用户信息缓存在 redis 或其他内存缓存中,并使用证书原始数据的 sha256 哈希作为密钥,那么你就会错过数据库命中。当然,如果您想反映更改,则必须在一段时间后清除缓存。