Skip to content

Commit 836e6fd

Browse files
committed
feat: Add initial implementation for oauth2 support in the spring cloud config client
Signed-off-by: prafsoni <prafsoni@gmail.com>
1 parent d4510f2 commit 836e6fd

3 files changed

Lines changed: 132 additions & 3 deletions

File tree

spring-cloud-config-client/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
<artifactId>spring-boot-starter-actuator</artifactId>
5959
<optional>true</optional>
6060
</dependency>
61+
<dependency>
62+
<groupId>org.springframework.boot</groupId>
63+
<artifactId>spring-boot-starter-security-oauth2-client</artifactId>
64+
</dependency>
6165
<dependency>
6266
<groupId>org.springframework.boot</groupId>
6367
<artifactId>spring-boot-starter-aspectj</artifactId>

spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.beans.BeanUtils;
2929
import org.springframework.beans.factory.annotation.Value;
3030
import org.springframework.boot.context.properties.ConfigurationProperties;
31+
import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties;
3132
import org.springframework.cloud.config.environment.EnvironmentMediaType;
3233
import org.springframework.cloud.configuration.TlsProperties;
3334
import org.springframework.core.env.Environment;
@@ -185,6 +186,8 @@ public class ConfigClientProperties {
185186
*/
186187
private boolean sendAllLabels = false;
187188

189+
private OAuth2Properties oauth2 = new OAuth2Properties();
190+
188191
ConfigClientProperties() {
189192
}
190193

@@ -352,6 +355,14 @@ public void setSendAllLabels(boolean sendAllLabels) {
352355
this.sendAllLabels = sendAllLabels;
353356
}
354357

358+
public OAuth2Properties getOauth2() {
359+
return oauth2;
360+
}
361+
362+
public void setOauth2(OAuth2Properties oauth2) {
363+
this.oauth2 = oauth2;
364+
}
365+
355366
private Credentials extractCredentials(int index) {
356367
Credentials result = new Credentials();
357368
int noOfUrl = this.uri.length;
@@ -441,7 +452,8 @@ public String toString() {
441452
+ Arrays.toString(this.uri) + ", mediaType=" + this.mediaType + ", discovery=" + this.discovery
442453
+ ", failFast=" + this.failFast + ", token=" + this.token + ", requestConnectTimeout="
443454
+ this.requestConnectTimeout + ", requestReadTimeout=" + this.requestReadTimeout + ", sendState="
444-
+ this.sendState + ", headers=" + this.headers + ", sendAllLabels=" + this.sendAllLabels + "]";
455+
+ this.sendState + ", headers=" + this.headers + ", sendAllLabels=" + this.sendAllLabels + ", oauth2"
456+
+ this.oauth2 + "]";
445457
}
446458

447459
/**
@@ -526,4 +538,52 @@ public enum MultipleUriStrategy {
526538

527539
}
528540

541+
public static class OAuth2Properties {
542+
543+
/**
544+
* Default client registration id.
545+
*/
546+
public static final String CLIENT_REGISTRATION_ID = "config-oauth2-client";
547+
548+
/**
549+
* Flag to say that the remote configuration server is configured with OAuth2.
550+
* Default false.;
551+
*/
552+
private boolean enabled = false;
553+
554+
private OAuth2ClientProperties.Provider provider = new OAuth2ClientProperties.Provider();
555+
556+
private OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration();
557+
558+
public boolean isEnabled() {
559+
return enabled;
560+
}
561+
562+
public void setEnabled(boolean enabled) {
563+
this.enabled = enabled;
564+
}
565+
566+
public OAuth2ClientProperties.Provider getProvider() {
567+
return provider;
568+
}
569+
570+
public void setProvider(OAuth2ClientProperties.Provider provider) {
571+
this.provider = provider;
572+
}
573+
574+
public OAuth2ClientProperties.Registration getRegistration() {
575+
return registration;
576+
}
577+
578+
public void setRegistration(OAuth2ClientProperties.Registration registration) {
579+
this.registration = registration;
580+
}
581+
582+
@Override
583+
public String toString() {
584+
return "OAuth2Properties [" + "enabled=" + enabled + "]";
585+
}
586+
587+
}
588+
529589
}

spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientRequestTemplateFactory.java

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818

1919
import java.io.IOException;
2020
import java.security.GeneralSecurityException;
21-
import java.util.Arrays;
21+
import java.util.ArrayList;
2222
import java.util.Base64;
2323
import java.util.HashMap;
24+
import java.util.List;
2425
import java.util.Map;
2526
import java.util.concurrent.TimeUnit;
2627

@@ -35,6 +36,8 @@
3536
import org.apache.hc.core5.http.io.SocketConfig;
3637
import org.apache.hc.core5.util.Timeout;
3738

39+
import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties;
40+
import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientPropertiesMapper;
3841
import org.springframework.cloud.configuration.SSLContextFactory;
3942
import org.springframework.http.HttpHeaders;
4043
import org.springframework.http.HttpRequest;
@@ -44,6 +47,16 @@
4447
import org.springframework.http.client.ClientHttpResponse;
4548
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
4649
import org.springframework.http.client.SimpleClientHttpRequestFactory;
50+
import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager;
51+
import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
52+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
53+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
54+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
55+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
56+
import org.springframework.security.oauth2.client.registration.ClientRegistration;
57+
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
58+
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
59+
import org.springframework.security.oauth2.client.web.client.OAuth2ClientHttpRequestInterceptor;
4760
import org.springframework.web.client.RestTemplate;
4861

4962
import static org.springframework.cloud.config.client.ConfigClientProperties.AUTHORIZATION;
@@ -77,15 +90,67 @@ public RestTemplate create() {
7790

7891
ClientHttpRequestFactory requestFactory = createHttpRequestFactory(properties);
7992
RestTemplate template = new RestTemplate(requestFactory);
93+
94+
final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
8095
Map<String, String> headers = new HashMap<>(properties.getHeaders());
8196
headers.remove(AUTHORIZATION); // To avoid redundant addition of header
8297
if (!headers.isEmpty()) {
83-
template.setInterceptors(Arrays.asList(new GenericRequestHeaderInterceptor(headers)));
98+
interceptors.add(new GenericRequestHeaderInterceptor(headers));
99+
}
100+
101+
if (properties.getOauth2().isEnabled()) {
102+
ClientHttpRequestInterceptor oauth2Interceptor = createOauth2Interceptor(properties.getOauth2());
103+
interceptors.add(oauth2Interceptor);
84104
}
105+
template.setInterceptors(interceptors);
85106

86107
return template;
87108
}
88109

110+
private ClientHttpRequestInterceptor createOauth2Interceptor(ConfigClientProperties.OAuth2Properties properties) {
111+
final OAuth2AuthorizedClientManager authorizedClientManager = createAuthorizedClientManager(properties);
112+
OAuth2ClientHttpRequestInterceptor oauth2Interceptor = new OAuth2ClientHttpRequestInterceptor(
113+
authorizedClientManager);
114+
oauth2Interceptor
115+
.setClientRegistrationIdResolver(request -> ConfigClientProperties.OAuth2Properties.CLIENT_REGISTRATION_ID);
116+
return oauth2Interceptor;
117+
}
118+
119+
private OAuth2AuthorizedClientManager createAuthorizedClientManager(
120+
ConfigClientProperties.OAuth2Properties properties) {
121+
122+
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
123+
.clientCredentials()
124+
.refreshToken()
125+
.build();
126+
127+
ClientRegistrationRepository clientRegistrationRepository = clientRegistrationRepository(properties);
128+
129+
OAuth2AuthorizedClientService authorizedClientService = new InMemoryOAuth2AuthorizedClientService(
130+
clientRegistrationRepository);
131+
132+
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(
133+
clientRegistrationRepository, authorizedClientService);
134+
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
135+
return authorizedClientManager;
136+
}
137+
138+
private ClientRegistrationRepository clientRegistrationRepository(
139+
ConfigClientProperties.OAuth2Properties properties) {
140+
OAuth2ClientProperties oauth2ClientProperties = new OAuth2ClientProperties();
141+
properties.getRegistration().setProvider(null); // In case it was set in config
142+
// properties
143+
oauth2ClientProperties.getRegistration()
144+
.put(ConfigClientProperties.OAuth2Properties.CLIENT_REGISTRATION_ID, properties.getRegistration());
145+
oauth2ClientProperties.getProvider()
146+
.put(ConfigClientProperties.OAuth2Properties.CLIENT_REGISTRATION_ID, properties.getProvider());
147+
oauth2ClientProperties.afterPropertiesSet();
148+
149+
List<ClientRegistration> registrations = new ArrayList<>(
150+
new OAuth2ClientPropertiesMapper(oauth2ClientProperties).asClientRegistrations().values());
151+
return new InMemoryClientRegistrationRepository(registrations);
152+
}
153+
89154
protected ClientHttpRequestFactory createHttpRequestFactory(ConfigClientProperties client) {
90155
if (client.getTls().isEnabled()) {
91156
try {

0 commit comments

Comments
 (0)