«Я люблю писать код аутентификации и авторизации». Нет 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 Войти
- Реактивная поддержка: @EnableWebFluxSecurity , @EnableReactiveMethodSecurity и поддержка тестирования WebFlux
- Модернизированное кодирование паролей
Сегодня я покажу вам, как использовать поддержку OAuth 2.0 Login с Okta. Я также покажу вам, как получить информацию о пользователе через OpenID Connect (OIDC).
Вы знаете, что Okta предлагает бесплатные учетные записи разработчиков до 7000 активных ежемесячных пользователей, верно? Этого должно быть достаточно, чтобы убрать ваше приложение-убийцу.
Spring Security делает аутентификацию с OAuth 2.0 чертовски простой. Он также предоставляет возможность извлекать информацию пользователя через OIDC. Следуйте инструкциям ниже, чтобы узнать больше!
Что такое OIDC? Если вы не знакомы с OAuth или OIDC, я рекомендую вам прочитать, что такое OAuth . Поток Open ID Connect включает в себя следующие шаги:
- Откройте для себя метаданные OIDC
- Выполните поток OAuth для получения токена ID и доступа к токенам
- Получить ключи подписи JWT и при необходимости динамически зарегистрировать клиентское приложение
- Проверьте токен JWT ID локально на основе встроенных дат и подписи
- Получить дополнительные пользовательские атрибуты при необходимости с токеном доступа
Создать приложение 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:
- Документация для разработчиков Okta и API OpenID Connect
- Идентификационные данные, утверждения и токены — учебник по OpenID Connect, часть 1 из 3
- OIDC в действии — учебник по OpenID Connect, часть 2 из 3
- Что в токене? — учебник по OpenID Connect, часть 3 из 3
- Добавьте контроль доступа на основе ролей в свое приложение с помощью Spring Security и Thymeleaf
Если у вас есть какие-либо вопросы по поводу этого поста, пожалуйста, оставьте комментарий ниже. Вы также можете отправлять сообщения в Stack Overflow с помощью тега okta или использовать наши форумы разработчиков .
Следите за @OktaDev в Твиттере, чтобы узнать больше интересного !
«Я люблю писать код аутентификации и авторизации». Нет Java-разработчика. Надоело строить одни и те же экраны входа снова и снова? Попробуйте API Okta для размещенной аутентификации, авторизации и многофакторной аутентификации.
Начните работу с Spring Security 5.0, и OIDC был первоначально опубликован в блоге разработчиков Okta 18 декабря 2017 года.