Я работаю над созданием некоторой новой функциональности там, где у нас есть существующая система. Наша цель - обеспечить взаимодействие Angular SPA с API-интерфейсами, чтобы представить новый интерфейс для нашего унаследованного приложения. Команда настроила IdentityServer4 для использования устаревшего приложения для проверки учетных данных.
SPA, написанный на Angular 7, использует неявный поток для аутентификации. Тип ответа "token id_token" Мне удалось заставить этот поток работать так, как я могу позволить неаутентифицированному пользователю зайти на сайт, получить доступ к экранам аутентификации IdentityServer, войти с правильным учетные данные, а затем перенаправлены обратно в приложение. Когда я получаю токен обратно, объект заявок имеет одно значение для aud
, client_id для SPA, например, spa-client . Access_token и id_token оба являются JWT с RS256 в качестве метода подписи. Наконец, я создал перехватчик в SPA для отправки JWT (в действительности он просто использует любое значение, отправленное обратно как access_token) в качестве токена «Bearer» в запросах API.
Теперь я создал приложение .NET Core 2.2 WebApi для построения API службы, который будет использоваться SPA. Это приложение использует пакет IdentityServer4.AccessTokenValidation для «защиты» API . Я прочитал раздел в документации IdentityServer4. В моем методе ConfigureServices
я написал следующее для настройки аутентификации:
services
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
if (string.IsNullOrWhiteSpace(serviceConfiguration.Authentication.Authority)) throw new ConfigurationException("", nameof(serviceConfiguration.Authentication.Authority), "An authority must be defined.");
if (string.IsNullOrWhiteSpace(serviceConfiguration.Authentication.ApiName)) throw new ConfigurationException("", nameof(serviceConfiguration.Authentication.ApiName), "An api name must be defined.");
options.Authority = serviceConfiguration.Authentication.Authority;
options.ApiName = serviceConfiguration.Authentication.ApiName;
if (!string.IsNullOrWhiteSpace(serviceConfiguration.Authentication.ApiSecret))
{
options.ApiSecret = serviceConfiguration.Authentication.ApiSecret;
}
options.RequireHttpsMetadata = false;
options.SupportedTokens = SupportedTokens.Both;
}
serviceConfiguration
- строго типизированное представление моего JSON appsettings.json
Насколько я понимаю, options.SupportedTokens = SupportedTokens.Both
проверит JWT и проведет самоанализ.
Теперь, когда все это настроено, я взял простой пример ValuesController
, который создается шаблоном API, и добавил к нему атрибут [Authorize]
. Выполнение простого запроса GET к этой конечной точке в Postman возвращает 401, как я и ожидал.
Затем я пытаюсь войти в SPA и перейти на тестовую страницу, которая будет делать то же самое, но с перехватчиком будет иметь токен-носитель, access_token или, в основном, JWT. Я все еще получаю 401 от службы.
Глядя на журналы, которые выдает служба, я не вижу ничего полезного:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost [1]
Запросить начало HTTP / 1.1 ОПЦИИ http://localhost:5001/api/values info:
Microsoft.AspNetCore.Hosting.Internal.WebHost [1]
Запросить начало HTTP / 1.1 ОПЦИИ http://localhost:5001/api/values info:
Microsoft.AspNetCore.Cors.Infrastructure.CorsService [4]
Выполнение политики CORS успешно. информация: Microsoft.AspNetCore.Cors.Infrastructure.CorsService [4]
Выполнение политики CORS успешно. информация: Microsoft.AspNetCore.Hosting.Internal.WebHost [2]
Запрос завершен в 61.1352ms 204 info: Microsoft.AspNetCore.Hosting.Internal.WebHost [2]
Запрос завершен в 61.1272ms 204 info: Microsoft.AspNetCore.Hosting.Internal.WebHost [1]
Запросить запуск HTTP / 1.1 GET http://localhost:5001/api/values application / json info:
Microsoft.AspNetCore.Hosting.Internal.WebHost [1]
Запросить запуск HTTP / 1.1 GET http://localhost:5001/api/values application / json info:
Microsoft.AspNetCore.Cors.Infrastructure.CorsService [4]
Выполнение политики CORS успешно. информация: Microsoft.AspNetCore.Cors.Infrastructure.CorsService [4]
Выполнение политики CORS успешно. информация: Microsoft.AspNetCore.Routing.EndpointMiddleware [0]
Выполнение конечной точки examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) 'info:
Microsoft.AspNetCore.Routing.EndpointMiddleware [0]
Выполнение конечной точки
(Examples.TestApp.API.Web) 'info:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [1]
Маршрут соответствует {action = "Get", controller = "Values"}. Выполнение действия
Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) info:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [1]Маршрут соответствует {action = "Get", controller = "Values"}. Выполнение действия
Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) info:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2]
Авторизация не удалась. информация: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2]
Авторизация не удалась. информация: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [3]
Авторизация не выполнена для запроса в фильтре «Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter». Информация:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [3]
Авторизация не выполнена для запроса в фильтре «Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter». Информация:
Microsoft.AspNetCore.Mvc.ChallengeResult [1]
Выполнение ChallengeResult со схемами аутентификации (). информация: Microsoft.AspNetCore.Mvc.ChallengeResult [1]
Выполнение ChallengeResult со схемами аутентификации (). информация: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler [12]
Схема аутентификации: на предъявителя был поставлен вызов. информация: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler [12]
Схема аутентификации: на предъявителя был поставлен вызов. информация: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [2]
Выполненное действие examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) в 166.3038ms информация:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [2]
Выполненное действие examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) в 162.8827ms информация:
Microsoft.AspNetCore.Routing.EndpointMiddleware [1]
Выполненная конечная точка 'examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) 'info:
Microsoft.AspNetCore.Routing.EndpointMiddleware [1]
Выполненная конечная точка 'examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) 'info:
Microsoft.AspNetCore.Hosting.Internal.WebHost [2]
Запрос завершен в 459.6677 мс. 401 info: Microsoft.AspNetCore.Hosting.Internal.WebHost [2]
Запрос завершен в 473,7648мс 401
Установка логирования на Трассировка больше ничего не показала.
Я попытался пойти к Почтальону, чтобы посмотреть, смогу ли я сделать самоанализ на токене вручную. Я установил базовую авторизацию и установил имя пользователя «test-api», идентификатор api и пароль, которые я установил в секретном ключе клиента. В теле указан набор x-www-form-urlencoded с ключом «token» и значением access_token. Я получаю 200 OK с претензиями вместе с "active: true". Похоже, это должно быть хорошо, верно?
Мне не принадлежит реализация IdentityServer, поэтому я не совсем уверен, что происходит на этом этапе, за исключением возможности входа в интерфейс администратора. Я вошел в интерфейс администратора для сервера идентификации и дважды проверил настройки для клиента и API. Клиенту предоставляется область действия «API», а API получает такую же область «API». Это показано в области, которая отправляется обратно в ответе на самоанализ, а также в токене, который я получаю от клиента.
Я также пытался установить options.SupportedTokens = SupportedTokens.Reference
и options.SupportedTokens = SupportedTokens.JWT
. Ни один не имел никаких изменений. (
Что я делаю не так? Это проблема конфигурации или я идиот (возможно, последний).
РЕДАКТИРОВАТЬ : RE access_token и id_token
Я ошибся в исходном вопросе. Токены разные (мне нужно взглянуть не только на часть заголовка).
Аудитория странная. Я никогда не обращал внимания на возможную разницу здесь при декодировании. Мои способности восприятия должны сосать!
Токен доступа имеет aud: "http: /// resources"
У id_token есть aud: "spa-client"