From b54960f07291a6971a81c69d7eb63f7bf317d313 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Mon, 27 Apr 2015 17:32:47 -0500 Subject: [PATCH] Management Security uses Spring Realm Previously ManagementSecurityAutoConfiguration used Spring Security's default realm of "Realm" when authentication failed. This was confusing because when prompted for authentication (i.e. no credentials provided) the realm "Spring" was requested. This commit ensures the Realm that is used is consistent for all of of the security auto configuration. Fixes #2466 --- .../ManagementSecurityAutoConfiguration.java | 5 +- ...agementSecurityAutoConfigurationTests.java | 75 +++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfiguration.java index 30efe4b7986..a190a16d840 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfiguration.java @@ -229,13 +229,14 @@ public class ManagementSecurityAutoConfiguration { if (this.security.isRequireSsl()) { http.requiresChannel().anyRequest().requiresSecure(); } - http.exceptionHandling().authenticationEntryPoint(entryPoint()); + AuthenticationEntryPoint entryPoint = entryPoint(); + http.exceptionHandling().authenticationEntryPoint(entryPoint); paths = this.server.getPathsArray(paths); http.requestMatchers().antMatchers(paths); String[] endpointPaths = this.server.getPathsArray(getEndpointPaths( this.endpointHandlerMapping, false)); configureAuthorizeRequests(endpointPaths, http.authorizeRequests()); - http.httpBasic(); + http.httpBasic().authenticationEntryPoint(entryPoint); // No cookies for management endpoints by default http.csrf().disable(); http.sessionManagement().sessionCreationPolicy( diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java index d48f52a852e..14cfd1e42f8 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java @@ -16,8 +16,12 @@ package org.springframework.boot.actuate.autoconfigure; +import javax.servlet.Filter; + +import org.hamcrest.Matchers; import org.junit.After; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; @@ -31,6 +35,7 @@ import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.authority.AuthorityUtils; @@ -38,7 +43,12 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.FilterChainProxy; import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.util.StringUtils; +import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import static org.hamcrest.Matchers.greaterThan; @@ -185,6 +195,71 @@ public class ManagementSecurityAutoConfigurationTests { this.context.getBean(AuthenticationManager.class)); } + // gh-2466 + @Test + public void realmSameForManagement() throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.setServletContext(new MockServletContext()); + this.context.register(AuthenticationConfig.class, + SecurityAutoConfiguration.class, + ManagementSecurityAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class, + ManagementServerPropertiesAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + + MockMvc mockMvc = MockMvcBuilders + .webAppContextSetup((WebApplicationContext) this.context) + .addFilters( + this.context.getBean("springSecurityFilterChain", Filter.class)) + .build(); + + + // no user (Main) + mockMvc.perform( + MockMvcRequestBuilders.get("/")) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()) + .andExpect( + MockMvcResultMatchers.header().string("www-authenticate", + Matchers.containsString("realm=\"Spring\""))); + + // invalid user (Main) + mockMvc.perform( + MockMvcRequestBuilders.get("/").header("authorization", "Basic xxx")) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()) + .andExpect( + MockMvcResultMatchers.header().string("www-authenticate", + Matchers.containsString("realm=\"Spring\""))); + + // no user (Management) + mockMvc.perform( + MockMvcRequestBuilders.get("/beans")) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()) + .andExpect( + MockMvcResultMatchers.header().string("www-authenticate", + Matchers.containsString("realm=\"Spring\""))); + + // invalid user (Management) + mockMvc.perform( + MockMvcRequestBuilders.get("/beans").header("authorization", "Basic xxx")) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()) + .andExpect( + MockMvcResultMatchers.header().string("www-authenticate", + Matchers.containsString("realm=\"Spring\""))); + } + + @EnableGlobalAuthentication + @Configuration + static class AuthenticationConfig { + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } + } + @Configuration protected static class TestConfiguration {