【发布时间】:2020-03-11 11:09:15
【问题描述】:
最近我将一个 API 从 .net core 2.2 迁移到 .net core 3.0,以便使用证书实现身份验证。
我已遵循此 Microsoft 文档:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.0 来完成我的工作。但我面临一个问题: 当我调用带有 [Authorize] 属性的控制器方法时,从不执行证书验证。如果请求的标头中没有证书,我会得到一个 403,这是必需的行为,但是如果我放置证书,则假定的行为应该是指纹验证,但什么都没有......
这是我的证书验证服务:
public class CertificateValidationService
{
public bool ValidateCertificate(X509Certificate2 clientCertificate, string thumbprintToChek) =>
clientCertificate.Thumbprint.Equals(thumbprintToChek);
}
如文档中所述,在 StartUp.cs 中,我在 ConfigureServices 方法中设置了以下代码行
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options => // code from ASP.NET Core sample
{
options.AllowedCertificateTypes = CertificateTypes.All;
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
var validationService = context.HttpContext.RequestServices.GetService<CertificateValidationService>();
if (validationService.ValidateCertificate(context.ClientCertificate, Configuration.GetValue<string>("Apim:CertificateThumbprint")))
{
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();
}
else
{
context.Fail("Invalid certificate.");
}
return Task.CompletedTask;
}
};
options.Events = new CertificateAuthenticationEvents
{
OnAuthenticationFailed = context =>
{
context.Fail("Certificate not valid.");
return Task.CompletedTask;
}
};
});
services.AddCertificateForwarding(options =>
{
options.CertificateHeader = "X-ARR-ClientCert";
options.HeaderConverter = (headerValue) =>
{
X509Certificate2 clientCertificate = null;
if (!string.IsNullOrWhiteSpace(headerValue))
{
byte[] bytes = headerValue.ToByteArray();
clientCertificate = new X509Certificate2(bytes);
}
return clientCertificate;
};
});
我还使用以下代码填充了 Configure 方法:
app.UseCertificateForwarding();
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
所以当我向 API 发出请求时,CertificateForwarding 委托被调用,但身份验证委托,永远不会。
但是,我尝试在一个全新的项目(仅用于测试)中实现此身份验证,它运行良好。
【问题讨论】:
-
好吧,我已经完成了让它工作。我已经删除了我之前添加的所有代码。清理并重建解决方案,然后再次更新 StartUp.cs 和 Program.cs 并且它工作。我不明白第一次出了什么问题,因为代码保持不变。 VS缓存可能有一些问题?
标签: c# authentication x509certificate .net-core-3.0 asp.net-core-3.0