1. Обзор
Модуль безопасности Spring Cloud предоставляет функции, связанные с безопасностью на основе токенов в приложениях Spring Boot.
В частности, это упрощает SSO на основе OAuth2-с поддержкой ретрансляции токенов между серверами ресурсов, а также настройки нисходящей аутентификации с использованием встроенного прокси-сервера Zuul.
В этой краткой статье мы рассмотрим, как настроить эти функции с помощью клиентского приложения Spring Boot, сервера авторизации и API REST, работающего в качестве сервера ресурсов.
Обратите внимание, что в этом примере у нас есть только одно клиентское приложение, которое использует единый вход для демонстрации функций облачной безопасности, но в типичном сценарии у нас будет по крайней мере два клиентских приложения, чтобы обосновать необходимость единого входа.
2. Быстрый запуск приложения облачной безопасности
Давайте начнем с настройки единого входа в приложении Spring Boot.
Во-первых, нам нужно добавить spring-cloud-starter-oauth2 зависимость:
org.springframework.cloud spring-cloud-starter-oauth2 2.2.2.RELEASE
Это также приведет к зависимости spring-cloud-starter-security .
Мы можем настроить любой социальный сайт в качестве сервера аутентификации для нашего сайта или мы можем использовать наш собственный сервер. В нашем случае мы выбрали последний вариант и настроили приложение, которое действует как сервер авторизации, который развернут локально в http://localhost:7070/authserver.
Наш сервер авторизации использует токены JWT.
Кроме того, чтобы любой Клиент мог получить учетные данные пользователя, нам необходимо настроить наш сервер ресурсов, работающий на порту 9000, с конечной точкой, которая может обслуживать эти учетные данные.
Здесь мы настроили конечную точку/ user , доступную по адресу http://localhost:9000/user.
Для получения более подробной информации о том, как настроить Сервер авторизации и Сервер ресурсов, ознакомьтесь с нашей предыдущей статьей здесь .
Теперь мы можем добавить аннотацию в класс конфигурации в нашем клиентском приложении:
@Configuration @EnableOAuth2Sso public class SiteSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // ... } }
Любые запросы, требующие проверки подлинности, будут перенаправлены на Сервер авторизации. Для этого мы также должны определить свойства сервера:
security: oauth2: client: accessTokenUri: http://localhost:7070/authserver/oauth/token userAuthorizationUri: http://localhost:7070/authserver/oauth/authorize clientId: authserver clientSecret: passwordforauthserver resource: userInfoUri: http://localhost:9000/user
Обратите внимание, что нам нужно иметь spring-boot-starter-security в вашем пути к классу, чтобы найти приведенную выше конфигурацию работающей.
3. Ретрансляция Токенов Доступа
При ретрансляции токена клиент OAuth2 пересылает полученный им токен OAuth2 на исходящий запрос ресурса.
Поскольку мы объявили аннотацию @EnableOauth2Sso , Spring Boot добавляет OAuth2ClientContext bean в области запроса. Исходя из этого, мы можем создать свой собственный OAuth2RestTemplate в нашем клиентском приложении:
@Bean public OAuth2RestOperations restOperations( OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) { return new OAuth2RestTemplate(resource, context); }
Как только мы настроим компонент , контекст переадресует токен доступа запрошенным службам, а также обновит токен, если срок его действия истечет.
4. Ретрансляция токена OAuth с помощью RestTemplate
Ранее мы определили restOperations bean типа OAuth2RestTemplate в нашем клиентском приложении. В результате мы можем использовать getForObject() метод OAuth2RestTemplate для отправки запроса с необходимыми токенами на защищенный сервер ресурсов от нашего клиента.
Во-первых, давайте определим конечную точку, которая требует аутентификации на нашем сервере ресурсов:
@GetMapping("/person") @PreAuthorize("hasAnyRole('ADMIN', 'USER')") public @ResponseBody Person personInfo(){ return new Person("abir", "Dhaka", "Bangladesh", 29, "Male"); }
Это простая конечная точка REST, которая возвращает представление JSON объекта Person .
Теперь мы можем отправить запрос из клиентского приложения с помощью метода getForObject () , который передаст токен на сервер ресурсов :
@Autowired private RestOperations restOperations; @GetMapping("/personInfo") public ModelAndView person() { ModelAndView mav = new ModelAndView("personinfo"); String personResourceUrl = "http://localhost:9000/person"; mav.addObject("person", restOperations.getForObject(personResourceUrl, String.class)); return mav; }
5. Настройка Zuul для ретрансляции токенов
Если мы хотим передать токен вниз по потоку прокси-службам, мы можем использовать встроенный обратный прокси-сервер Spring Cloud Zuul.
Во-первых, нам нужно добавить зависимость Maven для работы с Zuul:
org.springframework.cloud spring-cloud-starter-netflix-zuul
Затем нам нужно добавить аннотацию @ EnableZuulProxy в наш класс конфигурации в клиентском приложении:
@Configuration @EnableOAuth2Sso @EnableZuulProxy public class SiteSecurityConfigurer extends WebSecurityConfigurerAdapter { //... }
Все, что осталось сделать, это добавить свойства конфигурации Zuul в наш файл application.yml :
zuul: sensitiveHeaders: Cookie,Set-Cookie routes: resource: path: /api/** url: http://localhost:9000 user: path: /user/** url: http://localhost:9000/user
Любой запрос, поступающий в конечную точку/|/api клиентского приложения, будет перенаправлен на URL-адрес сервера ресурсов. Нам также необходимо указать URL-адрес конечной точки учетных данных пользователя.
6. Заключение
В этой краткой статье мы рассмотрели, как использовать Spring Cloud Security с OAuth2 и Zuul для настройки защищенных серверов авторизации и ресурсов, а также как ретранслировать токены OAuth2 между серверами с помощью OAuth2RestTemplate и встроенного прокси-сервера Zuul.
Как всегда, код доступен на GitHub .