diff --git a/pom.xml b/pom.xml
index f86382b13..9552cc9c0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,19 +44,6 @@
HEAD
-
- spring-cloud-sleuth-dependencies
- spring-cloud-sleuth-api
- spring-cloud-sleuth-instrumentation
- spring-cloud-sleuth-brave
- spring-cloud-sleuth-autoconfigure
- tests
- spring-cloud-sleuth-zipkin
- spring-cloud-starter-sleuth
- spring-cloud-sleuth-samples
- docs
-
-
1.8
1.8
@@ -75,9 +62,9 @@
2.5.1
5.13.9
0.32.0
+
2.3.4.RELEASE
2.2.0.RELEASE
- 5.6.0
false
4.9.0
4.8.0
@@ -103,6 +90,19 @@
3.2.0
+
+ spring-cloud-sleuth-dependencies
+ spring-cloud-sleuth-api
+ spring-cloud-sleuth-instrumentation
+ spring-cloud-sleuth-brave
+ spring-cloud-sleuth-autoconfigure
+ tests
+ spring-cloud-sleuth-zipkin
+ spring-cloud-starter-sleuth
+ spring-cloud-sleuth-samples
+ docs
+
+
@@ -270,13 +270,6 @@
import
pom
-
- org.springframework.security
- spring-security-bom
- ${spring-security-version}
- pom
- import
-
org.springframework.security.oauth.boot
spring-security-oauth2-autoconfigure
diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml
index e9dbc5c48..4cd770321 100644
--- a/spring-cloud-sleuth-autoconfigure/pom.xml
+++ b/spring-cloud-sleuth-autoconfigure/pom.xml
@@ -192,6 +192,11 @@
spring-security-oauth2-autoconfigure
true
+
+ org.springframework.security
+ spring-security-oauth2-client
+ true
+
org.springframework.vault
spring-vault-core
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java
index 507d87116..4a79a10a6 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java
@@ -18,8 +18,10 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.web.client;
import reactor.netty.http.client.HttpClient;
+import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
+import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -36,6 +38,7 @@ import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.http.HttpClientHandler;
import org.springframework.cloud.sleuth.instrument.web.client.HttpClientBeanPostProcessor;
import org.springframework.cloud.sleuth.instrument.web.client.LazyTraceClientHttpRequestInterceptor;
+import org.springframework.cloud.sleuth.instrument.web.client.TraceDefaultOAuth2UserServiceCustomizer;
import org.springframework.cloud.sleuth.instrument.web.client.TraceRequestHttpHeadersFilter;
import org.springframework.cloud.sleuth.instrument.web.client.TraceResponseHttpHeadersFilter;
import org.springframework.cloud.sleuth.instrument.web.client.TraceRestTemplateBeanPostProcessor;
@@ -51,6 +54,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
+import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
@@ -167,6 +171,7 @@ class TraceWebClientAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ UserInfoRestTemplateCustomizer.class, OAuth2RestTemplate.class })
+ @Deprecated // Use Spring-Security OAuth2 support
protected static class TraceOAuthConfiguration {
@Bean
@@ -183,4 +188,24 @@ class TraceWebClientAutoConfiguration {
}
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(DefaultOAuth2UserService.class)
+ protected static class TraceSpringSecurityOAuth2Configuration {
+
+ @Bean
+ static BeanPostProcessor traceDefaultOAuth2UserServiceBeanPostProcessor(BeanFactory beanFactory) {
+ return new BeanPostProcessor() {
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof DefaultOAuth2UserService) {
+ new TraceDefaultOAuth2UserServiceCustomizer(beanFactory)
+ .customize((DefaultOAuth2UserService) bean);
+ }
+ return bean;
+ }
+ };
+ }
+
+ }
+
}
diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml
index cb6429c80..e30a07dbd 100644
--- a/spring-cloud-sleuth-instrumentation/pom.xml
+++ b/spring-cloud-sleuth-instrumentation/pom.xml
@@ -31,7 +31,7 @@
3.1.4-SNAPSHOT
..
-
+
@@ -220,6 +220,11 @@
spring-security-oauth2-autoconfigure
true
+
+ org.springframework.security
+ spring-security-oauth2-client
+ true
+
org.springframework.session
spring-session-data-redis
diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceDefaultOAuth2UserServiceCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceDefaultOAuth2UserServiceCustomizer.java
new file mode 100644
index 000000000..336dbbd06
--- /dev/null
+++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceDefaultOAuth2UserServiceCustomizer.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2013-2021 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
+ *
+ * https://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.cloud.sleuth.instrument.web.client;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.cloud.sleuth.instrument.web.mvc.TracingClientHttpRequestInterceptor;
+import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.web.client.RestOperations;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Customizes a {@link DefaultOAuth2UserService} by providing it with a trace interceptor.
+ *
+ * @author Marcin Grzejszczak
+ * @since 3.0.6
+ */
+public class TraceDefaultOAuth2UserServiceCustomizer {
+
+ private static final Log log = LogFactory.getLog(TraceDefaultOAuth2UserServiceCustomizer.class);
+
+ private final BeanFactory beanFactory;
+
+ private static final Field REST_OPERATIONS = ReflectionUtils.findField(DefaultOAuth2UserService.class,
+ "restOperations", RestOperations.class);
+
+ public TraceDefaultOAuth2UserServiceCustomizer(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+ public void customize(DefaultOAuth2UserService service) {
+ try {
+ ReflectionUtils.makeAccessible(Objects.requireNonNull(REST_OPERATIONS,
+ "restOperations field was not found in [DefaultOAuth2UserService] class"));
+ RestOperations restOperations = (RestOperations) REST_OPERATIONS.get(service);
+ if (!(restOperations instanceof RestTemplate)) {
+ log.warn(
+ "Won't instrument the restOperations field in [DefaultOAuth2UserService] class because it's not a RestTemplate object");
+ return;
+ }
+ RestTemplate template = (RestTemplate) restOperations;
+ final TracingClientHttpRequestInterceptor interceptor = this.beanFactory
+ .getBean(TracingClientHttpRequestInterceptor.class);
+ new RestTemplateInterceptorInjector(interceptor).inject(template);
+ }
+ catch (Exception e) {
+ log.warn("Can't access the restOperations field - won't instrument the [DefaultOAuth2UserService] class",
+ e);
+ }
+ }
+
+}
diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceDefaultOAuth2UserServiceCustomizerTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceDefaultOAuth2UserServiceCustomizerTests.java
new file mode 100644
index 000000000..e5b020bdc
--- /dev/null
+++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceDefaultOAuth2UserServiceCustomizerTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2013-2021 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
+ *
+ * https://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.cloud.sleuth.instrument.web.client;
+
+import org.assertj.core.api.BDDAssertions;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
+import org.springframework.cloud.sleuth.instrument.web.mvc.TracingClientHttpRequestInterceptor;
+import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.web.client.RestTemplate;
+
+class TraceDefaultOAuth2UserServiceCustomizerTests {
+
+ @Test
+ void should_add_a_trace_interceptor_to_defaultoauth2userservice() {
+ DefaultOAuth2UserService service = new DefaultOAuth2UserService();
+ BeanFactory beanFactory = beanFactory();
+ TraceDefaultOAuth2UserServiceCustomizer serviceCustomizer = new TraceDefaultOAuth2UserServiceCustomizer(
+ beanFactory);
+
+ serviceCustomizer.customize(service);
+ serviceCustomizer.customize(service);
+
+ Object operations = ReflectionUtils
+ .getField(ReflectionUtils.findField(DefaultOAuth2UserService.class, "restOperations"), service);
+ BDDAssertions.then(operations).isInstanceOf(RestTemplate.class);
+ RestTemplate restTemplate = (RestTemplate) operations;
+ BDDAssertions.then(restTemplate.getInterceptors()).hasSize(1)
+ .hasOnlyElementsOfType(TracingClientHttpRequestInterceptor.class);
+ }
+
+ private BeanFactory beanFactory() {
+ StaticListableBeanFactory beanFactory = new StaticListableBeanFactory();
+ beanFactory.addBean("TracingClientHttpRequestInterceptor",
+ TracingClientHttpRequestInterceptor.create(null, null));
+ return beanFactory;
+ }
+
+}