Как настроить декодер jwt в spring boot oauth2

#spring #spring-boot #spring-security #oauth-2.0

#spring #spring-загрузка #spring-безопасность #oauth-2.0

Вопрос:

Я хочу динамически устанавливать jwk-set-uri для разных клиентов на моем сервере ресурсов, информацию о которых я получаю из фильтра. И у меня есть следующая конфигурация сервера ресурсов.

 @Slf4j
@Import(SecurityProblemSupport.class)
@RequiredArgsConstructor
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  private final SecurityProblemSupport problemSupport;
  private final RealmProperties realmProperties;
  private final MultiTenantManager multiTenantManager;

  @Override
  public void configure(final HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .exceptionHandling().authenticationEntryPoint(problemSupport).accessDeniedHandler(problemSupport)
      .and()
        .authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
      .and().requestMatcher(new OAuthRequestedMatcher()).authorizeRequests().anyRequest()
        .fullyAuthenticated();
  }

  @Bean
  public RequestContextListener requestContextListener() {
    return new RequestContextListener();
  }

  private static class OAuthRequestedMatcher implements RequestMatcher {

    public boolean matches(HttpServletRequest request) {
      String auth = request.getHeader("Authorization");
      log.debug("auth decode from request: ", auth);
      boolean haveOauth2Token = (auth != null) amp;amp; auth.startsWith("Bearer");
      boolean haveAccessToken = request.getParameter("access_token") != null;
      return haveOauth2Token || haveAccessToken;
    }
  }

  @Override
  public void configure(final ResourceServerSecurityConfigurer config) {
    config.resourceId("login-app");
  }

  @Bean
  SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.authorizeExchange().anyExchange().authenticated().and().oauth2ResourceServer().jwt()
        .jwtDecoder(myCustomDecoder());
    return http.build();
  }

  @Bean
  ReactiveJwtDecoder myCustomDecoder() {
    return realmProperties.getRealms().stream()
    .filter(realm -> realm.getRealm().equals(multiTenantManager.getCurrentTenant()))
    .map(realm -> new NimbusReactiveJwtDecoder(((Realm) realm).getJwkSetUri()))
    .findFirst()
    .orElseThrow(() -> new InternalServerErrorException("cannot find the jwk set url for the realm"));
  }
}
  

Но я получил исключение, говорящее

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.ObjectPostProcessor<?>' available
  

Любая помощь по этому поводу? что я могу сделать, чтобы динамически задать uri jwk set для анализа токена?

Спасибо -Peng

Ответ №1:

Я решаю настройки декодирования токена следующим образом:

 @Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    // Inject
    private String resourceId;

    // Inject
    private String secret;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(resourceId);
        resources.tokenStore(createTokenStore(new ResourceAccessTokenConverter()));
    }

    private TokenStore createTokenStore(AccessTokenConverter converter) {
        JwtAccessTokenConverter tokenConverter = new CustomJwtAccessTokenConverter();
        tokenConverter.setAccessTokenConverter(converter);
        tokenConverter.setVerifier(new MacSigner(secret));
        TokenStore ts = new JwtTokenStore(tokenConverter);

        return ts;
    }


    public class CustomJwtAccessTokenConverter extends JwtAccessTokenConverter {


        @Override
        protected Map<String, Object> decode(String token) {
            return super.decode(token);
        }

        @Override
        public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
            return super.convertAccessToken(token, authentication);
        }

        @Override
        public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map) {
            return super.extractAccessToken(value, map);
        }

        @Override
        public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
            return super.extractAuthentication(map);
        }

    }

}
  

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

1. Не могли бы вы, пожалуйста, уточнить это решение. Мне нужно протестировать Spring Security 5 с поддержкой NimbusJwtDecoderJwkSupport. Спасибо