Merge pull request #8268 from Eddú Meléndez
* gh-8268: Polish "Enable customization of RestTemplate that retrieves JwtAccessTokenConverter's key" Enable customization of RestTemplate that retrieves JwtAccessTokenConverter's key
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.security.oauth2.resource;
|
||||
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Callback for customizing the {@link RestTemplate} that is used to fetch the keys used
|
||||
* by {@link JwtAccessTokenConverter}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @since 1.5.2
|
||||
* @see JwtAccessTokenConverter#setSigningKey(String)
|
||||
* @see JwtAccessTokenConverter#setVerifierKey(String)
|
||||
*/
|
||||
public interface JwtAccessTokenConverterRestTemplateCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the {@code template} before it is initialized.
|
||||
* @param template the rest template
|
||||
*/
|
||||
void customize(RestTemplate template);
|
||||
|
||||
}
|
||||
@@ -76,6 +76,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Madhura Bhave
|
||||
* @author Eddú Meléndez
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Configuration
|
||||
@@ -245,16 +246,18 @@ public class ResourceServerTokenServicesConfiguration {
|
||||
@Conditional(JwtTokenCondition.class)
|
||||
protected static class JwtTokenServicesConfiguration {
|
||||
|
||||
private RestTemplate keyUriRestTemplate = new RestTemplate();
|
||||
|
||||
private final ResourceServerProperties resource;
|
||||
|
||||
private final List<JwtAccessTokenConverterConfigurer> configurers;
|
||||
|
||||
private final List<JwtAccessTokenConverterRestTemplateCustomizer> customizers;
|
||||
|
||||
public JwtTokenServicesConfiguration(ResourceServerProperties resource,
|
||||
ObjectProvider<List<JwtAccessTokenConverterConfigurer>> configurers) {
|
||||
ObjectProvider<List<JwtAccessTokenConverterConfigurer>> configurers,
|
||||
ObjectProvider<List<JwtAccessTokenConverterRestTemplateCustomizer>> customizers) {
|
||||
this.resource = resource;
|
||||
this.configurers = configurers.getIfAvailable();
|
||||
this.customizers = customizers.getIfAvailable();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -299,6 +302,12 @@ public class ResourceServerTokenServicesConfiguration {
|
||||
}
|
||||
|
||||
private String getKeyFromServer() {
|
||||
RestTemplate keyUriRestTemplate = new RestTemplate();
|
||||
if (!CollectionUtils.isEmpty(this.customizers)) {
|
||||
for (JwtAccessTokenConverterRestTemplateCustomizer customizer : this.customizers) {
|
||||
customizer.customize(keyUriRestTemplate);
|
||||
}
|
||||
}
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String username = this.resource.getClientId();
|
||||
String password = this.resource.getClientSecret();
|
||||
@@ -308,7 +317,7 @@ public class ResourceServerTokenServicesConfiguration {
|
||||
}
|
||||
HttpEntity<Void> request = new HttpEntity<Void>(headers);
|
||||
String url = this.resource.getJwt().getKeyUri();
|
||||
return (String) this.keyUriRestTemplate
|
||||
return (String) keyUriRestTemplate
|
||||
.exchange(url, HttpMethod.GET, request, Map.class).getBody()
|
||||
.get("value");
|
||||
}
|
||||
|
||||
@@ -54,17 +54,22 @@ import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
import org.springframework.social.connect.ConnectionFactoryLocator;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourceServerTokenServicesConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Madhura Bhave
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class ResourceServerTokenServicesConfigurationTests {
|
||||
|
||||
@@ -240,6 +245,27 @@ public class ResourceServerTokenServicesConfigurationTests {
|
||||
.isInstanceOf(CustomUserInfoRestTemplateFactory.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jwtAccessTokenConverterIsConfiguredWhenKeyUriIsProvided() {
|
||||
EnvironmentTestUtils.addEnvironment(this.environment,
|
||||
"security.oauth2.resource.jwt.key-uri=http://localhost:12345/banana");
|
||||
this.context = new SpringApplicationBuilder(ResourceConfiguration.class)
|
||||
.environment(this.environment).web(false).run();
|
||||
assertThat(this.context.getBeansOfType(JwtAccessTokenConverter.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jwtAccessTokenConverterRestTemplateCanBeCustomized() {
|
||||
EnvironmentTestUtils.addEnvironment(this.environment,
|
||||
"security.oauth2.resource.jwt.key-uri=http://localhost:12345/banana");
|
||||
this.context = new SpringApplicationBuilder(ResourceConfiguration.class,
|
||||
JwtAccessTokenConverterRestTemplateCustomizerConfiguration.class)
|
||||
.environment(this.environment).web(false).run();
|
||||
JwtAccessTokenConverterRestTemplateCustomizer customizer = this.context
|
||||
.getBean(JwtAccessTokenConverterRestTemplateCustomizer.class);
|
||||
verify(customizer).customize(any(RestTemplate.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ ResourceServerTokenServicesConfiguration.class,
|
||||
ResourceServerPropertiesConfiguration.class,
|
||||
@@ -354,4 +380,14 @@ public class ResourceServerTokenServicesConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class JwtAccessTokenConverterRestTemplateCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
public JwtAccessTokenConverterRestTemplateCustomizer restTemplateCustomizer() {
|
||||
return mock(JwtAccessTokenConverterRestTemplateCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user