EndpointRequest should match @ServletEndpoint
This commit also changes the request matcher for MVC endpoints to use an AntPathRequestMatcher instead of an MvcRequestMatcher. The endpoint is always available under the mapped endpoint path and this way the same matcher can be used for both MVC and Jersey. Fixes gh-17912 Co-authored-by: Phillip Webb <pwebb@pivotal.io>pull/18464/head
parent
21302df854
commit
674f2f5a6c
27
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityRequestMatcherProviderAutoConfiguration.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfiguration.java
27
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityRequestMatcherProviderAutoConfiguration.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfiguration.java
58
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityRequestMatcherProviderAutoConfigurationTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java
58
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityRequestMatcherProviderAutoConfigurationTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java
21
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/MvcRequestMatcherProvider.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/AntPathRequestMatcherProvider.java
21
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/MvcRequestMatcherProvider.java → spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/AntPathRequestMatcherProvider.java
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.actuator.customsecurity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Abstract base class for actuator tests with custom security.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public abstract class AbstractSampleActuatorCustomSecurityTests {
|
||||
|
||||
abstract String getPath();
|
||||
|
||||
abstract String getManagementPath();
|
||||
|
||||
abstract Environment getEnvironment();
|
||||
|
||||
@Test
|
||||
public void homeIsSecure() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = restTemplate().getForEntity(getPath() + "/", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
assertThat(body.get("error")).isEqualTo("Unauthorized");
|
||||
assertThat(entity.getHeaders()).doesNotContainKey("Set-Cookie");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsecureStaticResources() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getPath() + "/css/bootstrap.min.css", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("body");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorInsecureEndpoint() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health/diskSpace", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorLinksWithAnonymous() {
|
||||
ResponseEntity<Object> entity = restTemplate().getForEntity(getManagementPath() + "/actuator", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorLinksWithUnauthorizedUser() {
|
||||
ResponseEntity<Object> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator",
|
||||
Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorLinksWithAuthorizedUser() {
|
||||
ResponseEntity<Object> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator",
|
||||
Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
adminRestTemplate().getForEntity(getManagementPath() + "/actuator/", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSecureEndpointWithAnonymous() {
|
||||
ResponseEntity<Object> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSecureEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<Object> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSecureEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<Object> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
entity = adminRestTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureServletEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity("/actuator/jolokia", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureServletEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureServletEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorCustomMvcSecureEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate()
|
||||
.getForEntity(getManagementPath() + "/actuator/example/echo?text={t}", String.class, "test");
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorCustomMvcSecureEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate()
|
||||
.getForEntity(getManagementPath() + "/actuator/example/echo?text={t}", String.class, "test");
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorCustomMvcSecureEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate()
|
||||
.getForEntity(getManagementPath() + "/actuator/example/echo?text={t}", String.class, "test");
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).isEqualTo("test");
|
||||
assertThat(entity.getHeaders().getFirst("echo")).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorExcludedFromEndpointRequestMatcher() {
|
||||
ResponseEntity<Object> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/mappings",
|
||||
Object.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
TestRestTemplate restTemplate() {
|
||||
return configure(new TestRestTemplate());
|
||||
}
|
||||
|
||||
TestRestTemplate adminRestTemplate() {
|
||||
return configure(new TestRestTemplate("admin", "admin"));
|
||||
}
|
||||
|
||||
TestRestTemplate userRestTemplate() {
|
||||
return configure(new TestRestTemplate("user", "password"));
|
||||
}
|
||||
|
||||
TestRestTemplate beansRestTemplate() {
|
||||
return configure(new TestRestTemplate("beans", "beans"));
|
||||
}
|
||||
|
||||
private TestRestTemplate configure(TestRestTemplate restTemplate) {
|
||||
restTemplate.setUriTemplateHandler(new LocalHostUriTemplateHandler(getEnvironment()));
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.actuator.customsecurity;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for actuator endpoints with custom dispatcher servlet path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.mvc.servlet.path=/example")
|
||||
|
||||
public class CustomServletPathSampleActuatorTests extends AbstractSampleActuatorCustomSecurityTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
@Override
|
||||
Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.actuator.customsecurity;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for separate management and main service ports with custom dispatcher
|
||||
* servlet path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = { "management.server.port=0", "spring.mvc.servlet.path=/example" })
|
||||
public class ManagementPortCustomServletPathSampleActuatorTests extends AbstractSampleActuatorCustomSecurityTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Test
|
||||
public void actuatorPathOnMainPortShouldNotMatch() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate()
|
||||
.getForEntity("http://localhost:" + this.port + "/example/actuator/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.managementPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<!-- Your own application should inherit from spring-boot-starter-parent -->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-samples</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-sample-secure-jersey</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Boot Sample Secure Jersey</name>
|
||||
<description>Spring Boot Sample Secure Jersey</description>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!-- Compile -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jersey</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jolokia</groupId>
|
||||
<artifactId>jolokia-core</artifactId>
|
||||
</dependency>
|
||||
<!-- Provided -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate build info</id>
|
||||
<goals>
|
||||
<goal>build-info</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>java9+</id>
|
||||
<activation>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/hello")
|
||||
public class Endpoint {
|
||||
|
||||
private final Service service;
|
||||
|
||||
public Endpoint(Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.service.message();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JerseyConfig extends ResourceConfig {
|
||||
|
||||
public JerseyConfig() {
|
||||
register(Endpoint.class);
|
||||
register(ReverseEndpoint.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.QueryParam;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/reverse")
|
||||
public class ReverseEndpoint {
|
||||
|
||||
@GET
|
||||
public String reverse(@QueryParam("input") @NotNull String input) {
|
||||
return new StringBuilder(input).reverse().toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleSecureJerseyApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SampleSecureJerseyApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
|
||||
import org.springframework.boot.actuate.web.mappings.MappingsEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Bean
|
||||
public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
|
||||
return new InMemoryUserDetailsManager(
|
||||
User.withDefaultPasswordEncoder().username("user").password("password").authorities("ROLE_USER")
|
||||
.build(),
|
||||
User.withDefaultPasswordEncoder().username("admin").password("admin")
|
||||
.authorities("ROLE_ACTUATOR", "ROLE_USER").build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http.authorizeRequests()
|
||||
.requestMatchers(EndpointRequest.to("health", "info")).permitAll()
|
||||
.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)).hasRole("ACTUATOR")
|
||||
.antMatchers("/**").hasRole("USER")
|
||||
.and()
|
||||
.httpBasic();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Service {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
||||
|
||||
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Abstract base class for actuator tests with custom security.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public abstract class AbstractJerseySecureTests {
|
||||
|
||||
abstract String getPath();
|
||||
|
||||
abstract String getManagementPath();
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate testRestTemplate;
|
||||
|
||||
@Test
|
||||
public void helloEndpointIsSecure() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getPath() + "/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorInsecureEndpoint() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health/diskSpace", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorLinksWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorLinksWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorLinksWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
adminRestTemplate().getForEntity(getManagementPath() + "/actuator/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSecureEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSecureEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSecureEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
entity = adminRestTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureServletEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureServletEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureServletEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorExcludedFromEndpointRequestMatcher() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/mappings",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
TestRestTemplate restTemplate() {
|
||||
return this.testRestTemplate;
|
||||
}
|
||||
|
||||
TestRestTemplate adminRestTemplate() {
|
||||
return this.testRestTemplate.withBasicAuth("admin", "admin");
|
||||
}
|
||||
|
||||
TestRestTemplate userRestTemplate() {
|
||||
return this.testRestTemplate.withBasicAuth("user", "password");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for actuator endpoints with custom application path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.jersey.application-path=/example")
|
||||
|
||||
public class CustomApplicationPathActuatorTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for actuator endpoints with custom security configuration.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class JerseySecureApplicationTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.port;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for separate management and main service ports with custom management
|
||||
* context path.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "management.server.port=0", "management.server.servlet.context-path=/management" })
|
||||
public class ManagementPortAndPathJerseyApplicationTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Test
|
||||
public void testMissing() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate("admin", "admin")
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/management/actuator/missing", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.managementPort + "/management";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 sample.secure.jersey;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for separate management and main service ports with custom
|
||||
* application path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = { "management.server.port=0", "spring.jersey.application-path=/example" })
|
||||
public class ManagementPortCustomApplicationPathJerseyTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Test
|
||||
public void actuatorPathOnMainPortShouldNotMatch() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate()
|
||||
.getForEntity("http://localhost:" + this.port + "/example/actuator/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.managementPort;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue