diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java index 67f8f1891e..04e4d37d9c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -144,9 +144,10 @@ public class EndpointWebMvcManagementContextConfiguration { @Bean @ConditionalOnBean(HealthEndpoint.class) @ConditionalOnEnabledEndpoint("health") - public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate) { + public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate, + ManagementServerProperties managementServerProperties) { HealthMvcEndpoint healthMvcEndpoint = new HealthMvcEndpoint(delegate, - isHealthSecure()); + isHealthSecure(), managementServerProperties.getSecurity().getRoles()); if (this.healthMvcEndpointProperties.getMapping() != null) { healthMvcEndpoint .addStatusMapping(this.healthMvcEndpointProperties.getMapping()); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java index d6e55375d9..9be5eac950 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -57,6 +57,8 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter roles; + private Map statusMapping = new HashMap(); private RelaxedPropertyResolver healthPropertyResolver; @@ -70,13 +72,19 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter roles) { super(delegate); this.secure = secure; setupDefaultStatusMapping(); + this.roles = roles; } private void setupDefaultStatusMapping() { @@ -192,12 +200,9 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter roles = Arrays.asList(StringUtils - .trimArrayElements(StringUtils.commaDelimitedListToStringArray( - this.roleResolver.getProperty("roles", "ROLE_ADMIN")))); for (GrantedAuthority authority : authentication.getAuthorities()) { String name = authority.getAuthority(); - for (String role : roles) { + for (String role : getRoles()) { if (role.equals(name) || ("ROLE_" + role).equals(name)) { return true; } @@ -207,6 +212,15 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter getRoles() { + if (this.roles != null) { + return this.roles; + } + return Arrays.asList( + StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray( + this.roleResolver.getProperty("roles", "ROLE_ADMIN")))); + } + private boolean isSpringSecurityAuthentication(Principal principal) { return ClassUtils.isPresent("org.springframework.security.core.Authentication", null) && (principal instanceof Authentication); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthMvcEndpointAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthMvcEndpointAutoConfigurationTests.java index e1f9285e4b..2fe464c068 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthMvcEndpointAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthMvcEndpointAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -16,6 +16,8 @@ package org.springframework.boot.actuate.autoconfigure; +import java.util.Arrays; + import org.junit.After; import org.junit.Test; @@ -33,6 +35,7 @@ import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.web.MockServletContext; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @@ -81,6 +84,20 @@ public class HealthMvcEndpointAutoConfigurationTests { assertThat(map.getDetails().get("foo")).isEqualTo("bar"); } + @Test + public void testSetRoles() throws Exception { + // gh-8314 + this.context = new AnnotationConfigWebApplicationContext(); + this.context.setServletContext(new MockServletContext()); + this.context.register(TestConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, + "management.security.roles[0]=super"); + this.context.refresh(); + HealthMvcEndpoint health = this.context.getBean(HealthMvcEndpoint.class); + assertThat(ReflectionTestUtils.getField(health, "roles")) + .isEqualTo(Arrays.asList("super")); + } + @Configuration @ImportAutoConfiguration({ SecurityAutoConfiguration.class, JacksonAutoConfiguration.class, WebMvcAutoConfiguration.class, diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java index f6bd0c3d25..75b7bc0f61 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.endpoint.mvc; +import java.util.Arrays; import java.util.Collections; import org.junit.Before; @@ -164,6 +165,19 @@ public class HealthMvcEndpointTests { assertThat(((Health) result).getDetails().get("foo")).isEqualTo("bar"); } + @Test + public void secureCustomRoleList() { + // gh-8314 + this.mvc = new HealthMvcEndpoint(this.endpoint, true, + Arrays.asList("HERO", "USER")); + given(this.endpoint.invoke()) + .willReturn(new Health.Builder().up().withDetail("foo", "bar").build()); + Object result = this.mvc.invoke(this.hero); + assertThat(result instanceof Health).isTrue(); + assertThat(((Health) result).getStatus() == Status.UP).isTrue(); + assertThat(((Health) result).getDetails().get("foo")).isEqualTo("bar"); + } + @Test public void secureCustomRoleNoAccess() { this.environment.getPropertySources().addLast(SECURITY_ROLES);