Можно ли поддерживать несколько эмитентов токенов JWT в ASP.NET Core 2? Я хочу предоставить API для внешней службы, и мне нужно использовать два источника токенов JWT - Firebase и настраиваемые эмитенты токенов JWT. В ядре ASP.NET я могу установить аутентификацию JWT для схемы аутентификации Bearer, но только для одного центра:
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://securetoken.google.com/my-firebase-project"
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "my-firebase-project"
ValidateAudience = true,
ValidAudience = "my-firebase-project"
ValidateLifetime = true
};
}
У меня может быть несколько эмитентов и аудиторий, но я не могу установить несколько авторитетов.
c#
firebase-authentication
asp.net-core-mvc
jwt
asp.net-core-2.0
В своем уме
источник
источник
Ответы:
Вы можете полностью достичь того, чего хотите:
services .AddAuthentication() .AddJwtBearer("Firebase", options => { options.Authority = "https://securetoken.google.com/my-firebase-project" options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "my-firebase-project" ValidateAudience = true, ValidAudience = "my-firebase-project" ValidateLifetime = true }; }) .AddJwtBearer("Custom", options => { // Configuration for your custom // JWT tokens here }); services .AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("Firebase", "Custom") .Build(); });
Давайте рассмотрим различия между вашим кодом и этим.
AddAuthentication
не имеет параметраЕсли вы установите схему проверки подлинности по умолчанию, то при каждом отдельном запросе промежуточное ПО проверки подлинности будет пытаться запустить обработчик проверки подлинности, связанный со схемой проверки подлинности по умолчанию. Поскольку теперь у нас есть две возможные схемы аутентификации, запускать одну из них нет смысла.
Используйте другую перегрузку
AddJwtBearer
Каждый
AddXXX
метод добавления аутентификации имеет несколько перегрузок:Теперь, поскольку вы используете один и тот же метод аутентификации дважды, но схемы аутентификации должны быть уникальными, вам необходимо использовать вторую перегрузку.
Обновите политику по умолчанию
Поскольку запросы больше не будут аутентифицироваться автоматически, добавление
[Authorize]
атрибутов к некоторым действиям приведет к тому, что запросы будут отклонены иHTTP 401
будет выдан.Так что это не то , что мы хотим , потому что мы хотим , чтобы обработчики проверки подлинности возможности аутентификации запроса, мы изменим политику по умолчанию системы авторизации, указав оба
Firebase
иCustom
аутентификацию схемы должно быть пытался проверить подлинность запроса.Это не мешает вам более ограничивать некоторые действия; у
[Authorize]
атрибута естьAuthenticationSchemes
свойство, позволяющее переопределить допустимые схемы аутентификации.Если у вас есть более сложные сценарии, вы можете использовать авторизацию на основе политик . Я считаю, что официальная документация прекрасна.
Представим, что некоторые действия доступны только для токенов JWT, выпущенных Firebase, и должны иметь заявку с определенным значением; вы можете сделать это так:
// Authentication code omitted for brevity services .AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("Firebase", "Custom") .Build(); options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("Firebase") .RequireClaim("role", "admin") .Build()); });
Затем вы можете использовать
[Authorize(Policy = "FirebaseAdministrators")]
для некоторых действий.И последнее, на что следует обратить внимание: если вы перехватываете
AuthenticationFailed
события и используете что-либо, кроме первойAddJwtBearer
политики, вы можете увидеть,IDX10501: Signature validation failed. Unable to match key...
что это вызвано тем, что система проверяет каждоеAddJwtBearer
по очереди, пока не найдет совпадение. Ошибка обычно игнорируется.источник
Authorization : Bearer <token>
что заголовок бытьAuthorization : Firebase <token>
например? Когда я попробовал это решение, я получил сообщение об ошибке: «Для схемы« Bearer »не зарегистрирован обработчик аутентификации»..AddJwtBearer
вызовов методов.[Authorize]
атрибутом.Это продолжение ответа Микаэля Дерри.
В нашем приложении есть настраиваемое требование авторизации, которое мы решаем из внутреннего источника. Мы использовали Auth0, но переходим на аутентификацию учетной записи Microsoft с использованием OpenID. Вот слегка отредактированный код из нашего запуска ASP.Net Core 2.1. Для будущих читателей это работает на момент написания этой статьи для указанных версий. Вызывающий использует id_token из OpenID для входящих запросов, переданных как Bearer token. Надеюсь, это поможет кому-то другому, пытающемуся преобразовать авторитет личности, так же, как этот вопрос и ответ помогли мне.
const string Auth0 = nameof(Auth0); const string MsaOpenId = nameof(MsaOpenId); string domain = "https://myAuth0App.auth0.com/"; services.AddAuthentication() .AddJwtBearer(Auth0, options => { options.Authority = domain; options.Audience = "https://myAuth0Audience.com"; }) .AddJwtBearer(MsaOpenId, options => { options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidateAudience = true, ValidAudience = "00000000-0000-0000-0000-000000000000", ValidateIssuer = true, ValidIssuer = "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", ValidateIssuerSigningKey = true, RequireExpirationTime = true, ValidateLifetime = true, RequireSignedTokens = true, ClockSkew = TimeSpan.FromMinutes(10), }; options.MetadataAddress = "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0/.well-known/openid-configuration"; } ); services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes( Auth0, MsaOpenId ) .Build(); var approvedPolicyBuilder = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes(Auth0, MsaOpenId) ; approvedPolicyBuilder.Requirements.Add(new HasApprovedRequirement(domain)); options.AddPolicy("approved", approvedPolicyBuilder.Build()); });
источник