1. Обзор
Модуль Spring Cloud Security предоставляет функции, связанные с безопасностью на основе токенов в приложениях Spring Boot.
В частности, это упрощает единый вход на основе OAuth2 благодаря поддержке ретрансляции токенов между серверами ресурсов, а также настройке нижестоящей аутентификации с использованием встроенного прокси-сервера Zuul.
В этой быстрой статье мы рассмотрим, как мы можем настроить эти функции с помощью клиентского приложения Spring Boot, сервера авторизации и REST API, работающего в качестве сервера ресурсов.
Обратите внимание, что в этом примере у нас есть только одно клиентское приложение, которое использует SSO для демонстрации функций облачной безопасности, но в типичном сценарии у нас было бы как минимум два клиентских приложения, чтобы обосновать необходимость единого входа.
2. Быстрый запуск приложения облачной безопасности
Начнем с настройки SSO в приложении Spring Boot.
Во- первых, нам нужно добавить зависимость spring-cloud-starter-oauth2
:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
Это также приведет к зависимости 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 добавляет bean-компонент OAuth2ClientContext
в область запроса. Исходя из этого, мы можем создать собственный OAuth2RestTemplate
в нашем клиентском приложении:
@Bean
public OAuth2RestOperations restOperations(
OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) {
return new OAuth2RestTemplate(resource, context);
}
После того, как мы настроили bean-компонент ,
контекст перенаправит токен доступа к запрошенным службам, а также обновит токен, если срок его действия истечет.
4. Ретрансляция токена OAuth с помощью RestTemplate
Ранее мы определили bean-компонент restOperations
типа 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 Embedded Reverse Proxy.
Во-первых, нам нужно добавить зависимость Maven для работы с Zuul:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
Далее нам нужно добавить аннотацию @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
и Embedded Zuul Proxy.
Как всегда, код доступен на GitHub .