(Правка - Найдено правильное исправление! См. Ниже)
ОК - это моя первая попытка .Net Core 2.0 и аутентификации, хотя в прошлом я работал с Web API 2.0 и довольно много работал над различными проектами MVC и Webforms ASP в течение последних нескольких лет.
Я пытаюсь создать проект ТОЛЬКО через Web API с использованием .Net Core. Это создаст серверную часть мультитенантного приложения для создания некоторых отчетов, поэтому мне нужно иметь возможность аутентифицировать пользователей. Кажется, что обычный подход заключается в использовании JWT - сначала аутентифицируйте пользователя для генерации токена, а затем передайте его клиенту для использования при каждом запросе API. Данные будут храниться и извлекаться с использованием EF Core.
Я проследовал за этим постом для базового способа настройки, и мне удалось заставить его работать нормально - у меня есть контроллер, который принимает имя пользователя/пароль и возвращает токен, если он действителен, и некоторые политики авторизации, настроенные на основе претензии.
Следующее, что мне нужно, это на самом деле управлять пользователями/паролями/и т.д. Я подумал, что для этого просто буду использовать .Net Core Identity, так как таким образом у меня будет много готового кода для беспокойства о пользователях/ролях, паролях и т.д. Я использовал User
классы User
и UserRole
которые получены из стандартного IdentityUser
и классы IdentityRole
, но с тех пор я вернулся к стандартным.
У меня проблема в том, что я не могу понять, как добавить личность и зарегистрировать все различные сервисы (ролевой менеджер, пользовательский менеджер и т.д.), Не нарушая при этом аутентификацию - в основном, как только я добавлю эту строку в мой класс Startup.ConfigureServices
:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<MyContext>();
Все идет не так, и я больше не вижу претензий при получении запроса, поэтому все политики просто блокируются, и вы ничего не можете получить.
Если у меня нет этих строк, я получаю ошибки, связанные с UserManager, RoleManager, UserStore и т.д., Которые не зарегистрированы для DI.
Итак... как (если это возможно) я могу зарегистрировать Идентичность и правильно подключить ее к Контексту, но избежать/удалить какие-либо изменения в действующем механизме авторизации?
Я довольно много смотрел в Интернете, но многое изменилось со времени .Net Core 1.x, поэтому многие учебные пособия и т.д. Больше не действуют.
Я не собираюсь использовать в этом API-интерфейсе какой-либо интерфейсный код, поэтому мне пока не нужна проверка подлинности с помощью cookie для форм или чего-либо еще.
редактировать
Хорошо, теперь я обнаружил, что в этом коде настройка аутентификации JWT в методе Startup.ConfigureServices()
:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
>>breakpoint>>> options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Blah.Blah.Bearer",
ValidAudience = "Blah.Blah.Bearer",
IssuerSigningKey =
JwtSecurityKey.Create("verylongsecretkey")
};
});
Если я поставлю точку останова в указанной строке (через ">> точку останова >>>"), то получит удар, когда я не добавлю строки для добавления служб идентификации, но если я добавлю эти строки, то она никогда не попадет. Это верно независимо от того, где в методе я помещаю вызов services.AddIdentity()
. Я понял, что это просто лямбда, поэтому он выполняется позже, но есть ли способ, как я могу заставить вещи AddIdentity НЕ устанавливать аутентификацию или заставить код немедленно удалить ее? Я предполагаю, что в какой-то момент есть некоторый код, который выбирает не запускать Lambda для конфигурации, которую я там установил, поскольку Identity уже установил его...
Спасибо, что прочитали все это, если у вас есть :)
РЕДАКТИРОВАТЬ - нашел ответ
Хорошо, в конце концов я нашел эту проблему GH, которая в основном именно эта проблема: https://github.com/aspnet/Identity/issues/1376
В основном то, что я должен был сделать, было двойным:
Убедитесь, что сначала был выполнен вызов services.AddIdentity<IdentityUser, IdentityContext()
Измените вызов, чтобы добавить аутентификацию из:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
...
Для того, чтобы:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
...
Это досадно приводит к созданию файла cookie, но, насколько я могу судить, он не используется для аутентификации - он просто использует токен-носитель для запросов к контроллерам/действиям, которые имеют [Authorize(Policy = "Administrator")]
или подобный набор по крайней мере.
Мне нужно больше тестировать, и я постараюсь вернуться сюда с обновлением, если я обнаружу, что это не работает каким-то образом.
(Отредактировано - поставить правильное решение в качестве ответа сейчас)