diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java index 235aa885728..799916594de 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java @@ -196,7 +196,7 @@ public class CrshAutoConfiguration { // overridden by ConfigurationProperties. SpringAuthenticationProperties authenticationProperties = new SpringAuthenticationProperties(); if (this.management != null) { - List roles = this.management.getSecurity().getRole(); + List roles = this.management.getSecurity().getRoles(); authenticationProperties.setRoles(roles.toArray(new String[roles.size()])); } return authenticationProperties; diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementServerProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementServerProperties.java index db13dd5ebd7..7821ea8afd8 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementServerProperties.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementServerProperties.java @@ -17,8 +17,7 @@ package org.springframework.boot.actuate.autoconfigure; import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import javax.validation.constraints.NotNull; @@ -164,9 +163,9 @@ public class ManagementServerProperties implements SecurityPrerequisite { private boolean enabled = true; /** - * Roles required to access the management endpoint. + * Comma-separated list of roles that can access the management endpoint. */ - private List role = new ArrayList(Arrays.asList("ADMIN")); + private List roles = Collections.singletonList("ADMIN"); /** * Session creating policy to use (always, never, if_required, stateless). @@ -181,12 +180,17 @@ public class ManagementServerProperties implements SecurityPrerequisite { this.sessions = sessions; } - public void setRole(List role) { - this.role = role; + public void setRoles(List roles) { + this.roles = roles; } - public List getRole() { - return this.role; + @Deprecated + public void setRole(String role) { + this.roles = Collections.singletonList(role); + } + + public List getRoles() { + return this.roles; } public boolean isEnabled() { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java index 4030250622a..bc4a48f08ab 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java @@ -124,7 +124,7 @@ public class ManagementWebSecurityAutoConfiguration { public void init() { if (this.management != null && this.security != null) { this.security.getUser().getRole() - .addAll(this.management.getSecurity().getRole()); + .addAll(this.management.getSecurity().getRoles()); } } @@ -297,7 +297,7 @@ public class ManagementWebSecurityAutoConfiguration { requests.requestMatchers(new LazyEndpointPathRequestMatcher( this.contextResolver, EndpointPaths.NON_SENSITIVE)).permitAll(); // Restrict the rest to the configured roles - List roles = this.management.getSecurity().getRole(); + List roles = this.management.getSecurity().getRoles(); requests.anyRequest().hasAnyRole(roles.toArray(new String[roles.size()])); } diff --git a/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 8ce47a4b0bc..8e774d1de4a 100644 --- a/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -163,6 +163,15 @@ "description": "Enable git info.", "defaultValue": true }, + { + "name": "management.security.role", + "type": "java.lang.String", + "description": "Roles required to access the management endpoint.", + "defaultValue": "ADMIN", + "deprecation": { + "replacement": "management.security.roles" + } + }, { "name": "spring.git.properties", "type": "java.lang.String", diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementServerPropertiesAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementServerPropertiesAutoConfigurationTests.java index 7a318fb9e32..3efbc3bfe04 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementServerPropertiesAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementServerPropertiesAutoConfigurationTests.java @@ -16,8 +16,14 @@ package org.springframework.boot.actuate.autoconfigure; +import org.junit.After; import org.junit.Test; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -28,6 +34,15 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class ManagementServerPropertiesAutoConfigurationTests { + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + @Test public void defaultManagementServerProperties() { ManagementServerProperties properties = new ManagementServerProperties(); @@ -58,4 +73,32 @@ public class ManagementServerPropertiesAutoConfigurationTests { assertThat(properties.getContextPath()).isEqualTo(""); } + @Test + @Deprecated + public void managementRoleSetRolesProperly() { + ManagementServerProperties properties = load("management.security.role=FOO"); + assertThat(properties.getSecurity().getRoles()).containsOnly("FOO"); + } + + @Test + public void managementRolesSetMultipleRoles() { + ManagementServerProperties properties = load("management.security.roles=FOO,BAR,BIZ"); + assertThat(properties.getSecurity().getRoles()).containsOnly("FOO", "BAR", "BIZ"); + } + + public ManagementServerProperties load(String... environment) { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(ctx, environment); + ctx.register(TestConfiguration.class); + ctx.refresh(); + this.context = ctx; + return this.context.getBean(ManagementServerProperties.class); + } + + @Configuration + @EnableConfigurationProperties(ManagementServerProperties.class) + static class TestConfiguration { + + } + } diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index b31c92487f0..62be349e73b 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -996,7 +996,7 @@ content into your application; rather pick only the properties that you need. management.context-path= # Management endpoint context-path. For instance `/actuator` management.port= # Management endpoint HTTP port. Use the same port as the application by default. management.security.enabled=true # Enable security. - management.security.role=ADMIN # Roles required to access the management endpoint. + management.security.roles=ADMIN # Comma-separated list of roles that can access the management endpoint. management.security.sessions=stateless # Session creating policy to use (always, never, if_required, stateless). # HEALTH INDICATORS (previously health.*) diff --git a/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 60d8289cd17..5315c622468 100644 --- a/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -520,14 +520,14 @@ TIP: Generated passwords are logged as the application starts. Search for '`Usin security password`'. You can use Spring properties to change the username and password and to change the -security roles required to access the endpoints. For example, you might set the following +security role(s) required to access the endpoints. For example, you might set the following in your `application.properties`: [source,properties,indent=0] ---- security.user.name=admin security.user.password=secret - management.security.role=SUPERUSER + management.security.roles=SUPERUSER ---- TIP: If you don't use Spring Security and your HTTP endpoints are exposed publicly,