Перейти к основному содержимому

OAuth2 — @EnableResourceServer против @EnableOAuth2Sso

· 5 мин. чтения

1. Обзор

В этом руководстве мы поговорим об аннотациях @EnableResourceServer и @EnableOAuth2Sso в Spring Security.

Мы начнем с объяснения различий между клиентом OAuth2 и сервером ресурсов OAuth2 . После этого мы немного поговорим о том, что эти аннотации могут сделать для нас, и продемонстрируем их использование на примере с использованием Zuul и простого API.

В этой статье мы предполагаем, что у вас уже есть опыт работы с Zuul и OAuth2 .

Если у вас его нет или вы считаете, что обзор любого из них был бы полезен, обратитесь к нашему краткому обзору Zuul и нашему руководству по OAuth2 .

2. Клиент OAuth2 и сервер ресурсов

В OAuth2 нам нужно рассмотреть четыре разные роли :

  • Владелец ресурса — лицо, которое может предоставлять доступ к своим защищенным ресурсам.
  • Сервер авторизации — предоставляет токены доступа клиентам после успешной аутентификации владельцев ресурсов и получения их авторизации. ``
  • Сервер ресурсов — компонент, которому требуется токен доступа, чтобы разрешить или, по крайней мере, рассмотреть возможность доступа к своим ресурсам.
  • Клиент — сущность, способная получать токены доступа с серверов авторизации.

Аннотирование нашего класса конфигурации с помощью @EnableResourceServer или @EnableOAuth2Sso указывает Spring настроить компоненты, которые преобразуют наше приложение в одну из двух последних ролей, упомянутых выше.

Аннотация @EnableResourceServer позволяет нашему приложению вести себя как сервер ресурсов , настроив OAuth2AuthenticationProcessingFilter и другие не менее важные компоненты .

Ознакомьтесь с классом ResourceServerSecurityConfigurer , чтобы лучше понять, что настраивается за кулисами.

И наоборот, аннотация @EnableOAuth2Sso превращает наше приложение в клиент OAuth2 . Он указывает Spring настроить OAuth2ClientAuthenticationProcessingFilter вместе с другими компонентами, которые необходимы нашему приложению для получения токенов доступа с сервера авторизации.

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

Сочетание этих аннотаций с некоторыми свойствами позволяет нам быстро все настроить и запустить. Давайте создадим два разных приложения, чтобы увидеть их в действии и то, как они могут дополнять друг друга:

  • Нашим первым приложением будет пограничный узел, простое приложение Zuul , которое будет использовать аннотацию @EnableOAuth2Sso . Он будет отвечать за аутентификацию пользователей (с помощью сервера авторизации ) и делегировать входящие запросы другим приложениям . ``
  • Второе приложение будет использовать аннотацию @EnableResourceServer и будет разрешать доступ к защищенным ресурсам, если входящие запросы содержат действительный токен доступа OAuth2.

3. Зуул — @EnableOAuth2Sso

Давайте начнем с создания приложения Zuul , которое будет действовать как наш пограничный узел и будет отвечать за аутентификацию пользователей с использованием сервера авторизации OAuth2 :

@Configuration
@EnableZuulProxy
@EnableOAuth2Sso
@Order(value = 0)
public class AppConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private ResourceServerTokenServices
resourceServerTokenServices;

@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authorization-server-1/**",
"/login").permitAll()
.anyRequest().authenticated().and()
.logout().permitAll().logoutSuccessUrl("/");
}
}

Аннотирование нашего приложения Zuul с помощью @ EnableOAuth2Sso также уведомляет Spring о необходимости настроить фильтр OAuth2TokenRelayFilter . Этот фильтр извлекает ранее полученные маркеры доступа из сеансов HTTP пользователей и распространяет их ниже по течению.

Обратите внимание, что мы также используем аннотацию @Order в нашем классе конфигурации AppConfiguration . Это делается для того, чтобы фильтры , созданные нашим WebSecurityConfigurerAdapter , имели приоритет над фильтрами , созданными другими WebSecurityConfigurerAdapter .

Например, мы могли бы аннотировать наше приложение Zuul с помощью @EnableResourceServer для поддержки как идентификаторов сеанса HTTP, так и токенов доступа OAuth2. Однако при этом создаются новые фильтры , которые по умолчанию имеют приоритет над фильтрами, созданными классом AppConfiguration . Это происходит потому , что ResouceServerConfiguration , класс конфигурации, активируемый @EnableResourceServer , указывает порядок по умолчанию 3, а WebSecurityConfigureAdapter имеет порядок по умолчанию 100.

Прежде чем мы перейдем к нашему серверу ресурсов , нам нужно настроить некоторые свойства: ``

zuul:
routes:
resource-server-mvc-1: /resource-server-mvc-1/**
authorization-server-1:
sensitiveHeaders: Authorization
path: /authorization-server-1/**
stripPrefix: false
add-proxy-headers: true

security:
basic:
enabled: false
oauth2:
sso:
loginPath: /login
client:
accessTokenUri: http://localhost:8769/authorization-server-1/oauth/token
userAuthorizationUri: /authorization-server-1/oauth/authorize
clientId: fooClient
clientSecret: fooSecret
resource:
jwt:
keyValue: "abc"
id: fooScope
serviceId: ${PREFIX:}resource

Не вдаваясь в подробности, используя этот конфиг, мы:

  • Настраиваем наши маршруты Zuul и сообщаем, какие заголовки следует добавить/удалить перед отправкой запросов вниз по течению.
  • Установка некоторых свойств OAuth2 для нашего приложения, чтобы иметь возможность взаимодействовать с нашим сервером авторизации и настройка JWT с симметричным шифрованием. [](/lessons/b/-spring-security-oauth-jwt) ``

4. API — @EnableResourceServer

Теперь, когда у нас есть приложение Zuul , давайте создадим наш Resource Server :

@SpringBootApplication
@EnableResourceServer
@Controller
@RequestMapping("/")
class ResourceServerApplication {

public static void main(String[] args) {
SpringApplication.run(ResourceServerApplication.class, args);
}

@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public String helloWorld(Principal principal) {
return "Hello " + principal.getName();
}
}

Это простое приложение, которое предоставляет одну конечную точку для возврата имени принципала , инициировавшего запрос.

Давайте завершим, настроив некоторые свойства:

security:
basic:
enabled: false
oauth2:
resource:
jwt:
keyValue: "abc"
id: fooScope
service-id: ${PREFIX:}resource

Имейте в виду, что нам нужен действительный токен доступа (который хранится в HTTP-сеансе пользователя на нашем пограничном узле) для доступа к конечной точке нашего Resource Server .

5. Вывод

В этой статье мы объяснили различия между аннотациями @EnableOAuth2Sso и @EnableResourceServer . Мы также продемонстрировали, как их использовать, на практическом примере с использованием Zuul и простого API.

Полную реализацию этого примера можно найти на Github .

При локальном запуске мы можем запустить и протестировать приложение по адресу http://192.168.1.67:8765/resource-server-mvc-1 .