Merge pull request #6540 from eddumelendez:health-endpoint-visibility

* pr/6540:
  Polish contribution
  Fix health endpoint security
pull/6644/head
Stephane Nicoll 8 years ago
commit 2d1e85c2fc

@ -17,7 +17,9 @@
package org.springframework.boot.actuate.endpoint.mvc; package org.springframework.boot.actuate.endpoint.mvc;
import java.security.Principal; import java.security.Principal;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.boot.actuate.endpoint.HealthEndpoint; import org.springframework.boot.actuate.endpoint.HealthEndpoint;
@ -35,6 +37,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -45,6 +48,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Dave Syer * @author Dave Syer
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Phillip Webb * @author Phillip Webb
* @author Eddú Meléndez
* @since 1.1.0 * @since 1.1.0
*/ */
@ConfigurationProperties(prefix = "endpoints.health") @ConfigurationProperties(prefix = "endpoints.health")
@ -184,14 +188,17 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
} }
if (isSpringSecurityAuthentication(principal)) { if (isSpringSecurityAuthentication(principal)) {
Authentication authentication = (Authentication) principal; Authentication authentication = (Authentication) principal;
String role = this.roleResolver.getProperty("role", "ROLE_ADMIN"); List<String> roles = Arrays.asList(StringUtils.trimArrayElements(StringUtils
.commaDelimitedListToStringArray(this.roleResolver.getProperty("roles", "ROLE_ADMIN"))));
for (GrantedAuthority authority : authentication.getAuthorities()) { for (GrantedAuthority authority : authentication.getAuthorities()) {
String name = authority.getAuthority(); String name = authority.getAuthority();
for (String role : roles) {
if (role.equals(name) || ("ROLE_" + role).equals(name)) { if (role.equals(name) || ("ROLE_" + role).equals(name)) {
return true; return true;
} }
} }
} }
}
return false; return false;
} }

@ -42,6 +42,7 @@ import static org.mockito.Mockito.mock;
* @author Christian Dupuis * @author Christian Dupuis
* @author Dave Syer * @author Dave Syer
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Eddú Meléndez
*/ */
public class HealthMvcEndpointTests { public class HealthMvcEndpointTests {
@ -49,19 +50,27 @@ public class HealthMvcEndpointTests {
Collections.<String, Object>singletonMap("endpoints.health.sensitive", Collections.<String, Object>singletonMap("endpoints.health.sensitive",
"false")); "false"));
private static final PropertySource<?> SECURITY_ROLES = new MapPropertySource("test",
Collections.<String, Object>singletonMap("management.security.roles",
"HERO, USER"));
private HealthEndpoint endpoint = null; private HealthEndpoint endpoint = null;
private HealthMvcEndpoint mvc = null; private HealthMvcEndpoint mvc = null;
private MockEnvironment environment; private MockEnvironment environment;
private UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken( private UsernamePasswordAuthenticationToken user = createAuthenticationToken("ROLE_USER");
"user", "password",
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); private UsernamePasswordAuthenticationToken admin = createAuthenticationToken("ROLE_ADMIN");
private UsernamePasswordAuthenticationToken admin = new UsernamePasswordAuthenticationToken( private UsernamePasswordAuthenticationToken hero = createAuthenticationToken("ROLE_HERO");
private UsernamePasswordAuthenticationToken createAuthenticationToken(String authority) {
return new UsernamePasswordAuthenticationToken(
"user", "password", "user", "password",
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN")); AuthorityUtils.commaSeparatedStringToAuthorityList(authority));
}
@Before @Before
public void init() { public void init() {
@ -140,6 +149,28 @@ public class HealthMvcEndpointTests {
assertThat(((Health) result).getDetails().get("foo")).isNull(); assertThat(((Health) result).getDetails().get("foo")).isNull();
} }
@Test
public void secureCustomRole() {
this.environment.getPropertySources().addLast(SECURITY_ROLES);
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);
given(this.endpoint.invoke())
.willReturn(new Health.Builder().up().withDetail("foo", "bar").build());
Object result = this.mvc.invoke(this.admin);
assertThat(result instanceof Health).isTrue();
assertThat(((Health) result).getStatus() == Status.UP).isTrue();
assertThat(((Health) result).getDetails().get("foo")).isNull();
}
@Test @Test
public void healthIsCached() { public void healthIsCached() {
given(this.endpoint.getTimeToLive()).willReturn(10000L); given(this.endpoint.getTimeToLive()).willReturn(10000L);

Loading…
Cancel
Save