Проверка подлинности Dotnet core 2.0 несколькими куки файлами идентичности схем и jwt
В dotnet core 1.1 asp я смог настроить и использовать промежуточное программное обеспечение идентификации, а затем промежуточное программное обеспечение jwt, выполнив следующие действия:
app.UseIdentity();
app.UseJwtBearerAuthentication(new JwtBearerOptions() {});
Теперь это изменилось в том, что мы реализуем промежуточное программное обеспечение с помощью
app.UseAuthentication();
Конфигурация настроек выполняется через раздел ConfigureServices Startup.cs.
В документации по миграции есть ссылки на использование схемы авторизации:
https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x#authentication-middleware-and-services
В 2.0 проектах аутентификация настраивается через службы. каждый схема аутентификации зарегистрирована в методе ConfigureServices Startup.cs. Метод UseIdentity заменяется на UseAuthentication.
Кроме того, имеется ссылка на:
Настройка схем аутентификации по умолчанию
В 1.x свойства AutomaticAuthenticate и AutomaticChallenge должны были быть установлены на единой схеме аутентификации. Там было нет хорошего способа обеспечить это.
В 2.0 эти два свойства были удалены как флаги на отдельном экземпляре AuthenticationOptions и перешли в базовый класс AuthenticationOptions. Свойства могут быть сконфигурированы в вызове метода AddAuthentication в пределах Метод ConfigureServices для Startup.cs:
В качестве альтернативы используйте перегруженную версию AddAuthentication метод для установки более одного свойства. В следующей перегруженной метод, схема по умолчанию установлена на CookieAuthenticationDefaults.AuthenticationScheme. Аутентификация схема может альтернативно быть указана в пределах вашей индивидуальной [Авторизовать] атрибуты или политики авторизации.
Возможно ли, что в dotnet core 2.0 можно использовать несколько схем аутентификации? Я не могу заставить политику уважать конфигурацию JWT (схема "Bearer" ), и только Identity работает в настоящее время с настройками. Я не могу найти образцы нескольких схем проверки подлинности.
Edit:
Я перечитал документацию и теперь понимаю, что:
app.UseAuthentication()
добавляет автоматическую аутентификацию по схеме по умолчанию. Identity настраивает схемы по умолчанию для вас.
У меня возникла проблема с тем, что похоже на взлом, работающий против нового api, выполнив следующее в Startup.cs Configure:
app.UseAuthentication();
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
var result = await context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
if (result?.Principal != null)
{
context.User = result.Principal;
}
}
await next.Invoke();
});
Это правильный способ сделать это, или я должен использовать инфраструктуру, DI и интерфейсы для пользовательских реализаций IAuthenticationSchemeProvider?
Изменить - дальнейшие подробности реализации и где ее найти.
JWT Config можно найти здесь, и я использую политики для определения авторизации, включая принятую схему аутентификации:
https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Management/Startup.cs
Пользовательское промежуточное ПО все еще реализовано. Контроллер Auth находится здесь:
https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/AuthController.cs
Он использует API-ключи, созданные приложением, для доступа к данным только для чтения. Вы можете найти реализацию контроллера, использующего политику здесь:
https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/SitemapController.cs
Измените строку подключения DB, чтобы указать на ваш SQL Server, и запустите приложение. Он автоматически переносит БД и настраивает пользователя admin ([email protected] - ArragroPassword1!). Затем перейдите на вкладку "Настройки" в строке меню и нажмите "Настроить параметры ключа API JWT ReadOnly", чтобы получить ключ. В почтальоне получите токен jwt, настроив новую вкладку и установив ее в POST со следующим адресом:
http://localhost:5000/api/auth/readonly-token
Поставка заголовков: Content-Type: application/json
Поставка тела:
{
"apiKey": "the api token from the previous step"
}
Скопируйте токен в ответе, а затем используйте postman:
http://localhost:5000/api/sitemap/flat
Authorization: "bearer - The token you received in the previous request"
Он будет работать вначале из-за пользовательского промежуточного программного обеспечения. Прокомментируйте приведенный выше код и повторите попытку, и вы получите 401.
Изменить - @DonnyTian ответ ниже охватывает мое решение в его комментариях. Проблема, с которой я столкнулась, заключалась в установке политики по умолчанию на UseMvc, но не в предоставлении схемы:
services.AddMvc(config =>
{
var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(defaultPolicy));
config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
config.Filters.Add(new ValidateModelAttribute());
});
Следуя советам, это работает без специального промежуточного программного обеспечения.
Ответы
Ответ 1
Asp.Net Core 2.0 определенно поддерживает несколько схем аутентификации.
Вместо того, чтобы взломать промежуточное программное обеспечение для проверки подлинности, вы можете попытаться указать схему в атрибуте Authorize
:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Я попытался, и все получилось отлично. Предполагая, что вы добавили как Identity, так и JWT, как показано ниже:
services.AddIdentity<ApplicationUser, ApplicationRole>()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Поскольку AddIdentity()
уже устанавливает аутентификацию cookie как схему по умолчанию, мы должны указать схему в атрибуте Authorize
для контроллеров. На данный момент я понятия не имею, как перезаписать стандартную схему, установленную AddIdentity()
, или, может быть, лучше не делать этого.
Работаем над созданием нового класса (вы можете называть его JwtAuthorize), который происходит от Authorize
и имеет Bearer как схему по умолчанию, поэтому вам не нужно указывать его каждый время.
UPDATE
Найден способ переопределить схему аутентификации по умолчанию Identity!
Вместо строки ниже:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
Используйте следующую перегрузку для установки схемы по умолчанию:
services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>....
Ответ 2
Я использовал этот вопрос для решения моей (аналогичной) проблемы объединения аутентификации Identity и Bearer в веб-приложении .NET Core 2.0. Важно отметить, что вам нужно добавить new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme
в следующий фрагмент кода:
services.AddMvc(config =>
{
var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(defaultPolicy));
config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
config.Filters.Add(new ValidateModelAttribute());
});
И
Добавьте параметр проверки подлинности по умолчанию:
services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>....
В моем первоначальном решении, основанном на этом вопросе, я не заметил, что оба изменения в моем коде были необходимы. Надеюсь, я смогу спасти кого-нибудь в те часы, которые я потратил впустую:)
Ответ 3
У Sean Wildermuth есть сообщение в блоге о включении cookie и jwt: https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2
Он цепляет его так:
services.AddAuthentication()
.AddCookie(cfg => cfg.SlidingExpiration = true)
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
};
});
Ответ 4
Основываясь на том, что говорит kevin rich http://www.whoiskevinrich.com/configuring-asp-net-core-2-0-authentication
Мне удалось установить jwt как метод аутентификации по умолчанию:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
})
Я протестировал это и смог удалить (AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme) из атрибута authorize, упомянутого в сообщении donnytian.