diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index d654a64b..015967f7 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -95,6 +95,19 @@ These links show up in the metadata that is consumed by clients, and used in some scenarios to decide whether to send requests to your application, so it's helpful if they are accurate. +=== Registering a Secure Application + +If your app wants to be contacted over HTTPS you can set two flags in +the `EurekaInstanceConfig`, _viz_ +`eureka.instance.[nonSecurePortEnabled,securePortEnabled]=[false,true]` +respectively. This will make Eureka publish instance information +showing an explicit preference for secure communication. The Spring +Cloud `DiscoveryClient` will always return an `https://...` URI for a +service configured this way, and the Eureka (native) instance +information will have a secure health check URL. Because of the way +Eureka works internally, it will still publish a non-secure URL for +status and home page unless you also override those explicitly. + === Eureka's Health Checks By default, Eureka uses the client heartbeat to determine if a client is up. diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java index 16767ab4..056f1bd5 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java @@ -16,9 +16,13 @@ package org.springframework.cloud.netflix.config; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.config.client.ConfigClientProperties; import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; @@ -48,6 +52,9 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration { @Autowired private ConfigClientProperties config; + @Autowired + private DiscoveryClient client; + @Autowired private EurekaClient eurekaClient; @@ -63,7 +70,7 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration { log.debug("Locating configserver via discovery"); InstanceInfo server = this.eurekaClient.getNextServerFromEureka( this.config.getDiscovery().getServiceId(), false); - String url = server.getHomePageUrl(); + String url = getHomePage(server); if (server.getMetadata().containsKey("password")) { String user = server.getMetadata().get("user"); user = user == null ? "user" : user; @@ -85,4 +92,13 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration { } } + private String getHomePage(InstanceInfo server) { + List instances = this.client + .getInstances(this.config.getDiscovery().getServiceId()); + if (instances == null || instances.isEmpty()) { + return server.getHomePageUrl(); + } + return instances.get(0).getUri().toString() + "/"; + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java index 9af10809..60b2985e 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java @@ -17,7 +17,6 @@ package org.springframework.cloud.netflix.eureka; import static com.netflix.appinfo.InstanceInfo.PortType.SECURE; -import static com.netflix.appinfo.InstanceInfo.PortType.UNSECURE; import java.net.URI; import java.util.ArrayList; @@ -113,8 +112,8 @@ public class EurekaDiscoveryClient implements DiscoveryClient { @Override public int getPort() { - // assume if unsecure is enabled, that is the default - if (this.instance.isPortEnabled(UNSECURE) || !this.instance.isPortEnabled(SECURE)) { + // assume if secure is enabled, that is the default + if (!this.instance.isPortEnabled(SECURE)) { return this.instance.getPort(); } return this.instance.getSecurePort(); @@ -122,8 +121,8 @@ public class EurekaDiscoveryClient implements DiscoveryClient { @Override public boolean isSecure() { - // assume if unsecure is enabled, that is the default - return !this.instance.isPortEnabled(UNSECURE) && this.instance.isPortEnabled(SECURE); + // assume if secure is enabled, that is the default + return this.instance.isPortEnabled(SECURE); } @Override diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java index 4581208c..1866febf 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java @@ -19,6 +19,8 @@ package org.springframework.cloud.netflix.config; import static org.junit.Assert.assertEquals; import static org.mockito.BDDMockito.given; +import java.util.Arrays; + import org.junit.After; import org.junit.Test; import org.mockito.Mockito; @@ -28,6 +30,7 @@ import org.springframework.cloud.config.client.ConfigClientProperties; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.netflix.appinfo.InstanceInfo; +import com.netflix.appinfo.InstanceInfo.PortType; import com.netflix.discovery.EurekaClient; /** @@ -75,6 +78,23 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests { assertEquals("http://foo:7001/", locator.getRawUri()); } + @Test + public void secureWhenRequested() throws Exception { + this.info = InstanceInfo.Builder.newBuilder().setAppName("app").setHostName("foo") + .setHomePageUrl("/", null).enablePort(PortType.SECURE, true).setSecurePort(443).build(); + given(this.client.getNextServerFromEureka("CONFIGSERVER", false)) + .willReturn(this.info); + given(this.client.getInstancesByVipAddress("CONFIGSERVER", false)) + .willReturn(Arrays.asList(this.info)); + setup("spring.cloud.config.discovery.enabled=true"); + assertEquals(1, this.context.getBeanNamesForType( + DiscoveryClientConfigServiceBootstrapConfiguration.class).length); + Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false); + ConfigClientProperties locator = this.context + .getBean(ConfigClientProperties.class); + assertEquals("https://foo:443/", locator.getRawUri()); + } + @Test public void setsPasssword() throws Exception { this.info.getMetadata().put("password", "bar");