Микросервисы и пружинная безопасность 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() для проверки токена с сервера аутентификации.