Статьи

Простой способ создать аутентификацию с помощью Spring Security 5.0 и OIDC

«Я люблю писать код аутентификации и авторизации». Нет Java-разработчика. Надоело строить одни и те же экраны входа снова и снова? Попробуйте API Okta для размещенной аутентификации, авторизации и многофакторной аутентификации.

Spring Security — это не просто мощная и гибко настраиваемая среда аутентификации и контроля доступа, это также де-факто стандарт для защиты приложений на основе Spring. Когда-то давно Spring Security требовала множество XML для настройки всего, но те времена давно прошли. В наши дни Spring Security предлагает гораздо более простую настройку через JavaConfig от Spring. Если вы посмотрите на класс `SecurityConfiguration.java` из примера JHipster OIDC, о котором я недавно писал, вы увидите, что он содержит менее 100 строк кода!

Spring Security 5.0 разрешает более 400 заявок и обладает множеством новых функций :

Сегодня я покажу вам, как использовать поддержку OAuth 2.0 Login с Okta. Я также покажу вам, как получить информацию о пользователе через OpenID Connect (OIDC).

Вы знаете, что Okta предлагает бесплатные учетные записи разработчиков до 7000 активных ежемесячных пользователей, верно? Этого должно быть достаточно, чтобы убрать ваше приложение-убийцу.

Spring Security делает аутентификацию с OAuth 2.0 чертовски простой. Он также предоставляет возможность извлекать информацию пользователя через OIDC. Следуйте инструкциям ниже, чтобы узнать больше!

Что такое OIDC? Если вы не знакомы с OAuth или OIDC, я рекомендую вам прочитать, что такое OAuth . Поток Open ID Connect включает в себя следующие шаги:

  1. Откройте для себя метаданные OIDC
  2. Выполните поток OAuth для получения токена ID и доступа к токенам
  3. Получить ключи подписи JWT и при необходимости динамически зарегистрировать клиентское приложение
  4. Проверьте токен JWT ID локально на основе встроенных дат и подписи
  5. Получить дополнительные пользовательские атрибуты при необходимости с токеном доступа

Создать приложение Spring Boot

Откройте start.spring.io в вашем браузере. Spring Initialzr — это сайт, который позволяет быстро и легко создавать новые приложения Spring Boot. Установите версию Spring Boot (в верхнем правом углу) на 2.0.0.M7 . Введите имя группы и артефакта. Как вы можете видеть на скриншоте ниже, я выбрал com.okta.developer и oidc . Для зависимостей выберите Веб , Реактивная сеть , Безопасность и Thymeleaf .

Нажмите « Создать проект» , загрузите zip, разверните его на жестком диске и откройте проект в своей любимой среде IDE. Запустите приложение с помощью ./mvnw spring-boot:run , и вам будет предложено войти в систему.

Spring Security 4.x предлагает вам обычную аутентификацию, а не форму входа, так что в Spring Security 5 все по-другому.

Средство запуска Spring Security создает пользователя по умолчанию с именем пользователя «user» и паролем, который изменяется при каждом запуске приложения. Вы можете найти этот пароль в своем терминале, как показано ниже.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Using default security password: 103c55b4-2760-4830-9bca-a06a87d384f9</span> Используя пароль безопасности по умолчанию: 103c55b4-2760-4830-9bca-a06a87d384f9</span>

В форме введите «пользователь» для пользователя и сгенерированный пароль для пароля. Следующим экраном будет 404, поскольку в вашем приложении не задан маршрут по умолчанию для / path.

В Spring Boot 1.x вы можете изменить пароль пользователя, так что каждый раз он один и тот же, добавив следующее в src/main/resources/application.properties .

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">security.user.password=spring security is ph@!</span> security.user.password = весенняя безопасность ph @!</span>

Тем не менее, это устаревшая функция в Spring Boot 2.0. Хорошей новостью является то, что это изменение, скорее всего, будет отменено до выпуска GA .

Тем временем вы можете скопировать пароль, который напечатан на вашу консоль, и использовать его с HTTPie .

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">$ http --auth user:'bf91316f-f894-453a-9268-4826cdd7e151' localhost:8080</span> $ http --auth пользователь: 'bf91316f-f894-453a-9268-4826cdd7e151' localhost: 8080</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">HTTP/1.1 404</span> HTTP / 1.1 404</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Cache-Control: no-cache, no-store, max-age=0, must-revalidate</span> Cache-Control: no-cache, no-store, max-age = 0, обязательно повторная проверка</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Content-Type: application/json;charset=UTF-8</span> Тип контента: application / json; charset = UTF-8</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Date: Sun, 03 Dec 2017 19:11:50 GMT</span> Дата: вс, 03 дек. 2017 19:11:50 GMT</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Expires: 0</span> Истекает: 0</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Pragma: no-cache</span> Прагма: без кеша</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Set-Cookie: JSESSIONID=65283FCBDB9E6EF1C0679290AA994B0D;</span> Набор-cookie: JSESSIONID = 65283FCBDB9E6EF1C0679290AA994B0D;</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Path=/;</span> Path = /;</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">HttpOnly</span> HttpOnly</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Transfer-Encoding: chunked</span> Передача-Кодировка: чанки</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">X-Content-Type-Options: nosniff</span> X-Content-Type-Options: nosniff</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">X-Frame-Options: DENY</span> X-Frame-Options: DENY</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">X-XSS-Protection: 1;</span> X-XSS-защита: 1;</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">mode=block</span> Режим = Блок</span>

Ответ будет 404, а также.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">{</span> {</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">"error": "Not Found",</span> "ошибка не найдена",</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">"message": "No message available",</span> "message": "Нет доступных сообщений",</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">"path": "/",</span> "путь": "/",</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">"status": 404,</span> «статус»: 404,</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">"timestamp": "2017-12-03T19:11:50.846+0000"</span> «метка времени»: «2017-12-03T19: 11: 50.846 + 0000»</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>

Вы можете избавиться от 404, создав MainController.java в том же каталоге, что и OidcApplication.java ( src/main/java/com/okta/developer/oidc ). Создайте метод home() который сопоставляется с / и возвращает имя пользователя.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">package com.okta.developer.oidc;</span> пакет com.okta.developer.oidc;</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.web.bind.annotation.GetMapping;</span> import org.springframework.web.bind.annotation.GetMapping;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.web.bind.annotation.RestController;</span> import org.springframework.web.bind.annotation.RestController;</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import java.security.Principal;</span> import java.security.Principal;</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">@RestController</span> @RestController</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public class MainController {</span> открытый класс MainController {</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">@GetMapping("/")</span> @GetMapping ( "/")</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">String home(Principal user) {</span> String home (Основной пользователь) {</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">return "Hello " + user.getName();</span> return "Hello" + user.getName ();</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>

Перезагрузите сервер, войдите в систему с user и сгенерированным паролем, и вы должны увидеть Hello user .

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">$ http --auth user:'d7c4138d-a1cc-4cc9-8975-97f37567594a' localhost:8080</span> $ http --auth пользователь: 'd7c4138d-a1cc-4cc9-8975-97f37567594a' localhost: 8080</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">HTTP/1.1 200</span> HTTP / 1.1 200</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Cache-Control: no-cache, no-store, max-age=0, must-revalidate</span> Cache-Control: no-cache, no-store, max-age = 0, обязательно повторная проверка</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Content-Length: 10</span> Длина контента: 10</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Content-Type: text/plain;charset=UTF-8</span> Тип контента: текстовый / обычный; кодировка = UTF-8</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Date: Sun, 03 Dec 2017 19:26:54 GMT</span> Дата: вс, 03 дек. 2017 19:26:54 GMT</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Expires: 0</span> Истекает: 0</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Pragma: no-cache</span> Прагма: без кеша</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Set-Cookie: JSESSIONID=22A5A91051B7AFBA1DC8BD30C0B53365;</span> Cookie-набор: JSESSIONID = 22A5A91051B7AFBA1DC8BD30C0B53365;</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Path=/;</span> Path = /;</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">HttpOnly</span> HttpOnly</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">X-Content-Type-Options: nosniff</span> X-Content-Type-Options: nosniff</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">X-Frame-Options: DENY</span> X-Frame-Options: DENY</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">X-XSS-Protection: 1;</span> X-XSS-защита: 1;</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">mode=block</span> Режим = Блок</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Hello user</span> Привет пользователь</span>

Добавить аутентификацию с Okta

В предыдущем уроке я показал вам, как использовать Spring Security OAuth для обеспечения единого входа для ваших приложений. В Spring Security 5 вы можете сделать то же самое, но вы также можете указать несколько провайдеров, чего раньше не могли делать. Spring Security 5 содержит пример входа в систему OAuth 2.0 и документацию о том, как все работает.

Создать приложение OpenID Connect

Для интеграции с Okta вам необходимо зарегистрировать аккаунт на сайте developer.okta.com . После подтверждения адреса электронной почты и входа в систему перейдите в Приложения > Добавить приложение . Нажмите Web, а затем нажмите Next . Дайте приложению имя, которое вы запомните, укажите http://localhost:8080 в качестве базового URI, а также http://localhost:8080/login/oauth2/code/okta для URI перенаправления входа в систему.

Переименуйте src/main/resources/application.properties в src/main/resources/application.yml и заполните его следующим текстом.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">spring:</span> весна:</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">thymeleaf:</span> thymeleaf:</span>
  <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">cache: false</span> кеш: ложь</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">security:</span> безопасность:</span>
  <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">oauth2:</span> oauth2:</span>
    <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">client:</span> клиент:</span>
      <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">registration:</span> Регистрация:</span>
        <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">okta:</span> окт:</span>
          <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">client-id: {clientId}</span> идентификатор клиента: {идентификатор клиента}</span>
          <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">client-secret: {clientSecret}</span> client-secret: {clientSecret}</span>
      <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">provider:</span> поставщик:</span>
        <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">okta:</span> окт:</span>
          <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">authorization-uri: https://{yourOktaDomain}.com/oauth2/default/v1/authorize</span> URI авторизации: https: // {yourOktaDomain} .com / oauth2 / default / v1 / authorize</span>
          <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">token-uri: https://{yourOktaDomain}.com/oauth2/default/v1/token</span> token-uri: https: // {yourOktaDomain} .com / oauth2 / default / v1 / token</span>
          <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">user-info-uri: https://{yourOktaDomain}.com/oauth2/default/v1/userinfo</span> user-info-uri: https: // {yourOktaDomain} .com / oauth2 / default / v1 / userinfo</span>
          <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">jwk-set-uri: https://{yourOktaDomain}.com/oauth2/default/v1/keys</span> jwk-set-uri: https: // {yourOktaDomain} .com / oauth2 / default / v1 / keys</span>

Скопируйте идентификатор клиента и секрет из вашего приложения OIDC в ​​файл application.yml . Для {yourOktaDomain} используйте значение вашего домена (например, dev-158606.oktapreview.com ). Убедитесь, что он не включает в себя -admin .

Вам потребуется добавить некоторые зависимости в ваш pom.xml для правильной инициализации конфигурации OAuth в Spring Security 5.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><dependency></span> <Зависимость></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><groupId>org.springframework.security</groupId></span> <Идентификатор_группы> org.springframework.security </ идентификатор_группы></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><artifactId>spring-security-config</artifactId></span> <Артефакт> весна-безопасность конфигурация </ артефакт></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></dependency></span> </ Зависимость></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><dependency></span> <Зависимость></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><groupId>org.springframework.security</groupId></span> <Идентификатор_группы> org.springframework.security </ идентификатор_группы></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><artifactId>spring-security-oauth2-client</artifactId></span> <Артефакт> весна-безопасность oauth2-клиент </ артефакт></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></dependency></span> </ Зависимость></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><dependency></span> <Зависимость></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><groupId>org.springframework.security</groupId></span> <Идентификатор_группы> org.springframework.security </ идентификатор_группы></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><artifactId>spring-security-oauth2-jose</artifactId></span> <Артефакт> весна-безопасность oauth2-хосе </ артефакт></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></dependency></span> </ Зависимость></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><dependency></span> <Зависимость></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><groupId>org.thymeleaf.extras</groupId></span> <Идентификатор_группы> org.thymeleaf.extras </ идентификатор_группы></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><artifactId>thymeleaf-extras-springsecurity4</artifactId></span> <Артефакт> thymeleaf-дополнения-springsecurity4 </ артефакт></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></dependency></span> </ Зависимость></span>

Перезапустите приложение и снова перейдите по http://localhost:8080 . Вы увидите ссылку для входа в Okta.

ПРИМЕЧАНИЕ. Если вы хотите узнать, как настроить экран входа в систему, отображаемый Spring Security, см. Документацию к странице входа в OAuth 2.0 .

После нажатия на ссылку, вы должны увидеть экран входа в систему.

Введите учетные данные, которые вы использовали для создания учетной записи, после входа в систему вы должны увидеть экран, подобный следующему.

ПРИМЕЧАНИЕ. Можно изменить что-то, так что Principal#getName() возвращает другое значение. Однако в Spring Boot 2.0.0.M7 есть ошибка, которая препятствует работе свойства конфигурации.

Получите информацию о пользователе с помощью OIDC

Измените свой MainController.java чтобы иметь код ниже. Этот код добавляет отображение /userinfo которое использует WebClient Spring WebFlux для получения информации о пользователе от конечной точки информации о пользователе. Я скопировал приведенный ниже код из примера входа в OAuth 2.0 в Spring Security 5.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/*</span> / *</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* Copyright 2002-2017 the original author or authors.</span> * Copyright 2002-2017 оригинального автора или авторов.</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* Licensed under the Apache License, Version 2.0 (the "License");</span> * Лицензировано по лицензии Apache, версия 2.0 («Лицензия»);</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* you may not use this file except in compliance with the License.</span> * Вы не можете использовать этот файл, кроме как в соответствии с Лицензией.</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* You may obtain a copy of the License at</span> * Вы можете получить копию лицензии на</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* http://www.apache.org/licenses/LICENSE-2.0</span> * http://www.apache.org/licenses/LICENSE-2.0</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* Unless required by applicable law or agreed to in writing, software</span> * Если это не требуется действующим законодательством или не согласовано в письменной форме, программное обеспечение</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* distributed under the License is distributed on an "AS IS" BASIS,</span> * распространяется по лицензии распространяется на основе "как есть",</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span> * БЕЗ ГАРАНТИЙ ИЛИ УСЛОВИЙ ЛЮБОГО ВИДА, явных или подразумеваемых.</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* See the License for the specific language governing permissions and</span> * См. Лицензию для конкретного языка, регулирующего разрешения и</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* limitations under the License.</span> * ограничения по лицензии.</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">package com.okta.developer.oidc;</span> пакет com.okta.developer.oidc;</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.beans.factory.annotation.Autowired;</span> import org.springframework.beans.factory.annotation.Autowired;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.http.HttpHeaders;</span> import org.springframework.http.HttpHeaders;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;</span> import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;</span> import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;</span> import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.stereotype.Controller;</span> import org.springframework.stereotype.Controller;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.ui.Model;</span> import org.springframework.ui.Model;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.util.StringUtils;</span> import org.springframework.util.StringUtils;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.web.bind.annotation.RequestMapping;</span> import org.springframework.web.bind.annotation.RequestMapping;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.web.reactive.function.client.ClientRequest;</span> import org.springframework.web.reactive.function.client.ClientRequest;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.web.reactive.function.client.ExchangeFilterFunction;</span> import org.springframework.web.reactive.function.client.ExchangeFilterFunction;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import org.springframework.web.reactive.function.client.WebClient;</span> import org.springframework.web.reactive.function.client.WebClient;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import reactor.core.publisher.Mono;</span> импортный реактор.кор.публикатор.Моно;</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import java.util.Collections;</span> import java.util.Collections;</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">import java.util.Map;</span> импорт java.util.Map;</span>
 
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/**</span> / **</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @author Joe Grandja</span> * @author Джо Гранджа</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">@Controller</span> @Controller</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public class MainController {</span> открытый класс MainController {</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">private final OAuth2AuthorizedClientService authorizedClientService;</span> закрытый финал OAuth2AuthorizedClientService authorizedClientService;</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public MainController(OAuth2AuthorizedClientService authorizedClientService) {</span> public MainController (OAuth2AuthorizedClientService authorizedClientService) {</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.authorizedClientService = authorizedClientService;</span> this.authorizedClientService = authorizedClientService;</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">@RequestMapping("/")</span> @RequestMapping ( "/")</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public String index(Model model, OAuth2AuthenticationToken authentication) {</span> public String index (Модель модели, аутентификация OAuth2AuthenticationToken) {</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">OAuth2AuthorizedClient authorizedClient = this.getAuthorizedClient(authentication);</span> OAuth2AuthorizedClient authorizedClient = this.getAuthorizedClient (аутентификация);</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">model.addAttribute("userName", authentication.getName());</span> model.addAttribute ("userName", authentication.getName ());</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">model.addAttribute("clientName", authorizedClient.getClientRegistration().getClientName());</span> model.addAttribute ("clientName", authorizedClient.getClientRegistration (). getClientName ());</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">return "index";</span> вернуть «индекс»;</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">@RequestMapping("/userinfo")</span> @RequestMapping ( "/") UserInfo</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public String userinfo(Model model, OAuth2AuthenticationToken authentication) {</span> public String userinfo (модель Model, аутентификация OAuth2AuthenticationToken) {</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">OAuth2AuthorizedClient authorizedClient = this.getAuthorizedClient(authentication);</span> OAuth2AuthorizedClient authorizedClient = this.getAuthorizedClient (аутентификация);</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Map userAttributes = Collections.emptyMap();</span> Карта userAttributes = Collections.emptyMap ();</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">String userInfoEndpointUri = authorizedClient.getClientRegistration()</span> Строка userInfoEndpointUri = authorizedClient.getClientRegistration ()</span>
               <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.getProviderDetails().getUserInfoEndpoint().getUri();</span> . .GetProviderDetails () getUserInfoEndpoint () getUri ().</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">if (!StringUtils.isEmpty(userInfoEndpointUri)) { // userInfoEndpointUri is optional for OIDC Clients</span> if (! StringUtils.isEmpty (userInfoEndpointUri)) {// userInfoEndpointUri является необязательным для клиентов OIDC</span>
           <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">userAttributes = WebClient.builder()</span> userAttributes = WebClient.builder ()</span>
                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.filter(oauth2Credentials(authorizedClient)).build()</span> .filter (oauth2Credentials (authorizedClient)). (сборка)</span>
                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.get().uri(userInfoEndpointUri)</span> .get (). URI (userInfoEndpointUri)</span>
                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.retrieve()</span> .retrieve ()</span>
                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.bodyToMono(Map.class).block();</span> .bodyToMono (Map.class) .block ();</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">model.addAttribute("userAttributes", userAttributes);</span> model.addAttribute ("userAttributes", userAttributes);</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">return "userinfo";</span> возврат "userinfo";</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">private OAuth2AuthorizedClient getAuthorizedClient(OAuth2AuthenticationToken authentication) {</span> private OAuth2AuthorizedClient getAuthorizedClient (аутентификация OAuth2AuthenticationToken) {</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">return this.authorizedClientService.loadAuthorizedClient(</span> вернуть this.authorizedClientService.loadAuthorizedClient (</span>
               <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">authentication.getAuthorizedClientRegistrationId(), authentication.getName());</span> authentication.getAuthorizedClientRegistrationId (), authentication.getName ());</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
 
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">private ExchangeFilterFunction oauth2Credentials(OAuth2AuthorizedClient authorizedClient) {</span> private ExchangeFilterFunction oauth2Credentials (OAuth2AuthorizedClient authorizedClient) {</span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">return ExchangeFilterFunction.ofRequestProcessor(</span> return ExchangeFilterFunction.ofRequestProcessor (</span>
               <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">clientRequest -> {</span> clientRequest -> {</span>
                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">ClientRequest authorizedRequest = ClientRequest.from(clientRequest)</span> ClientRequest authorizedRequest = ClientRequest.from (clientRequest)</span>
                           <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.header(HttpHeaders.AUTHORIZATION,</span> .header (HttpHeaders.AUTHORIZATION,</span>
                                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">"Bearer " + authorizedClient.getAccessToken().getTokenValue())</span> «Носитель» + authorizedClient.getAccessToken (). GetTokenValue ())</span>
                           <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">.build();</span> .build ();</span>
                   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">return Mono.just(authorizedRequest);</span> вернуть Mono.just (авторизованный запрос);</span>
               <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">});</span> });</span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>

Создайте страницу индекса Thymeleaf по адресу src/main/resources/templates/index.html . Вы можете использовать поддержку Thymeleaf для Spring Security, чтобы показать / скрыть различные части страницы в зависимости от статуса пользователя, прошедшего проверку подлинности.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><!DOCTYPE html></span> <! DOCTYPE html></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"</span> <html xmlns = "http://www.w3.org/1999/xhtml" xmlns: th = "http://www.thymeleaf.org"</span>
     <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"></span> XMLNS: сек = "http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><head></span> <Голова></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><title>Spring Security - OAuth 2.0 Login</title></span> <title> Spring Security - вход в OAuth 2.0 </ title></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><meta charset="utf-8" /></span> <meta charset = "utf-8" /></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></head></span> </ HEAD></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><body></span> <Тело></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div style="float: right" th:fragment="logout" sec:authorize="isAuthenticated()"></span> <div style = "float: right" th: фрагмент = "выход из системы" sec: authorize = "isAuthenticated ()"></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div style="float:left"></span> <div style = "float: left"></span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><span style="font-weight:bold">User: </span><span sec:authentication="name"></span></span> <span style = "font-weight: bold"> Пользователь: </ span> <span sec: authentication = "name"> </ span></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></div></span> </ DIV></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div style="float:none"> </div></span> <div style = "float: none"> </ div></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div style="float:right"></span> <div style = "float: right"></span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><form action="#" th:action="@{/logout}" method="post"></span> <form action = "#" th: action = "@ {/ logout}" method = "post"></span>
           <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><input type="submit" value="Logout" /></span> <input type = "submit" value = "Выйти" /></span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></form></span> </ Форма></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></div></span> </ DIV></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></div></span> </ DIV></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><h1>OAuth 2.0 Login with Spring Security</h1></span> <h1> Вход в OAuth 2.0 с помощью Spring Security </ h1></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div></span> <DIV></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">You are successfully logged in <span style="font-weight:bold" th:text="${userName}"></span></span> Вы успешно вошли в <span style = "font-weight: bold" th: text = "$ {userName}"> </ span></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">via the OAuth 2.0 Client <span style="font-weight:bold" th:text="${clientName}"></span></span> через клиент OAuth 2.0 <span style = "font-weight: bold" th: text = "$ {clientName}"> </ span></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></div></span> </ DIV></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div> </div></span> <div> </ div></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div></span> <DIV></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><a href="/userinfo" th:href="@{/userinfo}">Display User Info</a></span> <a href="/userinfo" th:href="@ enj/userinfo ultimate"> Отображение информации о пользователе </a></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></div></span> </ DIV></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></body></span> </ Body></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></html></span> </ Html></span>

Создайте другой шаблон в src/main/resources/userinfo.html для отображения атрибутов пользователя.

<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><!DOCTYPE html></span> <! DOCTYPE html></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"></span> <html xmlns = "http://www.w3.org/1999/xhtml" xmlns: th = "http://www.thymeleaf.org"></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><head></span> <Голова></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><title>Spring Security - OAuth 2.0 User Info</title></span> <title> Spring Security - информация о пользователе OAuth 2.0 </ title></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><meta charset="utf-8" /></span> <meta charset = "utf-8" /></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></head></span> </ HEAD></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><body></span> <Тело></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div th:replace="index::logout"></div></span> <div th: replace = "index :: logout"> </ div></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><h1>OAuth 2.0 User Info</h1></span> <h1> Информация о пользователе OAuth 2.0 </ h1></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><div></span> <DIV></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><span style="font-weight:bold">User Attributes:</span></span> <span style = "font-weight: bold"> Атрибуты пользователя: </ span></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><ul></span> <UL></span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><li th:each="userAttribute : ${userAttributes}"></span> <li th: each = "userAttribute: $ {userAttributes}"></span>
           <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><span style="font-weight:bold" th:text="${userAttribute.key}"></span>: <span th:text="${userAttribute.value}"></span></span> <span style = "font-weight: bold" th: text = "$ {userAttribute.key}"> </ span>: <span th: text = "$ {userAttribute.value}"> </ span></span>
       <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></li></span> </ Li></span>
   <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></ul></span> </ UL></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></div></span> </ DIV></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></body></span> </ Body></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></html></span> </ Html></span>

Теперь, когда вы вошли в систему, вы увидите ссылку для отображения информации о пользователе.

Нажмите на ссылку, и вы увидите содержимое идентификатора токена, полученного из конечной точки информации пользователя.

Узнайте больше о Spring Security и OIDC

В этой статье показано, как реализовать вход в систему с помощью OAuth 2.0 и Spring Security 5. Я также показал, как использовать OIDC для получения информации о пользователе. Исходный код приложения, разработанного в этой статье, можно найти на GitHub .

Эти ресурсы предоставляют дополнительную информацию об Okta и OIDC:

Если у вас есть какие-либо вопросы по поводу этого поста, пожалуйста, оставьте комментарий ниже. Вы также можете отправлять сообщения в Stack Overflow с помощью тега okta или использовать наши форумы разработчиков .

Следите за @OktaDev в Твиттере, чтобы узнать больше интересного !

«Я люблю писать код аутентификации и авторизации». Нет Java-разработчика. Надоело строить одни и те же экраны входа снова и снова? Попробуйте API Okta для размещенной аутентификации, авторизации и многофакторной аутентификации.

Начните работу с Spring Security 5.0, и OIDC был первоначально опубликован в блоге разработчиков Okta 18 декабря 2017 года.