在 ASP.net Core Wep Api 中动态选择身份验证方案

Dynamically chose authentication scheme in ASP.net Core Wep Api

我正在将使用 OWIN 和 .NET Framework 构建的 self-hosted 网络 API 移植到 ASP.NET 核心网络 API(使用 .NET 6.0)

在原来的API中,我有一个自定义的身份验证机制,select根据请求中的header为每个调用动态设置身份验证方案:

HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemeSelectorDelegate = new AuthenticationSchemeSelector((httpRequest) =>
{
    if(httpRequest.Headers.AllKeys.Any(k => k == "MyCustomHeader"))
    {
        return AuthenticationSchemes.Ntlm;
    }
    else
    {
        return AuthenticationSchemes.Anonymous;
    }
});

基本上,对于每个请求,我都会检查请求中的特定 header,并根据此选择是强制请求使用 Windows 身份验证还是允许请求匿名进行。

如何在 ASP.net 核心网络 api 中复制此行为?我通过使用 Microsoft.AspNetCore.Authentication.Negotiate NuGet 包和配置找到了如何使用 Windows 身份验证:

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
                .AddNegotiate();

但是,我不知道如何动态地 select 是使用该方案还是像以前一样基于 header 允许匿名调用。

这可能吗?我该怎么做?

这里有一种方法

services.AddAuthentication(opts =>
    {
        opts.DefaultScheme = "DynamicAuthenticationScheme";
    })
    .AddScheme<SystemSessionAuthenticationRelatedOptions, SystemAuthenticationRelatedHandler>(
        CommonConstants.SessionAuthentication, x => x.Test = "Ran in here")
    .AddCookie("CookieScheme")
    .AddJwtBearer(options =>
    {
        options.Authority = identityUrl;
        options.Audience = "shipping";
        options.RequireHttpsMetadata = false;
    })
    .AddPolicyScheme("DynamicAuthenticationScheme", "Default system policy",
        cfgOpts => cfgOpts.ForwardDefaultSelector = ctx =>
            ctx.Request.Headers.ContainsKey("IsTheSecretHeaderPresent?")
                ? "CookieScheme"
                : JwtBearerDefaults.AuthenticationScheme);

想法是为 DynamicAuthenticationScheme 指定一个默认的身份验证方案,我们为 Cookie 和 Jwt 身份验证相应地添加了 2 个名为 CookieSchemeJwtBearerDefaults.AuthenticationScheme 常量的身份验证方案。

然后将我们的默认认证方案定义为基于头信息的认证机制的路由。