Skip to content

Commit 0ec372b

Browse files
committed
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
2 parents 1d9520b + 9e9f006 commit 0ec372b

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.security.oauth2.resource;
18+
19+
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
20+
import org.springframework.web.client.RestTemplate;
21+
22+
/**
23+
* Callback for customizing the {@link RestTemplate} that is used to fetch the keys used
24+
* by {@link JwtAccessTokenConverter}.
25+
*
26+
* @author Eddú Meléndez
27+
* @since 1.5.2
28+
* @see JwtAccessTokenConverter#setSigningKey(String)
29+
* @see JwtAccessTokenConverter#setVerifierKey(String)
30+
*/
31+
public interface JwtAccessTokenConverterRestTemplateCustomizer {
32+
33+
/**
34+
* Customize the {@code template} before it is initialized.
35+
* @param template the rest template
36+
*/
37+
void customize(RestTemplate template);
38+
39+
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfiguration.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
*
7777
* @author Dave Syer
7878
* @author Madhura Bhave
79+
* @author Eddú Meléndez
7980
* @since 1.3.0
8081
*/
8182
@Configuration
@@ -245,16 +246,18 @@ public TokenStore jwkTokenStore() {
245246
@Conditional(JwtTokenCondition.class)
246247
protected static class JwtTokenServicesConfiguration {
247248

248-
private RestTemplate keyUriRestTemplate = new RestTemplate();
249-
250249
private final ResourceServerProperties resource;
251250

252251
private final List<JwtAccessTokenConverterConfigurer> configurers;
253252

253+
private final List<JwtAccessTokenConverterRestTemplateCustomizer> customizers;
254+
254255
public JwtTokenServicesConfiguration(ResourceServerProperties resource,
255-
ObjectProvider<List<JwtAccessTokenConverterConfigurer>> configurers) {
256+
ObjectProvider<List<JwtAccessTokenConverterConfigurer>> configurers,
257+
ObjectProvider<List<JwtAccessTokenConverterRestTemplateCustomizer>> customizers) {
256258
this.resource = resource;
257259
this.configurers = configurers.getIfAvailable();
260+
this.customizers = customizers.getIfAvailable();
258261
}
259262

260263
@Bean
@@ -299,6 +302,12 @@ public JwtAccessTokenConverter jwtTokenEnhancer() {
299302
}
300303

301304
private String getKeyFromServer() {
305+
RestTemplate keyUriRestTemplate = new RestTemplate();
306+
if (!CollectionUtils.isEmpty(this.customizers)) {
307+
for (JwtAccessTokenConverterRestTemplateCustomizer customizer : this.customizers) {
308+
customizer.customize(keyUriRestTemplate);
309+
}
310+
}
302311
HttpHeaders headers = new HttpHeaders();
303312
String username = this.resource.getClientId();
304313
String password = this.resource.getClientSecret();
@@ -308,7 +317,7 @@ private String getKeyFromServer() {
308317
}
309318
HttpEntity<Void> request = new HttpEntity<Void>(headers);
310319
String url = this.resource.getJwt().getKeyUri();
311-
return (String) this.keyUriRestTemplate
320+
return (String) keyUriRestTemplate
312321
.exchange(url, HttpMethod.GET, request, Map.class).getBody()
313322
.get("value");
314323
}

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfigurationTests.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,22 @@
5454
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
5555
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
5656
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
57+
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
5758
import org.springframework.social.connect.ConnectionFactoryLocator;
5859
import org.springframework.stereotype.Component;
60+
import org.springframework.web.client.RestTemplate;
5961

6062
import static org.assertj.core.api.Assertions.assertThat;
63+
import static org.mockito.Matchers.any;
6164
import static org.mockito.Mockito.mock;
65+
import static org.mockito.Mockito.verify;
6266

6367
/**
6468
* Tests for {@link ResourceServerTokenServicesConfiguration}.
6569
*
6670
* @author Dave Syer
6771
* @author Madhura Bhave
72+
* @author Eddú Meléndez
6873
*/
6974
public class ResourceServerTokenServicesConfigurationTests {
7075

@@ -240,6 +245,27 @@ public void customUserInfoRestTemplateFactory() {
240245
.isInstanceOf(CustomUserInfoRestTemplateFactory.class);
241246
}
242247

248+
@Test
249+
public void jwtAccessTokenConverterIsConfiguredWhenKeyUriIsProvided() {
250+
EnvironmentTestUtils.addEnvironment(this.environment,
251+
"security.oauth2.resource.jwt.key-uri=http://localhost:12345/banana");
252+
this.context = new SpringApplicationBuilder(ResourceConfiguration.class)
253+
.environment(this.environment).web(false).run();
254+
assertThat(this.context.getBeansOfType(JwtAccessTokenConverter.class)).hasSize(1);
255+
}
256+
257+
@Test
258+
public void jwtAccessTokenConverterRestTemplateCanBeCustomized() {
259+
EnvironmentTestUtils.addEnvironment(this.environment,
260+
"security.oauth2.resource.jwt.key-uri=http://localhost:12345/banana");
261+
this.context = new SpringApplicationBuilder(ResourceConfiguration.class,
262+
JwtAccessTokenConverterRestTemplateCustomizerConfiguration.class)
263+
.environment(this.environment).web(false).run();
264+
JwtAccessTokenConverterRestTemplateCustomizer customizer = this.context
265+
.getBean(JwtAccessTokenConverterRestTemplateCustomizer.class);
266+
verify(customizer).customize(any(RestTemplate.class));
267+
}
268+
243269
@Configuration
244270
@Import({ ResourceServerTokenServicesConfiguration.class,
245271
ResourceServerPropertiesConfiguration.class,
@@ -354,4 +380,14 @@ public OAuth2RestTemplate getUserInfoRestTemplate() {
354380

355381
}
356382

383+
@Configuration
384+
static class JwtAccessTokenConverterRestTemplateCustomizerConfiguration {
385+
386+
@Bean
387+
public JwtAccessTokenConverterRestTemplateCustomizer restTemplateCustomizer() {
388+
return mock(JwtAccessTokenConverterRestTemplateCustomizer.class);
389+
}
390+
391+
}
392+
357393
}

0 commit comments

Comments
 (0)