Сервер идентификации 4

Identity Server 4 (IS4) (https://identityserver4.readthedocs.io/en/latest/) - отличная библиотека, проста в использовании, а документация близка к совершенству.

Если вы новичок в OpenID Connect, JWT или защищенных API, я рекомендую просмотреть их примеры для быстрого старта. Еще я сам создал несколько стартап-проектов:

Цель

В примерах IS4 экран входа в систему построен с использованием рендеринга на стороне сервера (MVC), и практически нет документации о том, как заменить его на SPA (в angular / react или любой другой библиотеке JS).

Мы рассмотрим этапы замены пользовательского интерфейса, отображаемого на стороне сервера MVC, на чистый javascript, размещенный в другом домене.

Экран входа в систему

Хотя теоретически это не должно быть большой разницей, использование MVC дает нам большое преимущество использования C # при рендеринге страницы. Также проще подключиться к потокам OIDC (Open ID Connect), поскольку сервер может просто вернуть код HTTP 302 для перенаправления.

Самый простой способ перейти на полностью JS-интерфейс - взглянуть на образцы IS4 (https://github.com/karpikpl/identity-as-a-service) и выяснить, какая логика должна быть частью представления (JS ) и какая часть должна быть в API.

Но, к сожалению, это только часть.

Отказ от ответственности

Прежде чем мы начнем, я просто хочу указать, что в этом руководстве рассматривается простейший процесс без поддержки внешних учетных записей, согласия, регистрации устройства и т. Д.

Я знаю, что как только простой поток заработает, добавление этих дополнительных функций не так уж и сложно.

Я также называю свой пользовательский интерфейс одностраничным приложением, хотя это 3 статически размещенных html файла :) Но его легко заменить на приложение react или angular.

Настройка IS4

IS4 предлагает 3 настройки, которые управляют взаимодействием с пользователем (он же UI):

Также есть ConsentUrl и DeviceRegistrationUrl, но они используются не во всех сценариях (http://docs.identityserver.io/en/latest/reference/options.html?highlight = LoginUrl # взаимодействие пользователя ).

Имена говорят сами за себя, но документация относительно того, как они на самом деле используются, довольно минималистична.

  • LoginUrl будет использоваться всякий раз, когда IS4 решит, что требуется вход в систему (это происходит в AuthorizeInteractionResponseGenerator). IS4 добавит все необходимые параметры в строку запроса и перенаправит пользователя на LoginUrl.
  • ErrorUrl используется всякий раз, когда ошибка возникает во время потока, это не ошибка приложения, но в 99% случаев ошибки конфигурации между клиентом и Identity Server (неправильный тип предоставления, недопустимый секрет и др.). IS4 перенаправит пользователя на ErrorUrl и добавит errorId к URL-адресу. ErrorId можно заменить фактическим сообщением об ошибке с помощью службы взаимодействия.
  • LogoutUrl используется, когда пользователь выходит из клиентского приложения. Подобно ErrorUrl, IS4 добавляет logoutId к URL-адресу, который можно заменить на LogoutRequest, и процесс выхода из системы может быть завершен.

Позже я подробно расскажу, как создавать каждую страницу (Вход, Выход и Ошибка).

Если вы просто хотите увидеть рабочий образец, перейдите сюда:



Что мы строим

У нас будут работать бок о бок 4 сервиса:

  • Клиентское приложение под названием «spa», работающее на порту 8080, инициирует аутентификацию с IS4.
  • IS4 - API сервера идентификации 4 с зарегистрированным клиентским приложением «spa», работающим на порту 5000
  • Login-SPA - страница входа (UI для IS4) на чистом JS, работающая на порту 8082
  • API - (необязательно) защищенный ресурс, использующий IS4 для полномочий, работающий на порту 8083

Войти-SPA

Страница входа будет очень простой, всего два поля ввода и кнопка :)

Когда пользователь хочет войти в систему, мы должны вызвать настраиваемую конечную точку, добавленную в IS4 API.

Вызов API довольно прост, единственное, что нам нужно помнить, это передать ReturnUrl, который был указан в URL-адресе, на страницу входа. Мы также должны использовать параметр «С учетными данными», чтобы передать файлы cookie в другой домен, поскольку вызов будет происходить с localhost: 8082 и вызывать localhost: 5000.

IS4 - дополнительный API

Поскольку мы не используем образцы пользовательского интерфейса IS4, которые поставляются с дополнительными контроллерами, мы должны добавить собственный, мы назовем его AuthenticateController.

Метод входа в систему проверит имя пользователя и пароль, но также будет использовать returnUrl для создания контекста авторизации.

Для добавления нового контроллера требуется еще несколько вещей, например, добавление форматеров JSON:

services
.AddMvcCore()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonFormatters();

Здесь мы столкнемся с несколькими проблемами, первая из которых - CORS.

Нам нужно разрешить нашему пользовательскому интерфейсу вызывать API. Имейте в виду, что у Identity Server 4 настройки CORS отличаются от настроек ASP NET Core.

Как только эта проблема будет решена, мы столкнемся с другой - все, что мы отправляем Контекст авторизации, является нулевым. Расследование должно привести нас к OidcReturnUrlParser. Ему просто не нравится нелокальный URL, поскольку в версии MVC возвращаемый URL является локальным.

Чтобы решить эту проблему, мы должны написать наш собственный OidcReturnUrlParser, потому что этот класс является внутренним. Вот источники:



Не забудьте зарегистрировать переопределение в startup.cs:

services.AddTransient<IReturnUrlParser, ReturnUrlParser>();

Это должно нас подтолкнуть :)

Поддержка выхода

Для выхода из системы требуется специальная HTML-страница и контроллер.

Страница выхода из пользовательского интерфейса IS4 (интерфейс javascript) получит logoutId с сервера идентификации. Он должен использовать этот logoutId для вызова настраиваемой конечной точки и выполнения фактического выхода из системы.

Вот код:

Несколько замечаний:

  • нам нужно использовать параметр «с учетными данными» в запросе на передачу файлов cookie между доменами.
  • мы можем получить URL-адрес iframe в ответе, который мы должны использовать для добавления инфраструктуры на страницу выхода.
  • Если мы получаем URI перенаправления выхода, мы должны использовать его и направлять пользователя туда, куда запрашивает клиентское приложение.

Код для API:

Ключевым моментом здесь является то, что мы отправляем файл cookie в метод выхода из системы и на его основе получаем объект Пользователь, установленный ASP Core. Мы используем вспомогательный метод для SignOutAsync и удаляем файл cookie.

Страница ошибки

Страница ошибки довольно проста и похожа на страницу выхода из системы. Вы можете проверить это в образце репо.

Резюме

Вот и все. Мы добавили пользовательский интерфейс в другой домен, который работает с Identity Server 4. Прокомментируйте, если у вас есть какие-либо вопросы.

Спасибо за прочтение.