Authentication 为什么我的身份验证中间件在没有提供令牌的情况下将请求传递给授权过滤器?

Authentication 为什么我的身份验证中间件在没有提供令牌的情况下将请求传递给授权过滤器?,authentication,asp.net-core,jwt,identityserver4,asp.net-core-webapi,Authentication,Asp.net Core,Jwt,Identityserver4,Asp.net Core Webapi,我有一个.NETCore1.1WebAPI,它使用JWT认证中间件和自定义授权过滤器。它们的定义如下: services.AddSingleton<IAuthorizationRequirement, MercuryEndpointAuthorizationHandler>(); services.AddSingleton<IEndpointAuthorizeDictionary, EndpointRights>(); services.AddSingleton<I

我有一个.NETCore1.1WebAPI,它使用JWT认证中间件和自定义授权过滤器。它们的定义如下:

services.AddSingleton<IAuthorizationRequirement, MercuryEndpointAuthorizationHandler>();
services.AddSingleton<IEndpointAuthorizeDictionary, EndpointRights>();
services.AddSingleton<IAuthorizationHandler, MercuryEndpointAuthorizationHandler>();

services.AddAuthorization(options =>
{
    options.AddPolicy("AuthorizeMercuryEndpoint", policy =>
    {
        policy.AddRequirements(services.BuildServiceProvider().GetService<IAuthorizationRequirement>());
    });
});
当我调用受
[Authorize(“AuthorizeMercuryEndpoint”)]
和有效JWT令牌保护的端点时,调用按预期成功,我看到进程编写了以下调试:

====>  JWT Message received
====>  JWT token validated
====>  Request authorized (when the auth filter succeeds)
但是,如果我不传递令牌,JWT中间件似乎会将请求直接传递到授权筛选器,而不尝试身份验证-既不会调用
OnTokenValidated
也不会调用
OnAuthenticationFailed
,当授权失败时(因为没有经过身份验证的标识)管道终止

这是一个问题,因为如果JWT令牌验证未能通过初始身份验证,我希望将请求传递给第二个身份验证中间件


有人知道推荐的方法是什么吗?

JWT中间件只有在HTTP请求中找到令牌时才会应用验证部分,正如您所能做的那样

Authorize
属性现在包含一个
ActiveAuthenticationSchemes
属性,该属性定义将执行哪些身份验证方案来尝试对用户进行身份验证。这样做的好处是,您现在可以删除JWT中间件选项中的
自动身份验证
,它将在需要时延迟执行,例如,如果用户点击不需要身份验证的操作,它将不会执行


不过,有一件事您可能不喜欢,那就是MVC不会在身份验证方案成功后停止,这是您可以做到的。如果你愿意这样做,我认为这是一个很好的选择。

答案很好,很高兴看到代码,谢谢。您的最后一条评论-您的意思是,如果配置了>1个身份验证方法,则无论一个方法是否成功,都会逐个调用它们?如果是这样的话,我通过向
context.HttpContext.Items
添加一个值来解决这个问题,如果以前的身份验证成功,那么后续的身份验证可以使用哪个来跳过?听起来像是正确的解决方案?不用担心,很高兴它有所帮助。关于您的问题,是的,MVC将调用您的所有身份验证方案,并且不会在一个成功后立即停止。我可能不知道全部情况,但当一个身份验证方案成功时,您真的需要停止吗?@Mickaëlderrie您提到“身份验证…将在需要时延迟执行”,您知道如何强制NETCore2始终执行吗。问题与问题有关:
====>  JWT Message received
====>  JWT token validated
====>  Request authorized (when the auth filter succeeds)