Микросервисы и пружинная безопасность OAuth2
У меня уже есть сервер авторизации OAuth2, работающий в другом проекте. Теперь мне нужно будет защитить несколько простых REST-серверов spring-boot с OAuth2. Но я нахожу Весна документации действительно очень ограничен, когда дело доходит до разделения серверов авторизации и ресурсов.
Я нашел несколько вопросов, где ответ было "Ну, они могут быть разными коробками, пока они имеют один и тот же источник данных tokenStore". Может это неужели правда? Как это могло когда-нибудь работать для микросервисов? Казалось бы, очень странно, что каждая служба rest должна будет реализовать собственный сервер авторизации OAuth.
Итак, как настроить Oauth2.0 безопасность для Spring-boot REST-конечных точек, которые ссылаются на удаленный сервер авторизации oauth (возможно, даже не написанный с Spring)?
есть такая штука, называется RemoteTokenServices это кажется многообещающим, но на самом деле это не документировано все.
3 ответов
при настройке сервера auh::
создать новую юридическим лицом; в ClientDetailsServiceConfigurer
для ресурсов сервера. который будет использоваться для настройки RemoteTokenService
.
настройка Spring Security OAuth2 на сервере ресурсов:
создайте класс, который аннотируется с помощью @EnableWebSecurity
,@Configuration
и выходит WebSecurityConfigurerAdapter
.
@Configuration
@EnableWebSecurity
protected static class ResourceConfiguration extends WebSecurityConfigurerAdapter {
// methods
}
создайте метод с аннотированным @Bean, который вернет экземпляр TokenService
, который будет использоваться для создания AuthenticationManager
.
в этом методе создается экземпляр RemoteTokenService
и установить clientId, client_secret, checkTokenEndpointUrl и DefaultAccessTokenConverterWithClientRoles
(этот класс является нашей реализацией, чтобы получить client_authority при проверке подлинности accessToken на сервере OAuth2.)
@Bean
public ResourceServerTokenServices tokenService() {
RemoteTokenServices tokenServices = new RemoteTokenServices();
tokenServices.setClientId("resource_id");
tokenServices.setClientSecret("resource_secret");
tokenServices.setCheckTokenEndpointUrl("http://<server-url>: <port>/oauth/check_token");
return tokenServices;
}
переопределить authenticationManagerBean()
метод и аннотировать его с @Bean
и возвратить экземпляр OAuth2AuthenticationManager
С TokenService
вводят.
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
OAuth2AuthenticationManager authenticationManager = new OAuth2AuthenticationManager();
authenticationManager.setTokenServices(tokenService());
return authenticationManager;
}
создать класс с аннотацией @EnableResourceServer
, @Configuration
и продлить ResourceServerConfigurerAdapter
.
@Configuration
@EnableResourceServer
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
// Mehotds
}
переопределить методы настройки образуют супер класс для настройки сервера ресурсов. Другой конфигуратор для настройки сервера ресурсов.
ResourceServerSecurityConfigurer: настройка Resource_id.
HttpSecurity: это настроит фильтр безопасности, чтобы сообщить ему, что пользователю требуется аутентификация для защищенных URL-адресов (API).
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource_id");
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/**").authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
.antMatcher("/**").authenticated()
эта строка защитит каждый url-адрес api вашего сервера ресурсов.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
не будет создавать сессии.
PS:: Если что-то не так, скажите мне.
это не совсем верно, что оба должны совместно использовать одну и ту же базу данных, при условии, что сервер ресурсов имеет какой-то способ проверки подлинности маркера доступа (был выдан сервером авторизации), а также какой-то способ его декодирования (возможно, ему нужно знать, какие области он предоставляет, например). Спецификация OAuth2 ничего не говорит о том, как это должно быть достигнуто.
Если ресурс находится в том же процессе, что и сервер авторизации, то совместное использование данных является простым вариантом. В противном случае ему нужен какой-то способ перевода токена. Если токен-это просто непрозрачная строка случайных байтов, то, очевидно, он должен обменять ее на реальную информацию. Это RemoteTokenServices
делает. Сервер авторизации предоставляет /check_token
endpoint, чтобы разрешить декодирование маркеров.
альтернативой является фактическое кодирование информации в токене и цифровая подпись сервера авторизации. Затем сервер ресурсов может декодировать и проверять сам токен до тех пор, пока он понять формат.
Я бы рекомендовал вам посмотреть на Cloudfoundry UAA который предоставляет сервер авторизации из коробки, которая реализована с использованием подписанных токенов JWT (он также предоставляет /check_token
конечная точка). The жетоны обзор и API docs вероятно, хорошая отправная точка.
рабочий образец RemoteTokenService
можно найти здесь.
подробнее о check_token
api, вы можете ссылаться org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.java
на ресурсе сервера OAuth2AuthenticationProcessingFilter
проверяет токен OAuth2, вызывая OAuth2AuthenticationManager.authenticate()
метод, который делает вызов RemoteTokenServices.loadAuthentication()
для проверки токена с сервера аутентификации.