#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. Спасибо