«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. token
3. Zuul — @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 с симметричным шифрованием.
4. API — @EnableResourceServer
Теперь, когда у нас есть приложение Zuul, давайте создадим наш сервер ресурсов:
@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-сеансе пользователя в нашем пограничном узле) для доступа к конечной точке нашего ресурса. Сервер.
5. Заключение
В этой статье мы объяснили различия между аннотациями @EnableOAuth2Sso и @EnableResourceServer. Мы также продемонстрировали, как их использовать, на практическом примере с использованием Zuul и простого API.
Полную реализацию этого примера можно найти на Github.
При локальном запуске мы можем запустить и протестировать приложение по адресу http://192.168.1.67:8765/resource-server-mvc-1