diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 3a1c5cf089..1a2b27cf33 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -85,14 +85,35 @@ See {github-code}/spring-cloud-netflix-eureka-client/src/main/java/org/springfra To disable the Eureka Discovery Client you can set `eureka.client.enabled` to `false`. -=== Authenticating with the Eureka Server +=== Basic authentication with the Eureka Server HTTP basic authentication will be automatically added to your eureka client if one of the `eureka.client.serviceUrl.defaultZone` URLs has credentials embedded in it (curl style, like -`http://user:password@localhost:8761/eureka`). For more complex needs -you can create a `@Bean` of type `DiscoveryClientOptionalArgs` and -inject `ClientFilter` instances into it, all of which will be applied +`http://user:password@localhost:8761/eureka`). + +=== OAuth2 client support + +OAuth 2 support will be auto configured when `org.springframework.security.oauth:spring-security-oauth2` +is available in your classpath and you provide a `@Bean` of type `EurekaOAuth2ResourceDetails` within +your context. OAuth2 resource details can by configured with the following properties: + +.application.yml +---- + eureka: + client: + oauth2: + client_secret: client-secret + client_id: user + access_token_uri: oauth2-token-uri +---- + +IMPORTANT: OAuth2 client support is only supported with Rest Template. Jersey dependencies must be excluded. See <> for more information. + +=== Custom authentication + +For more complex needs you can create a `@Bean` of type `DiscoveryClientOptionalArgs` and +inject `ClientFilter` or `RestTemplace` instances into it, all of which will be applied to the calls from the client to the server. NOTE: Because of a limitation in Eureka it isn't possible to support diff --git a/pom.xml b/pom.xml index 8e4095007d..f0bc48305b 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,7 @@ 2.0.0.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT Elmhurst.BUILD-SNAPSHOT + 2.2.1.RELEASE 1.2.0.RELEASE @@ -119,6 +120,11 @@ pom import + + org.springframework.security.oauth + spring-security-oauth2 + ${spring-security-oauth2.version} + io.netty netty-codec-http diff --git a/spring-cloud-netflix-eureka-client/pom.xml b/spring-cloud-netflix-eureka-client/pom.xml index c6891838c6..95917dee43 100644 --- a/spring-cloud-netflix-eureka-client/pom.xml +++ b/spring-cloud-netflix-eureka-client/pom.xml @@ -111,6 +111,12 @@ ribbon-httpclient true + + org.springframework.security.oauth + spring-security-oauth2 + true + + org.springframework.boot spring-boot-starter-security diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/DiscoveryClientOptionalArgsConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/DiscoveryClientOptionalArgsConfiguration.java index d0439afb52..155eaf26cb 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/DiscoveryClientOptionalArgsConfiguration.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/DiscoveryClientOptionalArgsConfiguration.java @@ -16,12 +16,17 @@ package org.springframework.cloud.netflix.eureka.config; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.cloud.netflix.eureka.MutableDiscoveryClientOptionalArgs; +import org.springframework.cloud.netflix.eureka.http.BasicEurekaRestTemplateFactory; +import org.springframework.cloud.netflix.eureka.http.EurekaRestTemplateFactory; import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs; +import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories; +import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -31,12 +36,37 @@ * @author Daniel Lavoie */ @Configuration +@AutoConfigureAfter(EurekaOAuth2AutoConfiguration.class) public class DiscoveryClientOptionalArgsConfiguration { + + @Bean + @ConditionalOnMissingBean(value = EurekaRestTemplateFactory.class) + public EurekaRestTemplateFactory eurekaRestTemplateFactory() { + return new BasicEurekaRestTemplateFactory(); + } + + @Bean + @ConditionalOnMissingBean + public RestTemplateTransportClientFactory restTemplateTransportClientFactory( + EurekaRestTemplateFactory eurekaRestTemplateFactory) { + return new RestTemplateTransportClientFactory(eurekaRestTemplateFactory); + } + + @Bean + @ConditionalOnMissingBean + public RestTemplateTransportClientFactories restTemplateTransportClientFactories( + RestTemplateTransportClientFactory restTemplateTransportClientFactory) { + return new RestTemplateTransportClientFactories( + restTemplateTransportClientFactory); + } + @Bean @ConditionalOnMissingClass("com.sun.jersey.api.client.filter.ClientFilter") @ConditionalOnMissingBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT) - public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs() { - return new RestTemplateDiscoveryClientOptionalArgs(); + public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs( + RestTemplateTransportClientFactories restTemplateTransportClientFactories) { + return new RestTemplateDiscoveryClientOptionalArgs( + restTemplateTransportClientFactories); } @Bean diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/EurekaOAuth2AutoConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/EurekaOAuth2AutoConfiguration.java new file mode 100644 index 0000000000..8577ec2b51 --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/config/EurekaOAuth2AutoConfiguration.java @@ -0,0 +1,28 @@ +package org.springframework.cloud.netflix.eureka.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.netflix.eureka.http.EurekaRestTemplateFactory; +import org.springframework.cloud.netflix.eureka.http.oauth2.EurekaOAuth2ResourceDetails; +import org.springframework.cloud.netflix.eureka.http.oauth2.OAuth2EurekaRestTemplateFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; + +@Configuration +@ConditionalOnClass(BaseOAuth2ProtectedResourceDetails.class) +public class EurekaOAuth2AutoConfiguration { + @Bean + @ConditionalOnProperty("eureka.client.oauth2.client-id") + public EurekaOAuth2ResourceDetails eurekaOAuth2ResourceDetails() { + return new EurekaOAuth2ResourceDetails(); + } + + @Bean + @ConditionalOnBean(EurekaOAuth2ResourceDetails.class) + public EurekaRestTemplateFactory eurekaRestTemplateFactory( + EurekaOAuth2ResourceDetails eurekaOAuth2ResourceDetails) { + return new OAuth2EurekaRestTemplateFactory(eurekaOAuth2ResourceDetails); + } +} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/BasicEurekaRestTemplateFactory.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/BasicEurekaRestTemplateFactory.java new file mode 100644 index 0000000000..9b0396d9eb --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/BasicEurekaRestTemplateFactory.java @@ -0,0 +1,49 @@ +/* + * Copyright 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.cloud.netflix.eureka.http; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.client.support.BasicAuthorizationInterceptor; +import org.springframework.web.client.RestTemplate; + +/** + * @author Daniel Lavoie + */ +public class BasicEurekaRestTemplateFactory implements EurekaRestTemplateFactory { + @Override + public RestTemplate newRestTemplate(String serviceUrl) { + RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(); + try { + URI serviceURI = new URI(serviceUrl); + if (serviceURI.getUserInfo() != null) { + String[] credentials = serviceURI.getUserInfo().split(":"); + if (credentials.length == 2) { + restTemplateBuilder.interceptors(new BasicAuthorizationInterceptor( + credentials[0], credentials[1])); + } + } + } + catch (URISyntaxException ignore) { + + } + + return restTemplateBuilder.build(); + } +} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaRestTemplateFactory.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaRestTemplateFactory.java new file mode 100644 index 0000000000..7480b8197a --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/EurekaRestTemplateFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright 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.cloud.netflix.eureka.http; + +import org.springframework.web.client.RestTemplate; + +/** + * @author Daniel Lavoie + */ +public interface EurekaRestTemplateFactory { + RestTemplate newRestTemplate(String serviceUrl); +} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateDiscoveryClientOptionalArgs.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateDiscoveryClientOptionalArgs.java index b0eba96fdc..aa949c3209 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateDiscoveryClientOptionalArgs.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateDiscoveryClientOptionalArgs.java @@ -19,11 +19,14 @@ import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs; /** + * Eureka client extension that allows customization of the transport client. + * * @author Daniel Lavoie */ public class RestTemplateDiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs { - public RestTemplateDiscoveryClientOptionalArgs() { - setTransportClientFactories(new RestTemplateTransportClientFactories()); + public RestTemplateDiscoveryClientOptionalArgs( + RestTemplateTransportClientFactories restTemplateTransportClientFactories) { + setTransportClientFactories(restTemplateTransportClientFactories); } } diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java index 12f205b48c..634777e322 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java @@ -44,6 +44,8 @@ import com.netflix.discovery.util.StringUtil; /** + * {@link RestTemplate} based implementation of an {@link EurekaHttpClient}. + * * @author Daniel Lavoie */ public class RestTemplateEurekaHttpClient implements EurekaHttpClient { diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactories.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactories.java index d437703ba2..7da5529b27 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactories.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactories.java @@ -33,6 +33,12 @@ */ public class RestTemplateTransportClientFactories implements TransportClientFactories { + private final RestTemplateTransportClientFactory restTemplateTransportClientFactory; + + public RestTemplateTransportClientFactories( + RestTemplateTransportClientFactory restTemplateTransportClientFactory) { + this.restTemplateTransportClientFactory = restTemplateTransportClientFactory; + } @Override public TransportClientFactory newTransportClientFactory( @@ -44,15 +50,15 @@ public TransportClientFactory newTransportClientFactory( public TransportClientFactory newTransportClientFactory( EurekaClientConfig clientConfig, Collection additionalFilters, InstanceInfo myInstanceInfo) { - return new RestTemplateTransportClientFactory(); + return restTemplateTransportClientFactory; } @Override - public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig, - final Collection additionalFilters, - final InstanceInfo myInstanceInfo, - final Optional sslContext, - final Optional hostnameVerifier) { - return new RestTemplateTransportClientFactory(); + public TransportClientFactory newTransportClientFactory( + final EurekaClientConfig clientConfig, + final Collection additionalFilters, final InstanceInfo myInstanceInfo, + final Optional sslContext, + final Optional hostnameVerifier) { + return restTemplateTransportClientFactory; } } diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java index 9258a31162..f1821d5958 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java @@ -16,10 +16,6 @@ package org.springframework.cloud.netflix.eureka.http; -import java.net.URI; -import java.net.URISyntaxException; - -import org.springframework.http.client.support.BasicAuthorizationInterceptor; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; @@ -50,28 +46,22 @@ * @author Daniel Lavoie */ public class RestTemplateTransportClientFactory implements TransportClientFactory { + private EurekaRestTemplateFactory eurekaRestTemplateFactory; - @Override - public EurekaHttpClient newClient(EurekaEndpoint serviceUrl) { - return new RestTemplateEurekaHttpClient(restTemplate(serviceUrl.getServiceUrl()), - serviceUrl.getServiceUrl()); + public RestTemplateTransportClientFactory( + EurekaRestTemplateFactory eurekaRestTemplateFactory) { + this.eurekaRestTemplateFactory = eurekaRestTemplateFactory; } - private RestTemplate restTemplate(String serviceUrl) { - RestTemplate restTemplate = new RestTemplate(); - try { - URI serviceURI = new URI(serviceUrl); - if (serviceURI.getUserInfo() != null) { - String[] credentials = serviceURI.getUserInfo().split(":"); - if (credentials.length == 2) { - restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor( - credentials[0], credentials[1])); - } - } - } - catch (URISyntaxException ignore) { + @Override + public EurekaHttpClient newClient(EurekaEndpoint eurekaEndpoint) { + return new RestTemplateEurekaHttpClient( + newRestTemplate(eurekaEndpoint.getServiceUrl()), + eurekaEndpoint.getServiceUrl()); + } - } + private RestTemplate newRestTemplate(String serviceUrl) { + RestTemplate restTemplate = eurekaRestTemplateFactory.newRestTemplate(serviceUrl); restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter()); @@ -96,34 +86,34 @@ public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)); SimpleModule jsonModule = new SimpleModule(); - jsonModule.setSerializerModifier(createJsonSerializerModifier());//keyFormatter, compact)); + jsonModule.setSerializerModifier(createJsonSerializerModifier());// keyFormatter, + // compact)); converter.getObjectMapper().registerModule(jsonModule); converter.getObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true); converter.getObjectMapper().configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); - converter.getObjectMapper().addMixIn(Applications.class, ApplicationsJsonMixIn.class); - converter.getObjectMapper().addMixIn(InstanceInfo.class, InstanceInfoJsonMixIn.class); - - // converter.getObjectMapper().addMixIn(DataCenterInfo.class, DataCenterInfoXmlMixIn.class); - // converter.getObjectMapper().addMixIn(InstanceInfo.PortWrapper.class, PortWrapperXmlMixIn.class); - // converter.getObjectMapper().addMixIn(Application.class, ApplicationXmlMixIn.class); - // converter.getObjectMapper().addMixIn(Applications.class, ApplicationsXmlMixIn.class); - + converter.getObjectMapper().addMixIn(Applications.class, + ApplicationsJsonMixIn.class); + converter.getObjectMapper().addMixIn(InstanceInfo.class, + InstanceInfoJsonMixIn.class); return converter; } - public static BeanSerializerModifier createJsonSerializerModifier() {//final KeyFormatter keyFormatter, final boolean compactMode) { + public static BeanSerializerModifier createJsonSerializerModifier() { return new BeanSerializerModifier() { @Override public JsonSerializer modifySerializer(SerializationConfig config, - BeanDescription beanDesc, JsonSerializer serializer) { - /*if (beanDesc.getBeanClass().isAssignableFrom(Applications.class)) { - return new ApplicationsJsonBeanSerializer((BeanSerializerBase) serializer, keyFormatter); - }*/ + BeanDescription beanDesc, JsonSerializer serializer) { + /* + * if (beanDesc.getBeanClass().isAssignableFrom(Applications.class)) { + * return new ApplicationsJsonBeanSerializer((BeanSerializerBase) + * serializer, keyFormatter); } + */ if (beanDesc.getBeanClass().isAssignableFrom(InstanceInfo.class)) { - return new InstanceInfoJsonBeanSerializer((BeanSerializerBase) serializer, false); + return new InstanceInfoJsonBeanSerializer( + (BeanSerializerBase) serializer, false); } return serializer; } diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/oauth2/EurekaOAuth2ResourceDetails.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/oauth2/EurekaOAuth2ResourceDetails.java new file mode 100644 index 0000000000..5d02d015f4 --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/oauth2/EurekaOAuth2ResourceDetails.java @@ -0,0 +1,30 @@ +/* + * Copyright 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.cloud.netflix.eureka.http.oauth2; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; + +/** + * Configuration Properties to define OAuth2 resource details for the Eureka Client + * + * @author Daniel Lavoie + */ +@ConfigurationProperties("eureka.client.oauth2") +public class EurekaOAuth2ResourceDetails extends ClientCredentialsResourceDetails { + +} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/oauth2/OAuth2EurekaRestTemplateFactory.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/oauth2/OAuth2EurekaRestTemplateFactory.java new file mode 100644 index 0000000000..b5e96d735a --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/oauth2/OAuth2EurekaRestTemplateFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright 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.cloud.netflix.eureka.http.oauth2; + +import org.springframework.cloud.netflix.eureka.http.EurekaRestTemplateFactory; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.web.client.RestTemplate; + +/** + * @author Daniel Lavoie + */ +public class OAuth2EurekaRestTemplateFactory implements EurekaRestTemplateFactory { + private final EurekaOAuth2ResourceDetails eurekaOAuth2ResourceDetails; + + public OAuth2EurekaRestTemplateFactory( + EurekaOAuth2ResourceDetails eurekaOAuth2ResourceDetails) { + this.eurekaOAuth2ResourceDetails = eurekaOAuth2ResourceDetails; + } + + @Override + public RestTemplate newRestTemplate(String serviceUrl) { + return new OAuth2RestTemplate(eurekaOAuth2ResourceDetails); + } +} diff --git a/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories index e8c7702551..6f8da02eb8 100644 --- a/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories @@ -1,6 +1,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,\ org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,\ +org.springframework.cloud.netflix.eureka.config.EurekaOAuth2AutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\ org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/EurekaOAuth2AutoConfigurationTest.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/EurekaOAuth2AutoConfigurationTest.java new file mode 100644 index 0000000000..8369c85aeb --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/EurekaOAuth2AutoConfigurationTest.java @@ -0,0 +1,31 @@ +package org.springframework.cloud.netflix.eureka.config; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.cloud.netflix.eureka.http.oauth2.EurekaOAuth2ResourceDetails; +import org.springframework.cloud.netflix.eureka.http.oauth2.OAuth2EurekaRestTemplateFactory; +import org.springframework.cloud.netflix.eureka.sample.EurekaSampleApplication; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = EurekaSampleApplication.class, properties = { + "spring.profiles.active=oauth2" }, webEnvironment = WebEnvironment.RANDOM_PORT) +@DirtiesContext +public class EurekaOAuth2AutoConfigurationTest { + @Autowired + private OAuth2EurekaRestTemplateFactory eurekaRestTemplateFactory; + + @Autowired + private EurekaOAuth2ResourceDetails resourceDetails; + + @Test + public void contextLoads() { + Assert.assertNotNull(eurekaRestTemplateFactory); + Assert.assertNotNull(resourceDetails); + } +} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/EurekaServerMockApplication.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/EurekaServerMockApplication.java index 2c9cbb3668..35105db971 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/EurekaServerMockApplication.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/EurekaServerMockApplication.java @@ -65,8 +65,9 @@ public class EurekaServerMockApplication { */ @Bean public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() { - return new RestTemplateTransportClientFactory() - .mappingJacksonHttpMessageConverter(); + return new RestTemplateTransportClientFactory( + new BasicEurekaRestTemplateFactory()) + .mappingJacksonHttpMessageConverter(); } @ResponseStatus(HttpStatus.OK) @@ -75,7 +76,8 @@ public void register(@PathVariable String appName, @RequestBody InstanceInfo instanceInfo) { isTrue(instanceInfo.getPort() != DEFAULT_PORT && instanceInfo.getPort() != 0, "Port not received from client"); - isTrue(instanceInfo.getSecurePort() != DEFAULT_SECURE_PORT && instanceInfo.getSecurePort() != 0, + isTrue(instanceInfo.getSecurePort() != DEFAULT_SECURE_PORT + && instanceInfo.getSecurePort() != 0, "Secure Port not received from client"); // Nothing to do } @@ -132,8 +134,8 @@ public InstanceInfo getInstance(@PathVariable(required = false) String appName, @Configuration @Order(Ordered.HIGHEST_PRECEDENCE) - protected static class TestSecurityConfiguration extends WebSecurityConfigurerAdapter { - + protected static class TestSecurityConfiguration + extends WebSecurityConfigurerAdapter { TestSecurityConfiguration() { super(true); @@ -142,15 +144,15 @@ protected static class TestSecurityConfiguration extends WebSecurityConfigurerAd @Bean public UserDetailsService userDetailsService() { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withUsername("test").password("{noop}test").roles("USER").build()); + manager.createUser(User.withUsername("test").password("{noop}test") + .roles("USER").build()); return manager; } @Override protected void configure(HttpSecurity http) throws Exception { // super.configure(http); - http.antMatcher("/apps/**") - .httpBasic(); + http.antMatcher("/apps/**").httpBasic(); } } diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClientTest.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClientTest.java index 4545d62cbb..b42efa8a3b 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClientTest.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClientTest.java @@ -55,8 +55,9 @@ public class RestTemplateEurekaHttpClientTest { @Before public void setup() { - eurekaHttpClient = new RestTemplateTransportClientFactory() - .newClient(new DefaultEndpoint(serviceUrl)); + eurekaHttpClient = new RestTemplateTransportClientFactory( + new BasicEurekaRestTemplateFactory()) + .newClient(new DefaultEndpoint(serviceUrl)); EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils); diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoriesTest.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoriesTest.java index 88d02636ea..c8cf4cfd98 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoriesTest.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoriesTest.java @@ -24,6 +24,8 @@ public class RestTemplateTransportClientFactoriesTest { @Test(expected = UnsupportedOperationException.class) public void testJerseyIsUnsuported() { - new RestTemplateTransportClientFactories().newTransportClientFactory(null, null); + new RestTemplateTransportClientFactories(new RestTemplateTransportClientFactory( + new BasicEurekaRestTemplateFactory())) + .newTransportClientFactory(null, null); } } diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTest.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTest.java index 50de78aec8..e5f30319b2 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTest.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTest.java @@ -30,7 +30,8 @@ public class RestTemplateTransportClientFactoryTest { @Before public void setup() { - transportClientFatory = new RestTemplateTransportClientFactory(); + transportClientFatory = new RestTemplateTransportClientFactory( + new BasicEurekaRestTemplateFactory()); } @Test diff --git a/spring-cloud-netflix-eureka-client/src/test/resources/application-oauth2.yml b/spring-cloud-netflix-eureka-client/src/test/resources/application-oauth2.yml new file mode 100644 index 0000000000..2335e56b03 --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/test/resources/application-oauth2.yml @@ -0,0 +1,5 @@ +eureka: + client: + oauth2: + client_secret: client-secret + client_id: client-id \ No newline at end of file