gpt4 book ai didi

c# - 在中间件之前调用自定义 AuthenticationHandler

转载 作者:太空宇宙 更新时间:2023-11-03 11:59:44 26 4
gpt4 key购买 nike

我有一个 ASP.NET Core WebAPI (2.2),它使用两种类型的身份验证:

  • JWTBearer
  • APIKey(自定义)

这就是我在 Startup.cs 中配置它的方式:

services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddApiKeyAuthentication(options => Configuration.Bind("ApiKeyAuth", options));

services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
jwtOptions.Events = new JwtBearerEvents
{
OnAuthenticationFailed = AuthenticationFailed
};
});

我的 Controller 装饰有包含这两种方案的 Authorize 属性。因此,我可以使用不记名 token 或通过在 header 中指定 API key 来调用我的 Web 方法 - 效果很好。

现在我添加了一个自定义中间件,我在其中执行一些特定于租户的检查。我在 Configure 方法中注册了中间件(在 UseAuthentication 之后):

// ....
app.UseAuthentication();
app.UseMiddleware<CustomMiddleware>()

现在,如果我使用 bearer 身份验证调用 REST 方法,我的 CustomMiddleware 将通过身份验证用户调用 - 我可以 访问声明。

如果我使用我的自定义 APIKey 身份验证调用相同 REST 方法,我的 CustomMiddleware 会在我的之前被调用AuthenticationHandler.HandleAuthenticateAsync() 方法。用户通过身份验证 - 我无法访问声明(我将自己填充到 HandleAuthenticateAsync 方法中)。

为什么要在认证前调用中间件?我怎样才能改变这种行为,以便在 HandleAuthenticateAsync() 之后 调用中间件?

最佳答案

您需要设置一个前向默认选择器,以便在必要时将 API key 身份验证方案设置为默认方案。

这是一个例子:

services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
jwtOptions.Events = new JwtBearerEvents
{
OnAuthenticationFailed = AuthenticationFailed
};
jwtOptions.ForwardDefaultSelector = ctx =>
{
if (ctx.Request.Headers.TryGetValue("Api-Key", out var headerValues))
{
return "ApiKeyAuth";
}

return null;
};
})
.AddApiKeyAuthentication(options => Configuration.Bind("ApiKeyAuth", options));

我做了一些猜测来构建选择器,但基本上如果应该使用另一个方案,它需要返回另一个方案的名称,否则为 null。

在示例中,它检查请求中是否包含“Api-Key” header ,如果是,则返回“ApiKeyAuth”,这是 API key 方案的名称。如果它们不同,请将它们交换为您的值。

如果在两个方案中都使用了 Authorization: Bearer xyz header ,您需要检查选择器中的 header 内容才能做出决定。

关于c# - 在中间件之前调用自定义 AuthenticationHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57586728/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com