Rework security autoconfiguration
This commit combines security autoconfigurations for management endpoints and the rest of the application. By default, if Spring Security is on the classpath, it turns on @EnableWebSecurity. In the presence of another WebSecurityConfigurerAdapter this backs off completely. A default AuthenticationManager is also provided with a user and generated password. This can be turned off by specifying a bean of type AuthenticationManager, AuthenticationProvider or UserDetailsService. Closes gh-7958
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
<module>spring-boot-sample-actuator-log4j2</module>
|
||||
<module>spring-boot-sample-actuator-noweb</module>
|
||||
<module>spring-boot-sample-actuator-ui</module>
|
||||
<module>spring-boot-sample-actuator-custom-security</module>
|
||||
<module>spring-boot-sample-amqp</module>
|
||||
<module>spring-boot-sample-aop</module>
|
||||
<module>spring-boot-sample-atmosphere</module>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?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 http://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>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-sample-actuator-custom-security</artifactId>
|
||||
<name>Spring Boot Actuator Custom Security Sample</name>
|
||||
<description>Spring Boot Actuator Custom Security Sample</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!-- Compile -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</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>
|
||||
<!-- Runtime -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</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>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package sample.actuator.customsecurity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class ExampleController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String home(Map<String, Object> model) {
|
||||
model.put("message", "Hello World");
|
||||
model.put("title", "Hello Home");
|
||||
model.put("date", new Date());
|
||||
return "home";
|
||||
}
|
||||
|
||||
@RequestMapping("/foo")
|
||||
public String foo() {
|
||||
throw new RuntimeException("Expected exception in controller");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2012-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 sample.actuator.customsecurity;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleActuatorCustomSecurityApplication {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleActuatorCustomSecurityApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package sample.actuator.customsecurity;
|
||||
|
||||
import org.springframework.boot.autoconfigure.security.SpringBootSecurity;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private SpringBootSecurity bootSecurity;
|
||||
|
||||
public SecurityConfiguration(SpringBootSecurity bootSecurity) {
|
||||
this.bootSecurity = bootSecurity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication()
|
||||
.withUser("user").password("password").authorities("ROLE_USER").and()
|
||||
.withUser("admin").password("admin").authorities("ROLE_ACTUATOR", "ROLE_USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
.requestMatchers(this.bootSecurity.endpointIds("status", "info")).permitAll()
|
||||
.requestMatchers(this.bootSecurity.endpointIds(SpringBootSecurity.ALL_ENDPOINTS)).hasRole("ACTUATOR")
|
||||
.requestMatchers(this.bootSecurity.staticResources()).permitAll()
|
||||
.antMatchers("/foo").permitAll()
|
||||
.antMatchers("/**").hasRole("USER")
|
||||
.and()
|
||||
.cors()
|
||||
.and()
|
||||
.httpBasic();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
endpoints.all.web.enabled=true
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,32 @@
|
||||
<#import "/spring.ftl" as spring />
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error</title>
|
||||
<#assign home><@spring.url relativeUrl="/"/></#assign>
|
||||
<#assign bootstrap><@spring.url relativeUrl="/css/bootstrap.min.css"/></#assign>
|
||||
<link rel="stylesheet" href="${bootstrap}" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand" href="http://freemarker.org/"> FreeMarker -
|
||||
Plain </a>
|
||||
<ul class="nav">
|
||||
<li><a href="${home}"> Home </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h1>Error Page</h1>
|
||||
<div id="created">${timestamp?datetime}</div>
|
||||
<div>
|
||||
There was an unexpected error (type=${error}, status=${status}).
|
||||
</div>
|
||||
<div>${message}</div>
|
||||
<div>
|
||||
Please contact the operator with the above information.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<#import "/spring.ftl" as spring />
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
<#assign home><@spring.url relativeUrl="/"/></#assign>
|
||||
<#assign bootstrap><@spring.url relativeUrl="/css/bootstrap.min.css"/></#assign>
|
||||
<link rel="stylesheet" href="${bootstrap}" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand" href="http://freemarker.org/"> FreeMarker -
|
||||
Plain </a>
|
||||
<ul class="nav">
|
||||
<li><a href="${home}"> Home </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h1>${title}</h1>
|
||||
<div>${message}</div>
|
||||
<div id="created">${date?datetime}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
package sample.actuator;
|
||||
package sample.actuator.customsecurity;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
@@ -12,10 +12,14 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
@@ -59,7 +63,7 @@ public class CorsSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void preflightRequestToEndpointShouldReturnOk() throws Exception {
|
||||
RequestEntity<?> healthRequest = RequestEntity
|
||||
.options(new URI("/application/health"))
|
||||
.options(new URI("/application/env"))
|
||||
.header("Origin", "http://localhost:8080")
|
||||
.header("Access-Control-Request-Method", "GET").build();
|
||||
ResponseEntity<?> exchange = this.testRestTemplate.exchange(healthRequest,
|
||||
@@ -70,7 +74,7 @@ public class CorsSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void preflightRequestWhenCorsConfigInvalidShouldReturnForbidden()
|
||||
throws Exception {
|
||||
RequestEntity<?> entity = RequestEntity.options(new URI("/application/health"))
|
||||
RequestEntity<?> entity = RequestEntity.options(new URI("/application/env"))
|
||||
.header("Origin", "http://localhost:9095")
|
||||
.header("Access-Control-Request-Method", "GET").build();
|
||||
ResponseEntity<byte[]> exchange = this.testRestTemplate.exchange(entity,
|
||||
@@ -14,16 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.actuator;
|
||||
|
||||
import java.util.Map;
|
||||
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.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -39,17 +35,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Integration tests for separate management and main service ports.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
|
||||
"management.port=0", "management.context-path=/admin",
|
||||
"management.security.enabled=false" })
|
||||
"management.port=0", "management.context-path=/admin"})
|
||||
@DirtiesContext
|
||||
public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 9010;
|
||||
|
||||
@@ -59,43 +52,36 @@ public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testHome() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate("user", getPassword())
|
||||
.getForEntity("http://localhost:" + this.port, Map.class);
|
||||
ResponseEntity<String> entity = new TestRestTemplate("user", "password")
|
||||
.getForEntity("http://localhost:" + this.port, String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
assertThat(body.get("message")).isEqualTo("Hello Phil");
|
||||
assertThat(entity.getBody()).contains("Hello World");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetrics() throws Exception {
|
||||
testHome(); // makes sure some requests have been made
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/admin/metrics", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHealth() throws Exception {
|
||||
public void testSecureActuator() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/admin/health",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsecureActuator() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/admin/status",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissing() throws Exception {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
ResponseEntity<String> entity = new TestRestTemplate("admin", "admin").getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/admin/missing",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
assertThat(entity.getBody()).contains("\"status\":404");
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package sample.actuator.customsecurity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class SampleActuatorCustomSecurityApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
public void homeIsSecure() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/", 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 testInsecureApplicationPath() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/foo", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
assertThat((String)body.get("message")).contains("Expected exception in controller");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsecureStaticResources() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/css/bootstrap.min.css", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("body");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insecureActuator() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/application/status",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureActuator() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/application/env",
|
||||
Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,10 +18,21 @@ package sample.actuator.log4j2;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleActuatorLog4J2Application {
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() throws Exception {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleActuatorLog4J2Application.class, args);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
endpoints.shutdown.enabled=true
|
||||
|
||||
management.security.enabled=false
|
||||
endpoints.all.web.enabled=true
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package sample.actuator.log4j2;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Rule;
|
||||
@@ -63,10 +65,17 @@ public class SampleActuatorLog4J2ApplicationTests {
|
||||
|
||||
@Test
|
||||
public void validateLoggersEndpoint() throws Exception {
|
||||
this.mvc.perform(get("/application/loggers/org.apache.coyote.http11.Http11NioProtocol"))
|
||||
this.mvc.perform(get("/application/loggers/org.apache.coyote.http11.Http11NioProtocol")
|
||||
.header("Authorization", "Basic " + getBasicAuth()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(equalTo("{\"configuredLevel\":\"WARN\","
|
||||
+ "\"effectiveLevel\":\"WARN\"}")));
|
||||
}
|
||||
|
||||
private String getBasicAuth() {
|
||||
return new String(Base64.getEncoder()
|
||||
.encode(("user:password").getBytes()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -29,6 +33,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@Controller
|
||||
public class SampleActuatorUiApplication {
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() throws Exception {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
public String home(Map<String, Object> model) {
|
||||
model.put("message", "Hello World");
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
health.diskspace.enabled=false
|
||||
|
||||
# empty so home page is unsecured
|
||||
security.basic.path=
|
||||
endpoints.all.web.enabled=true
|
||||
@@ -21,9 +21,7 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -46,9 +44,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class SampleActuatorUiApplicationPortTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 9010;
|
||||
|
||||
@@ -82,7 +77,7 @@ public class SampleActuatorUiApplicationPortTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ public class SampleActuatorUiApplicationTests {
|
||||
public void testHome() throws Exception {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/", HttpMethod.GET,
|
||||
ResponseEntity<String> entity = this.restTemplate.withBasicAuth("user", getPassword())
|
||||
.exchange("/", HttpMethod.GET,
|
||||
new HttpEntity<Void>(headers), String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("<title>Hello");
|
||||
@@ -80,11 +81,16 @@ public class SampleActuatorUiApplicationTests {
|
||||
public void testError() throws Exception {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/error",
|
||||
ResponseEntity<String> entity = this.restTemplate.withBasicAuth("user", getPassword())
|
||||
.exchange("/error",
|
||||
HttpMethod.GET, new HttpEntity<Void>(headers), String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
assertThat(entity.getBody()).contains("<html>").contains("<body>")
|
||||
.contains("Please contact the operator with the above information");
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(ServiceProperties.class)
|
||||
@@ -31,6 +35,13 @@ public class SampleActuatorApplication {
|
||||
SpringApplication.run(SampleActuatorApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() throws Exception {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HealthIndicator helloHealthIndicator() {
|
||||
return new HealthIndicator() {
|
||||
|
||||
@@ -11,6 +11,7 @@ server.tomcat.accesslog.pattern=%h %t "%r" %s %b
|
||||
security.require-ssl=false
|
||||
#spring.jackson.serialization.INDENT_OUTPUT=true
|
||||
spring.jmx.enabled=true
|
||||
endpoints.all.web.enabled=true
|
||||
|
||||
spring.jackson.serialization.write_dates_as_timestamps=false
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -45,9 +44,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ActiveProfiles("endpoints")
|
||||
public class EndpointsPropertiesSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@@ -74,7 +70,7 @@ public class EndpointsPropertiesSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-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 sample.actuator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for insecured service endpoints (even with Spring Security on
|
||||
* classpath).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
|
||||
"management.security.enabled:false" })
|
||||
@DirtiesContext
|
||||
@ActiveProfiles("unsecure-management")
|
||||
public class InsecureManagementSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
public void testHomeIsSecure() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/", 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 testMetrics() throws Exception {
|
||||
try {
|
||||
testHomeIsSecure(); // makes sure some requests have been made
|
||||
}
|
||||
catch (AssertionError ex) {
|
||||
// ignore;
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/application/metrics",
|
||||
Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
assertThat(body).containsKey("counter.status.401.unmapped");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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 sample.actuator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for insecured service endpoints (even with Spring Security on
|
||||
* classpath).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
|
||||
"security.basic.enabled:false" })
|
||||
@DirtiesContext
|
||||
public class InsecureSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
public void testHome() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
assertThat(body.get("message")).isEqualTo("Hello Phil");
|
||||
assertThat(entity.getHeaders()).doesNotContainKey("Set-Cookie");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,9 +21,7 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -47,9 +45,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class ManagementAddressActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 9010;
|
||||
|
||||
@@ -75,7 +70,7 @@ public class ManagementAddressActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -47,9 +46,6 @@ public class ManagementPathSampleActuatorApplicationTests {
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties securityProperties;
|
||||
|
||||
@Test
|
||||
public void testHealth() throws Exception {
|
||||
ResponseEntity<String> entity = this.restTemplate
|
||||
@@ -71,7 +67,7 @@ public class ManagementPathSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.securityProperties.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -46,9 +44,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class ManagementPortAndPathSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 9010;
|
||||
|
||||
@@ -98,7 +93,7 @@ public class ManagementPortAndPathSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testErrorPage() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate()
|
||||
ResponseEntity<Map> entity = new TestRestTemplate("user", getPassword())
|
||||
.getForEntity("http://localhost:" + this.port + "/error", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -109,7 +104,7 @@ public class ManagementPortAndPathSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testManagementErrorPage() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
|
||||
ResponseEntity<Map> entity = new TestRestTemplate("user", getPassword()).getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/error", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -118,7 +113,7 @@ public class ManagementPortAndPathSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ package sample.actuator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.rule.OutputCapture;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -46,9 +46,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class ManagementPortSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 9010;
|
||||
|
||||
@@ -89,7 +86,7 @@ public class ManagementPortSampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testErrorPage() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
|
||||
ResponseEntity<Map> entity = new TestRestTemplate("user", getPassword()).getForEntity(
|
||||
"http://localhost:" + this.managementPort + "/error", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -98,7 +95,7 @@ public class ManagementPortSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -44,9 +43,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class NoManagementSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@@ -71,7 +67,7 @@ public class NoManagementSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -51,9 +50,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class SampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@@ -204,7 +200,8 @@ public class SampleActuatorApplicationTests {
|
||||
@Test
|
||||
public void testErrorPageDirectAccess() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/error", Map.class);
|
||||
ResponseEntity<Map> entity = this.restTemplate.withBasicAuth("user", getPassword())
|
||||
.getForEntity("/error", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
@@ -239,7 +236,7 @@ public class SampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-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 sample.actuator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for insecured service endpoints (even with Spring Security on
|
||||
* classpath).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
|
||||
"security.basic.enabled:false", "server.servlet.path:/spring" })
|
||||
@DirtiesContext
|
||||
public class ServletPathInsecureSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
public void testHome() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/spring/",
|
||||
Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> body = entity.getBody();
|
||||
assertThat(body.get("message")).isEqualTo("Hello Phil");
|
||||
assertThat(entity.getHeaders()).doesNotContainKey("Set-Cookie");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetricsIsSecure() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate
|
||||
.getForEntity("/spring/application/metrics", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -47,13 +46,11 @@ public class ServletPathSampleActuatorApplicationTests {
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Test
|
||||
public void testErrorPath() throws Exception {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/spring/error",
|
||||
ResponseEntity<Map> entity = this.restTemplate.withBasicAuth("user", getPassword())
|
||||
.getForEntity("/spring/error",
|
||||
Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -84,7 +81,7 @@ public class ServletPathSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -43,9 +42,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@DirtiesContext
|
||||
public class ShutdownSampleActuatorApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@@ -73,7 +69,7 @@ public class ShutdownSampleActuatorApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
server.error.path: /oops
|
||||
management.context-path: /admin
|
||||
endpoints.health.sensitive: false
|
||||
management.context-path: /admin
|
||||
@@ -0,0 +1,29 @@
|
||||
package sample.secure.oauth2.actuator;
|
||||
|
||||
import org.springframework.boot.autoconfigure.security.SpringBootSecurity;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* Basic auth security for actuator endpoints.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration
|
||||
public class ActuatorSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final SpringBootSecurity springBootSecurity;
|
||||
|
||||
public ActuatorSecurityConfiguration(SpringBootSecurity springBootSecurity) {
|
||||
this.springBootSecurity = springBootSecurity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.requestMatcher(this.springBootSecurity.endpointIds(SpringBootSecurity.ALL_ENDPOINTS))
|
||||
.authorizeRequests().antMatchers("/**").authenticated()
|
||||
.and()
|
||||
.httpBasic();
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,11 @@ import java.util.UUID;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@@ -34,6 +38,13 @@ public class SampleSecureOAuth2ActuatorApplication {
|
||||
return new Message("Hello World");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() throws Exception {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SampleSecureOAuth2ActuatorApplication.class, args);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
server.port=8081
|
||||
security.basic.enabled=true
|
||||
security.user.password=password
|
||||
endpoints.all.web.enabled=true
|
||||
security.oauth2.resource.id=service
|
||||
security.oauth2.resource.userInfoUri=http://localhost:8080/user
|
||||
logging.level.org.springframework.security=DEBUG
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package sample.secure.oauth2;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration
|
||||
public class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void init(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication().withUser("greg").password("turnquist").roles("read");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
spring.datasource.platform=h2
|
||||
|
||||
security.user.name=greg
|
||||
security.user.password=turnquist
|
||||
security.oauth2.client.client-id=foo
|
||||
security.oauth2.client.client-secret=bar
|
||||
security.oauth2.authorization.checkTokenAccess=isAuthenticated()
|
||||
|
||||
@@ -20,11 +20,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
@@ -34,6 +38,13 @@ public class SampleSecureApplication implements CommandLineRunner {
|
||||
@Autowired
|
||||
private SampleService service;
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() throws Exception {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
SecurityContextHolder.getContext()
|
||||
|
||||
@@ -20,15 +20,10 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import sample.secure.SampleSecureApplicationTests.TestConfiguration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
@@ -43,23 +38,17 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = { SampleSecureApplication.class, TestConfiguration.class })
|
||||
@SpringBootTest(classes = {SampleSecureApplication.class})
|
||||
public class SampleSecureApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private SampleService service;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
private Authentication authentication;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
AuthenticationManager authenticationManager = this.context
|
||||
.getBean(AuthenticationManager.class);
|
||||
this.authentication = authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken("user", "password"));
|
||||
this.authentication = new UsernamePasswordAuthenticationToken("user", "password");
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -90,9 +79,4 @@ public class SampleSecureApplicationTests {
|
||||
assertThat("Goodbye World").isEqualTo(this.service.denied());
|
||||
}
|
||||
|
||||
@PropertySource("classpath:test.properties")
|
||||
@Configuration
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
security.user.password=password
|
||||
@@ -30,11 +30,21 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
public class SampleServletApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() throws Exception {
|
||||
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
|
||||
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Bean
|
||||
public Servlet dispatcherServlet() {
|
||||
|
||||
@@ -16,15 +16,20 @@
|
||||
|
||||
package sample.servlet;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
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.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
@@ -44,12 +49,11 @@ public class SampleServletApplicationTests {
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties security;
|
||||
|
||||
@Test
|
||||
public void testHomeIsSecure() throws Exception {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/", String.class);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/", HttpMethod.GET, new HttpEntity<Void>(headers), String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -62,6 +66,6 @@ public class SampleServletApplicationTests {
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return this.security.getUser().getPassword();
|
||||
return "password";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.autoconfigure.security.SpringBootSecurity;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
@@ -80,7 +80,6 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
|
||||
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
@@ -94,4 +93,25 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Order(1)
|
||||
protected static class ActuatorSecurity extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final SpringBootSecurity springBootSecurity;
|
||||
|
||||
public ActuatorSecurity(SpringBootSecurity springBootSecurity) {
|
||||
this.springBootSecurity = springBootSecurity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.requestMatcher(this.springBootSecurity.endpointIds(SpringBootSecurity.ALL_ENDPOINTS))
|
||||
.authorizeRequests().anyRequest().authenticated()
|
||||
.and()
|
||||
.httpBasic();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
spring.thymeleaf.cache: false
|
||||
logging.level.org.springframework.security: INFO
|
||||
logging.level.org.springframework.security: INFO
|
||||
endpoints.all.web.enabled=true
|
||||
@@ -105,8 +105,10 @@ public class SampleMethodSecurityApplicationTests {
|
||||
|
||||
@Test
|
||||
public void testManagementProtected() throws Exception {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
|
||||
ResponseEntity<String> entity = this.restTemplate
|
||||
.getForEntity("/application/beans", String.class);
|
||||
.exchange("/application/beans", HttpMethod.GET, new HttpEntity<Void>(headers), String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,8 @@ import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
@@ -60,7 +58,6 @@ public class SampleWebSecureCustomApplication implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
|
||||
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,10 +23,8 @@ import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
@@ -63,7 +61,6 @@ public class SampleWebSecureJdbcApplication implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
|
||||
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -20,10 +20,9 @@ import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.autoconfigure.security.SpringBootSecurity;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
@@ -60,12 +59,19 @@ public class SampleWebSecureApplication implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
|
||||
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final SpringBootSecurity springBootSecurity;
|
||||
|
||||
public ApplicationSecurity(SpringBootSecurity springBootSecurity) {
|
||||
this.springBootSecurity = springBootSecurity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin()
|
||||
http.authorizeRequests()
|
||||
.requestMatchers(this.springBootSecurity.staticResources()).permitAll()
|
||||
.anyRequest().fullyAuthenticated().and().formLogin()
|
||||
.loginPage("/login").failureUrl("/login?error").permitAll().and()
|
||||
.logout().permitAll();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
spring.thymeleaf.cache: false
|
||||
security.basic.enabled: false
|
||||
# demo only:
|
||||
security.user.password: password
|
||||
logging.level.org.springframework.security: INFO
|
||||
logging.level.org.springframework.boot.actuate.audit.listener.AuditListener: DEBUG
|
||||
Reference in New Issue
Block a user