OAuth2 - @EnableResourceServer vs @ EnableOAuth2Sso
1. обзор
В этом руководстве мы поговорим об аннотациях@EnableResourceServer и@EnableOAuth2Sso в Spring Security.
Начнем с объясненияdifferences between an OAuth2 Client and an OAuth2 Resource Server. После этого мы немного поговорим о том, что эти аннотации могут для нас сделать, и продемонстрируем их использование на примере с использованиемZuul и простого API.
Для целей этой статьи мы будем предполагать некоторый ранее существовавший опыт работы сZuul иOAuth2.
Если у вас их нет или вы считаете, что обзор любого из них был бы полезен, обратитесь к нашимquick overview on Zuul и нашимguide to OAuth2.
2. Клиент OAuth2 и сервер ресурсов
В OAuth2 необходимо учитывать четыре разныхroles:
-
Resource Owner - объект, который может предоставить доступ к своим защищенным ресурсам
-
Authorization Server - предоставляет токены доступаClients после успешной аутентификацииResourceOwners и получения их авторизации
-
Resource Server - компонент, которому требуется токен доступа для разрешения или, по крайней мере, возможности доступа к его ресурсам
-
Client - сущность, способная получать токены доступа от серверов авторизации
Аннотирование нашего класса конфигурации с помощью@EnableResourceServer или@EnableOAuth2Sso указывает Spring настроить компоненты, которые преобразуют наше приложение в одну из двух последних ролей, упомянутых выше.
The @EnableResourceServer annotation enables our application to behave as a Resource Server, настроивOAuth2AuthenticationProcessingFilter и другие не менее важные компоненты.
Посмотрите классResourceServerSecurityConfigurer, чтобы лучше понять, что настраивается за кулисами.
Наоборот,the @EnableOAuth2Sso annotation transforms our application into an OAuth2 client. Он инструктирует Spring настроитьOAuth2ClientAuthenticationProcessingFilter вместе с другими компонентами, которые необходимы нашему приложению для получения токенов доступа с сервера авторизации.
Взгляните на классSsoSecurityConfigurer для получения дополнительных сведений о том, что Spring настраивает для нас.
Объединение этих аннотаций с некоторыми свойствами позволяет нам быстро приступить к работе. Давайте создадим два разных приложения, чтобы увидеть, как они работают и как они могут дополнять друг друга:
-
Нашим первым приложением будет граничный узел, простое приложениеZuul, которое будет использовать аннотацию@EnableOAuth2Sso. Он будет отвечать за аутентификацию пользователей (с помощьюAuthorizationServer) и делегировать входящие запросы другим приложениям.
-
Второе приложение будет использовать аннотацию@EnableResourceServer и разрешит доступ к защищенным ресурсам, если входящие запросы содержат действительный токен доступа OAuth2.
3. Зуул -@EnableOAuth2Sso
Начнем с создания приложенияZuul, которое будет действовать как наш граничный узел и будет отвечать за аутентификацию пользователей с использованием OAuth2AuthorizationServer:
@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. Это сделано для того, чтобы гарантировать, чтоFilters, созданные нашимWebSecurityConfigurerAdapter, имеют приоритет надFilters, созданным другимиWebSecurityConfigurerAdapters.
Например, мы могли бы аннотировать наше приложениеZuul с помощью@EnableResourceServer для поддержки как идентификаторов сеанса HTTP, так и токенов доступа OAuth2. Однако при этом создаются новыеFilters, которые по умолчанию имеют приоритет над теми, которые созданы классомAppConfiguration. Это происходит потому, чтоResouceServerConfiguration, класс конфигурации, запускаемый@EnableResourceServer, указывает значение по умолчанию дляorder, равное 3, в то время какWebSecurityConfigureAdapter имеет значение по умолчанию дляorder, равное 100.
Прежде чем мы перейдем к нашемуResourceServer,, нам нужно настроить некоторые свойства:
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 для нашего приложения, чтобы иметь возможность взаимодействовать с нашимAuthorizationServer, и настройкаJWT с шифрованиемsymmetric.
4. API -@EnableResourceServer
Теперь, когда у нас есть приложениеZuul, давайте создадим нашеResourceServer:
@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();
}
}
Это простое приложение, которое предоставляет единственную конечную точку для возвратаnamePrincipal, инициировавшего запрос.
В заключение, настроим некоторые свойства:
security:
basic:
enabled: false
oauth2:
resource:
jwt:
keyValue: "abc"
id: fooScope
service-id: ${PREFIX:}resource
Имейте в виду, чтоwe need a valid access token (который хранится в HTTP-сеансе пользователя в нашем пограничном узле)to access the endpoint of our Resource Server.
5. Заключение
В этой статье мы объяснили различия между аннотациями@EnableOAuth2Sso и@EnableResourceServer. Мы также продемонстрировали, как их использовать, на практическом примере с использованиемZuul и простого API.
Полную реализацию этого примера можно найти вover on Github.
При локальном запуске мы можем запустить и протестировать приложение наhttp://192.168.1.67:8765/resource-server-mvc-1