我有一个ASP.Net Core服务器,同时启用了http和https。它运行于IIS 10,ASP.NET CORE ~6.0。
我遵循了以下文档:[https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth](Microsoft的ASP.NET身份验证服务)
在此基础上,我创建了一个类来处理传入客户端请求的身份验证
public class CertValidationService
{
public bool ValidateCertificate(X509Certificate2 clientCertificate)
{
Log("\nInside validate"); //NOT triggered
/*my custom verification logic*/
return true;
}
public static void Handler(CertificateAuthenticationOptions options)
{
Log("\nCalled handler"); //NOT triggered
options.AllowedCertificateTypes = CertificateTypes.All;
options.Events = new CertificateAuthenticationEvents
{
OnAuthenticationFailed = OnFailed,
OnCertificateValidated = OnSuccess,
OnChallenge = OnChallenged
};
}
private static Task OnChallenged(CertificateChallengeContext context){
Log("\nInside challenge");
return Task.CompletedTask; //triggered
}
private static Task OnFailed(CertificateAuthenticationFailedContext context){
context.Fail("Failed!");
return Task.CompletedTask; //NOT triggered
}
private static Task OnSuccess(CertificateValidatedContext context){
Log("\nInside OnSuccess"); //NOT triggered
var validationService = context.HttpContext.RequestServices.GetService<CertValidationService>();
if (validationService != null && validationService.ValidateCertificate(context.ClientCertificate)){
Log("\nValidated!");
var claims = new List<Claim>{
new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.SubjectName.Name),
new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer)
};
context.Principal = new ClaimsPrincipal(
new ClaimsIdentity(
claims,
context.Scheme.Name //CertificateAuthenticationDefaults.AuthenticationScheme
)
);
context.Success();
} else {
Log("\nBad Certificate");
context.Fail("Bad Certificate");
}
return Task.CompletedTask;
}
public static void Log(string log) {
string path = "logs.txt";
try {
File.AppendAllText(path, log);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
我已经使用上面的类添加了证书验证,如下所示,虽然路由是为未经身份验证的端点触发的,但这里给出的“天气”路由不会触发ValidateCertificate方法以及成功和失败事件。要求服务器识别传入的请求是否来自伪造的apk。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
// ADDED VALIDATION
builder.Services.AddSingleton<CertValidationService>();
builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(CertValidationService.Handler);
// ----------------
builder.Services.Configure<IISServerOptions>(options => { options.AllowSynchronousIO = true; });
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
我设置了一些需要授权的路由,如下所示:
// baseURL/myroute/weather
[ApiController]
[Route("myroute")]
public class WeatherForecastController : ControllerBase
{
[HttpGet(Name = "weather")]
[Authorize(AuthenticationSchemes = CertificateAuthenticationDefaults.AuthenticationScheme)]
public string<WeatherForecast> Get()
{
return "data";
}
[HttpGet(Name = "weather_noauth")]
public string<WeatherForecast2> Get()
{
return "data";
}
}
1条答案
按热度按时间q3qa4bjr1#
这可能是因为证书在您的机器中不被识别为有效。您可能需要添加以下内容: