1

У меня есть веб-API .NET Core 1.1, который использует промежуточное программное обеспечение для проверки подлинности 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>()); 
    }); 
}); 

и

app.UseJwtBearerAuthentication(new JwtBearerOptions 
{ 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    TokenValidationParameters = tokenValidationParameters, 
    Events = new JwtBearerEvents() 
    { 
     OnMessageReceived = async (context) => 
     { 
      Debug.WriteLine("====> JWT Message received"); 
     }, 
     OnTokenValidated = async (context) => 
     { 
      Debug.WriteLine("====> JWT token validated"); 
      context.HttpContext.Items["JwtTokenIsValid"] = true; 
     }, 
     OnAuthenticationFailed = async (context) => 
     { 
      Debug.WriteLine("====> JWT token failed auth"); 
      context.HttpContext.Items["JwtTokenIsValid"] = false; 
      if ((AuthenticationType.IdServer & authTypes) != 0) 
       context.SkipToNextMiddleware(); 
     } 
    } 
}); 

Когда я звоню конечную точку, защищенную [Authorize("AuthorizeMercuryEndpoint")] и действительным маркер JWT, вызов завершается успешно, как ожидалось, и я вижу следующие отладки, написанного процесс:

====> JWT Message received 
====> JWT token validated 
====> Request authorized (when the auth filter succeeds) 

Однако, если я не передать маркер, промежуточное JWT появляется передать запрос прямо к фильтру авторизации без attempti ng - ни OnTokenValidated, ни OnAuthenticationFailed вызываются, а когда авторизация завершается с ошибкой (поскольку аутентификация отсутствует), конвейер завершается.

Это проблема, потому что я хочу передать запрос второстепенному средству проверки подлинности, если проверка маркера JWT не позволяет выполнить первоначальную аутентификацию.

Кто-нибудь знает, какой рекомендуемый подход для этого?

ответ

1

Связующее ПО JWT применяет часть проверки только в том случае, если находит HTTP-запрос, как вы можете see here.

Атрибут Authorize теперь содержит свойство ActiveAuthenticationSchemes, которое определяет, какие схемы аутентификации будут выполнены для проверки подлинности пользователя. Преимущество этого заключается в том, что теперь вы можете удалить AutomaticAuthenticate в параметрах промежуточного программного обеспечения JWT, и он будет выполняться лениво, когда это необходимо - например, если пользователь нажимает на действие, которое не требует аутентификации, оно не будет выполнено.

Возможно, вам может не понравиться, что MVC не остановится после успешной реализации схемы аутентификации, поскольку вы можете see here. Если это компромисс, который вы готовы принять, я думаю, что это хороший путь.

+0

Отличный ответ, приятно видеть код, спасибо. Ваш последний комментарий - вы имеете в виду, что если у меня есть метод проверки подлинности> 1, они будут вызываться один за другим независимо от того, удастся ли вам это или нет? Если это так, я рассмотрел это, добавив значение в значение context.HttpContext.Items, которое последующая аутентификация может использовать для пропуска, если ранее была выполнена аутентификация, - похоже на правильное решение? – Peter

+0

Не беспокойся, рад, что это помогло. Что касается вашего вопроса, да, MVC будет ссылаться на все ваши схемы аутентификации и не остановится, как только будет успешным. У меня может не быть полной картины, но вам действительно нужно прекратить работу, когда одна схема аутентификации завершается успешно? –

+0

@ MickaëlDerriey вы упоминаете, что «Аутентификация ... будет выполняться лениво, когда это необходимо», знаете ли вы, как заставить NETCore2 выполнять всегда. Вопрос связан с проблемой: https://stackoverflow.com/questions/46685448/netcore2-how-to-populate-user-without-setting-authorize-attribute-in-controller – Riga