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 .