在 ASP 网络核心中实现两个身份验证选项(令牌和证书)



[Target netcoreapp3.1]

嘿,你好!所以我有这个 Web API,它在我的 Startup 中受到这种形式的中间件的保护.cs:


public void ConfigureServices(IServiceCollection services)
{
//other services configuration
services.AddProtectedWebApi(options => { /* config */};
//other services configuration
}

这将验证 Azure 颁发的 Jwt 令牌并授予对 API 的访问权限;它工作正常。 目前,我有一个前端角度客户端网站,用户通过Azure AD登录。 Angular将令牌发送到我的Web API,一切正常。

我现在想使用相同的 Web 应用程序来处理来自没有凭据但使用预先提供的客户端证书的用户的查询请求。所以基本上,我想通过Azure或通过客户端证书在我的Angular网站上进行身份验证。然后,Angular 会将信息跟踪到我的 web 应用程序,这反过来又会使用适当的方法对用户进行身份验证。

需要明确的是,我仍然希望有人能够使用他的 Azure 帐户在没有证书的情况下登录。

在这种情况下,有没有一种简单的方法可以拥有两个身份验证选项,而无需创建单独的 Web 应用程序?我在那里读了一点:https://learn.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1#optional-client-certificates 但它似乎只适用于 ASP.NET Core 5的预览,我不能在我的情况下使用它。

希望以下内容能帮助某人! 我最终找到了这个链接:https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1

它解释了如何实现多个都有机会成功的授权策略。以下是我在经过更多研究后使用 IIS 找到的解决方案:

启动.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();

现在我只需要在我想要保护的控制器上方指定我想使用两种授权方法,就像这样,如果一种失败,它会回退到另一种并且它运行良好,我通过 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;

最新更新