Как настроить сервер реактивных ресурсов для использования JWT с симметричным ключом?

#java #spring-security #spring-webflux #spring-security-oauth2

#java #spring-безопасность #spring-webflux #spring-security-oauth2

Вопрос:

На сервере авторизации мой Jwt был сгенерирован с помощью этого:

       @Value("${jwt.key}")
      private String jwtKey;

      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
            .authenticationManager(authenticationManager)
            .tokenStore(tokenStore)
            .accessTokenConverter(jwtAccessTokenConverter);
      }
    
      @Bean
      public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
      }
    
      @Bean
      public JwtAccessTokenConverter jwtAccessTokenConverter() {
        var converter = new JwtAccessTokenConverter();
        converter.setSigningKey(jwtKey);
        return converter;
      }
  

Теперь на стороне сервера реактивных ресурсов:

   @Value("${jwt.key}")
  private String jwtKey;

  @Bean
  public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    return http
        .authorizeExchange()
        .anyExchange().authenticated()
        .and()
        .oauth2ResourceServer()
        .jwt(jwtSpec -> {...})
        .and.build();
  }
  

Как я могу настроить свой сервер реактивных ресурсов на использование этого токена с учетом ключа подписи?

Комментарии:

1. Вы используете Spring Boot? (А если нет, то почему бы и нет, поскольку вы используете Webflux?)

2. Да, я использую spring boot

3. я понятия не имею, о чем вы говорите. у jwt нет «ключа». И вы не используете «токен». Вы подписываете jwt, используя jwk (веб-ключ json), и у вас есть закрытый ключ на вашем сервере авторизации, и вы распространяете открытый ключ всем приложениям, которым необходимо проверить вывеску. Вы стандартно предоставляете URL-адрес для сервера ресурсов, чтобы сервер авторизации мог поворачивать ключи с заданными интервалами. И вы не должны «делиться» одним и тем же ключом между двумя серверами. Вам нужна пара ключей.

4. если вы правильно используете терминологию и понимаете, как вы это делаете, это описано здесь, в справочном руководстве по безопасности spring boot . Я предлагаю вам прочитать о том, как работают oauth и jwt, документация действительно очень хорошая docs.spring.io/spring-security/site/docs/current/reference /…

5. Пожалуйста, дайте мне знать эту конфигурацию … вот почему я здесь. Я знаю, как управлять для нереактивных. Но для реактивного, похоже, это должно пройти .oauth2ResourceServer().jwt(jwtSpec -> {...}) . Я просто не знаю человека

Ответ №1:

   @Value("${jwt.key}")
  private String jwtKey;

  @Bean
  public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    return http
        .authorizeExchange()
        .anyExchange().authenticated()
        .and()
        .oauth2ResourceServer()
        .jwt(jwtSpec -> { jwtSpec.decoder(jwtDecoder()); })
        .and.build();
  }

  @Bean
  public JwtDecoder jwtDecoder() {
    SecretKey secretKey = new SecretKeySpec(jwtKey, "HMACSHA256");
    return NimbusJwtDecoder
            .withSecretKey(secretKey)
            .macAlgorithm(MacAlgorithm.HS256)
            .build();
 }
  

Если вы не укажете алгоритм подписи, сервер авторизации использует HMACSHA256 в качестве алгоритма по умолчанию. Поэтому вам нужно указать это в конфигурации сервера ресурсов.

Комментарии:

1. Просто небольшое исправление, с которым оно работало ReactiveJwtDecoder , и NimbusReactiveJwtDecoder