«Я люблю писать код аутентификации и авторизации». Нет Java-разработчика. Надоело строить одни и те же экраны входа снова и снова? Попробуйте API Okta для размещенной аутентификации, авторизации и многофакторной аутентификации.
При создании веб-приложения авторизация и авторизация являются обязательными. Однако сделать это правильно не просто. Компьютерная безопасность — это настоящая специальность. Легионы разработчиков работают днем и ночью против одинаково многочисленных международных хакеров, создавая непрерывный цикл разработки для поиска уязвимостей, их атаки и исправления. Следить за всем этим соло было бы больно (если не невозможно).
К счастью, в этом нет необходимости. Spring Security и Spring Boot сделали реализацию веб-приложения с использованием OAuth 2.0 приятной и простой. Кроме того, Okta, поставщик доступа к программному обеспечению как удостоверению личности, использует Spring Boot, чтобы сделать процесс еще проще.
В этом руководстве вы сначала создадите веб-приложение OAuth 2.0 и сервер аутентификации, используя Spring Boot и Spring Security. После этого вы будете использовать Okta, чтобы избавиться от собственного сервера аутентификации и еще больше упростить приложение Spring Boot.
Давайте начнем!
Создайте сервер OAuth 2.0
Начните с перехода к Spring Initializr и создания нового проекта со следующими настройками:
- Измените тип проекта с Maven на Gradle .
- Измените группу на com.okta.spring .
- Измените артефакт на AuthorizationServerApplication .
- Добавьте одну зависимость: Web .

Скачайте проект и скопируйте его куда-нибудь на свой жесткий диск. В этом уроке вы создадите три разных проекта, так что вы можете захотеть создать родительский каталог, где-то вроде SpringBootOAuth .
Вам нужно добавить одну зависимость в файл build.gradle :
implementation 'org.springframework.security.oauth:spring-security-oauth2:2.3.3.RELEASE' |
Это добавляет OAuth совершенства Spring.
Обновите src/main/resources/application.properties чтобы он соответствовал:
server.port=8081server.servlet.context-path=/authuser.oauth.clientId=R2dpxQ3vPrtfgF72user.oauth.clientSecret=fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9user.oauth.redirectUris=http://localhost:8082/login/oauth2/code/user.oauth.user.username=Andrewuser.oauth.user.password=abcd |
Это устанавливает порт сервера, путь контекста сервлета и некоторые значения по умолчанию для оперативной памяти, сгенерированных ad-hoc токенов, которые сервер собирается вернуть клиенту, а также для имени пользователя и пароля нашего пользователя. В производственной среде вам потребуется немного более сложный сервер для реального сервера аутентификации без жестко закодированных URI перенаправления, а также имен пользователей и паролей.
Обновите класс AuthorizationServerApplication добавив @EnableResourceServer :
package com.okta.spring.AuthorizationServerApplication;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;@SpringBootApplication@EnableResourceServerpublic class AuthorizationServerApplication { public static void main(String[] args) { SpringApplication.run(AuthorizationServerApplication.class, args); }} |
Создайте новый класс AuthServerConfig в том же пакете, что и ваш класс приложения com.okta.spring.AuthorizationServerApplication в src/main/java (отныне создавайте Java-классы в src/main/java/com/okta/spring/AuthorizationServerApplication ). Этот класс конфигурации Spring включает и настраивает сервер авторизации OAuth.
package com.okta.spring.AuthorizationServerApplication;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;@Configuration@EnableAuthorizationServerpublic class AuthServerConfig extends AuthorizationServerConfigurerAdapter { @Value("${user.oauth.clientId}") private String ClientID; @Value("${user.oauth.clientSecret}") private String ClientSecret; @Value("${user.oauth.redirectUris}") private String RedirectURLs; private final PasswordEncoder passwordEncoder; public AuthServerConfig(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } @Override public void configure( AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient(ClientID) .secret(passwordEncoder.encode(ClientSecret)) .authorizedGrantTypes("authorization_code") .scopes("user_info") .autoApprove(true) .redirectUris(RedirectURLs); }} |
Класс AuthServerConfig — это класс, который создает и возвращает наши веб-токены JSON при правильной аутентификации клиента.
Создайте класс SecurityConfiguration :
package com.okta.spring.AuthorizationServerApplication;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.Order;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@Configuration@Order(1)public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Value("${user.oauth.user.username}") private String username; @Value("${user.oauth.user.password}") private String password; @Override protected void configure(HttpSecurity http) throws Exception { http.requestMatchers() .antMatchers("/login", "/oauth/authorize") .and() .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser(username) .password(passwordEncoder().encode(password)) .roles("USER"); } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }} |
Класс SecurityConfiguration — это класс, который фактически проверяет подлинность запросов к вашему серверу авторизации. Обратите внимание на верхнюю часть, где он извлекает имя пользователя и пароль из файла application.properties .
Наконец, создайте класс Java с именем UserController :
package com.okta.spring.AuthorizationServerApplication;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.security.Principal;@RestControllerpublic class UserController { @GetMapping("/user/me") public Principal user(Principal principal) { return principal; }} |
Этот файл позволяет клиентским приложениям узнать больше о пользователях, которые проходят аутентификацию на сервере.
Это ваш ресурсный сервер! Не так уж плохо. Spring Boot делает это довольно легко. Четыре файла и несколько свойств. Чуть позже вы сделаете это еще проще с Okta, но сейчас перейдем к созданию клиентского приложения, которое вы можете использовать для тестирования сервера аутентификации.
Запустите сервер авторизации:
./gradlew bootRun |
Подождите немного, пока он закончит работу. Терминал должен заканчиваться примерно так:
...2019-02-23 19:06:49.122 INFO 54333 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path '/auth '2019-02-23 19:06:49.128 INFO 54333 --- [ main] c.o.s.A.AuthorizationServerApplication : Started AuthorizationServerApplication in 3.502 seconds (JVM running for 3.945) |
ПРИМЕЧАНИЕ. Если вы получаете сообщение об ошибке JAXB ( java.lang.ClassNotFoundException: javax.xml.bind.JAXBException ), то это потому, что вы используете Java 11. Чтобы это исправить, добавьте JAXB в свой build.gradle .
implementation 'org.glassfish.jaxb:jaxb-runtime' |
Создайте свое клиентское приложение
Вернуться к Весне Инициализр . Создайте новый проект со следующими настройками:
- Тип проекта должен быть Gradle (не Maven).
- Группа: com.okta.spring .
- Артефакт: SpringBootOAuthClient .
- Добавьте три зависимости: Web , Thymeleaf , OAuth2 Client .

Загрузите проект, скопируйте его в место последнего распаковывания и распакуйте его.
На этот раз вам нужно добавить следующую зависимость в ваш файл build.gradle :
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE' |
Переименуйте src/main/resources/application.properties в application.yml и обновите его, чтобы он соответствовал YAML ниже:
server: port: 8082 session: cookie: name: UISESSIONspring: thymeleaf: cache: false security: oauth2: client: registration: custom-client: client-id: R2dpxQ3vPrtfgF72 client-secret: fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9 client-name: Auth Server scope: user_info provider: custom-provider redirect-uri-template: http://localhost:8082/login/oauth2/code/ client-authentication-method: basic authorization-grant-type: authorization_code provider: custom-provider: token-uri: http://localhost:8081/auth/oauth/token authorization-uri: http://localhost:8081/auth/oauth/authorize user-info-uri: http://localhost:8081/auth/user/me user-name-attribute: name |
Обратите внимание, что здесь вы настраиваете clientId и clientSecret , а также различные URI для вашего сервера аутентификации. Они должны соответствовать значениям в другом проекте.
Обновите класс SpringBootOAuthClientApplication чтобы он соответствовал:
package com.okta.spring.SpringBootOAuthClient;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringBootOAuthClientApplication { public static void main(String[] args) { SpringApplication.run(SpringBootOAuthClientApplication.class, args); }} |
Создайте новый класс Java с именем WebController :
package com.okta.spring.SpringBootOAuthClient;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import java.security.Principal;@Controllerpublic class WebController { @RequestMapping("/securedPage") public String securedPage(Model model, Principal principal) { return "securedPage"; } @RequestMapping("/") public String index(Model model, Principal principal) { return "index"; }} |
Это контроллер, который отображает входящие запросы в ваши файлы шаблонов Thymeleaf (которые вы сделаете через секунду).
Создайте другой класс Java с именем SecurityConfiguration :
package com.okta.spring.SpringBootOAuthClient;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configurationpublic class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.antMatcher("/**").authorizeRequests() .antMatchers("/", "/login**").permitAll() .anyRequest().authenticated() .and() .oauth2Login(); }} |
Этот класс определяет конфигурацию Spring Security для вашего приложения: разрешает все запросы на домашнем пути и требует аутентификации для всех других маршрутов. он также устанавливает поток входа в Spring Boot OAuth.
Последние файлы, которые вам нужно добавить, — это два файла шаблона Thymeleaf. Полное рассмотрение шаблонов Thymeleaf выходит далеко за рамки данного руководства, но вы можете взглянуть на их веб-сайт для получения дополнительной информации.
Шаблоны находятся в каталоге src/main/resources/templates . Вы заметите в контроллере выше, что они просто возвращают строки для маршрутов. Когда в сборку включены зависимости Thymeleaf, Spring Boot автоматически предполагает, что вы возвращаете имя файла шаблона из контроллеров, и поэтому приложение будет искать в src/main/resources/templates имя файла с возвращенной строкой плюс .html .
Создайте домашний шаблон: src/main/resources/templates/index.html :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>Spring Security SSO</h1> <a href="securedPage">Login</a> </body> </html> |
И защищенный шаблон: src/main/resources/templates/securedPage.html :
<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>Secured Page</title> </head> <body> <h1>Secured Page</h1> <span th:text="${#authentication.name}"></span> </body> </html> |
Я просто укажу на одну строку:
<span th:text="${#authentication.name}"></span> |
Это строка, которая будет вставлять имя аутентифицированного пользователя. В этой строке вам понадобилась org.thymeleaf.extras:thymeleaf-extras-springsecurity5 в файле build.gradle .
Запустите клиентское приложение:
./gradlew bootRun |
Подожди, пока оно закончится. Терминал должен заканчиваться примерно так:
...2019-02-23 19:29:04.448 INFO 54893 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path ''2019-02-23 19:29:04.453 INFO 54893 --- [ main] c.o.s.S.SpringBootOAuthClientApplication : Started SpringBootOAuthClientApplication in 3.911 seconds (JVM running for 4.403) |
Протестируйте сервер ресурсов
Перейдите в выбранном браузере к клиентскому приложению по адресу http://localhost:8082/ .
Нажмите на ссылку Войти .
Вы будете перенаправлены на страницу входа:

Введите имя пользователя Andrew и пароль abcd (из файла application.properties с сервера аутентификации).
Нажмите « Войти», и вы попадете в супер-необычный шаблон securedPage.html с надписью «Защищенная страница» и «Эндрю».
Большой! Оно работает. Теперь ты собираешься сделать это еще проще.
Вы можете остановить как серверные, так и клиентские приложения Spring Boot.
Создать приложение OpenID Connect
Okta является провайдером аутентификации и авторизации SaaS (программное обеспечение как услуга). Мы предоставляем бесплатные аккаунты разработчикам, чтобы они могли без проблем создавать приложения OIDC. Зайдите на сайт developer.okta.com и зарегистрируйтесь. После того как вы подтвердили свою электронную почту, войдите в систему и выполните следующие действия:
- Перейдите в Приложение > Добавить приложение .
- Выберите тип приложения Web и нажмите Next .
- Дайте приложению имя. Я назвал мой «Spring Boot OAuth».
- В разделе URI перенаправления входа в систему измените значение на
http://localhost:8080/login/oauth2/code/okta. Остальные значения по умолчанию будут работать. - Нажмите Готово .
Оставьте страницу открытой, чтобы принять к сведению идентификатор клиента и секрет клиента . Они понадобятся тебе через минуту.
Создать новое приложение Spring Boot
Вернемся к Spring Initializr еще раз. Создайте новый проект со следующими настройками:
- Измените тип проекта с Maven на Gradle .
- Измените группу на com.okta.spring .
- Измените Артефакт на OktaOAuthClient .
- Добавьте три зависимости: Web , Thymeleaf , Okta .
- Нажмите Создать проект .

Скопируйте проект и распакуйте его куда-нибудь.
В файле build.gradle добавьте следующую зависимость:
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE' |
Также, пока вы там, обратите внимание на зависимость com.okta.spring:okta-spring-boot-starter:1.1.0 . Это Okta Spring Boot Starter. Это удобный проект, который делает интеграцию Okta с Spring Boot приятной и простой. Для получения дополнительной информации взгляните на GitHub проекта .
Измените src/main/resources/application.properties на application.yml и добавьте следующее:
server: port: 8080okta: oauth2: issuer: https://{yourOktaDomain}/oauth2/default client-id: {yourClientId} client-secret: {yourClientSecret}spring: thymeleaf: cache: false |
Помните, когда я сказал, что вам понадобится ваш ClientID и Client Secret выше. Ну, время пришло. Вы должны заполнить их в файл, а также ваш URL издателя Okta. Это будет выглядеть примерно так: dev-123456.okta.com . Вы можете найти его в разделе API > Серверы авторизации .
Вам также понадобятся два похожих файла шаблона в каталоге src/main/resources/templates . Файл шаблона index.html точно такой же, и его можно скопировать, если хотите. securedPage.html шаблона securedPage.html немного отличается из-за способа, которым информация об аутентификации возвращается из Okta по сравнению с простым сервером аутентификации, который вы создали ранее.
Создайте домашний шаблон: src/main/resources/templates/index.html :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>Spring Security SSO</h1> <a href="securedPage">Login</a> </body> </html> |
И защищенный шаблон: src/main/resources/templates/securedPage.html :
<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>Secured Page</title> </head> <body> <h1>Secured Page</h1> <span th:text="${#authentication.principal.attributes.name}">Joe Coder</span> </body> </html> |
Создайте класс Java с именем WebController в пакете com.okta.spring.SpringBootOAuth :
package com.okta.spring.OktaOAuthClient;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import java.security.Principal;@Controllerpublic class WebController { @RequestMapping("/securedPage") public String securedPage(Model model, Principal principal) { return "securedPage"; } @RequestMapping("/") public String index(Model model, Principal principal) { return "index"; }} |
Этот класс просто создает два маршрута, один для домашнего маршрута и один для защищенного маршрута. Опять же, Spring Boot и Thymeleaf автоматически маскируют это для двух файлов шаблонов в src/main/resources/templates .
Наконец, создайте еще один Java-класс имен SecurityConfiguration :
package com.okta.spring.OktaOAuthClient;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configurationpublic class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.antMatcher("/**").authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated() .and() .oauth2Login(); }} |
Это оно! Бам!
Запустите клиент с поддержкой Okta-OAuth:
./gradlew bootRun |
Вы должны увидеть кучу выходных данных, которые заканчиваются на:
...2019-02-23 20:09:03.465 INFO 55890 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''2019-02-23 20:09:03.470 INFO 55890 --- [ main] c.o.s.O.OktaOAuthClientApplication : Started OktaOAuthClientApplication in 3.285 seconds (JVM running for 3.744) |
Перейдите по адресу http: // localhost: 8080 .
Нажмите кнопку Войти .
На этот раз вы будете перенаправлены на страницу входа в Okta. Вам может понадобиться использовать браузер в режиме инкогнито или выйти из своей панели мониторинга developer.okta.com, чтобы не пропустить страницу входа и не получить немедленный доступ к защищенной конечной точке.

Авторизуйтесь, и вы увидите защищенную страницу с вашим именем!
Узнайте больше о Spring Boot, Spring Security и OAuth 2.0
Вот и все. Супер просто. В предыдущем руководстве вы рассмотрели, как использовать Spring Boot и Spring Security для реализации базового сервера аутентификации и клиентского приложения. Затем вы использовали Okta, чтобы сделать еще более простое клиентское приложение с полнофункциональной аутентификацией SSO и OAuth.
Вы можете увидеть готовый код этого руководства на GitHub по адресу oktadeveloper / okta-spring-boot-authz-server-example .
Если вы хотите узнать больше о Spring Boot, OAuth 2.0 и Spring Security, ознакомьтесь с этими полезными руководствами:
- Начните с Spring Boot, OAuth 2.0 и Okta
- Что, черт возьми, OAuth?
- Начните с Spring Security 5.0 и OIDC
- Идентификационные данные, утверждения и токены — учебник по OpenID Connect, часть 1 из 3
- Создайте безопасный API с помощью Spring Boot и GraphQL
Если у вас есть какие-либо вопросы по поводу этого поста, пожалуйста, добавьте комментарий ниже. Чтобы получить более интересный контент, следите за @oktadev в Twitter или подпишитесь на наш канал на YouTube !
«Краткое руководство по OAuth 2.0 с Spring Security» первоначально было опубликовано в блоге разработчиков Okta в марте 2019 года.
«Я люблю писать код аутентификации и авторизации». Нет Java-разработчика. Надоело строить одни и те же экраны входа снова и снова? Попробуйте API Okta для размещенной аутентификации, авторизации и многофакторной аутентификации.