[目标netcoreapp3.1]
你好呀!因此,在Startup.cs中,我有一个受这种形式的中间件保护的Web Api:
public void ConfigureServices(IServiceCollection services)
{
//other services configuration
services.AddProtectedWebApi(options => { /* config */};
//other services configuration
}
这将验证由Azure发行的Jwt令牌,并授予对该API的访问权限;它工作正常。目前,我有一个前端有 Angular 的客户端网站,用户可以在其中通过Azure AD登录。Angular将令牌发送到我的Web API,一切正常。
我现在想使用相同的webapp来处理没有凭证但具有预先提供的客户端证书的用户的查询请求。因此,基本上,我想通过Azure或客户端证书在Angular WebSite上进行身份验证。然后,Angular会将信息跟踪到我的webapp,这将进而使用适当的方法对用户进行身份验证。
需要说明的是,我仍然希望某人能够通过使用其Azure帐户登录而无需证书。
在这种情况下,是否有一种简单的方法就可以拥有两个身份验证选项,而不必创建单独的Web应用程序?我在那儿读了一点:https : //docs.microsoft.com/zh-cn/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1#optional-client-certificates 但似乎只能在我无法使用的ASP.NET Core 5预览版。
希望接下来的事情能对某人有所帮助!我最终找到了此链接:https : //docs.microsoft.com/zh-cn/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1
它说明了如何实施多个都有成功机会的授权策略。下面是经过更多研究后发现的使用IIS的解决方案:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
//other services configuration
services.Configure<IISOptions>(options =>
{
options.ForwardClientCertificate = true;
});
services.Configure<CertificateForwardingOptions>(options =>
{
options.CertificateHeader = {/*your header present in client request*/};
});
//other services configuration
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.AllowedCertificateTypes =/*Whatever you need*/;
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
if ({/*CertValidationClass*/}.ValidateCertificate(context.ClientCertificate))
{
context.Success();
}
else
{
context.Fail("invalid cert");
}
return Task.CompletedTask;
}
};
});
services.AddProtectedWebApi(options => { /* config */};
//other services configuration
}
{CertValidationClass}是定制的服务或帮助程序类,用于验证所有我需要验证才能批准的证书。显然,你可以自己向此模板添加更多验证和操作。
我已经app.UseAuthentication(); app.UseAuthorization();
在中间件管道中使用过,无需更改它,但是你必须app.UseCertificateForwarding();
在这两个之前添加。
现在,我只需要在控制器上方指定要保护的控制器,就可以同时使用两种Authorization方法,就像这样,如果一个方法失败了,它就会落在另一个方法上,并且效果很好,我通过Insomnia发出的请求进行了测试, /无令牌和/无证书。
MyApiController.cs
[Authorize(AuthenticationSchemes = AuthSchemes)]
public class MyApiController
{
//Just add the schemes you want used here
private const string AuthSchemes =
CertificateAuthenticationDefaults.AuthenticationScheme; + "," +
JwtBearerDefaults.AuthenticationScheme;