From 87c9a14bff532d58c2fa1c190bb67b283e2f0012 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Thu, 18 Jul 2013 11:39:38 -0500 Subject: [PATCH] SEC-2198: http.httpBasic() defaults AuthenticationEntryPoint --- .../web/configurers/HttpBasicConfigurer.java | 18 +++-- ...leWebSecurityConfigurerAdapterTests.groovy | 15 +++-- .../builders/HttpConfigurationTests.groovy | 20 +++--- .../ExpressionUrlAuthorizationsTests.groovy | 67 ++++++++++--------- .../HttpBasicConfigurerTests.groovy | 63 ++++++++++++++++- .../NamespaceHttpBasicTests.groovy | 4 +- 6 files changed, 130 insertions(+), 57 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java index 174c080c45..654dd74e54 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurer.java @@ -36,20 +36,23 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi * * * *

Shared Objects Created

* - * No shared objects are populated + * * *

Shared Objects Used

* * The following shared objects are used: * * * * @author Rob Winch @@ -58,7 +61,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi public final class HttpBasicConfigurer> extends AbstractHttpConfigurer { private static final String DEFAULT_REALM = "Spring Security Application"; - private AuthenticationEntryPoint authenticationEntryPoint; + private AuthenticationEntryPoint authenticationEntryPoint = new BasicAuthenticationEntryPoint(); private AuthenticationDetailsSource authenticationDetailsSource; /** @@ -114,6 +117,11 @@ public final class HttpBasicConfigurer> extends return this; } + public void init(B http) throws Exception { + http + .setSharedObject(AuthenticationEntryPoint.class, authenticationEntryPoint); + } + @Override public void configure(B http) throws Exception { AuthenticationManager authenticationManager = http.getAuthenticationManager(); diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy index f76d618801..b5dac6ceb2 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy @@ -15,8 +15,9 @@ */ package org.springframework.security.config.annotation.web -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean +import javax.servlet.http.HttpServletResponse + +import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Configuration import org.springframework.core.annotation.Order import org.springframework.security.authentication.AuthenticationManager @@ -38,11 +39,13 @@ public class SampleWebSecurityConfigurerAdapterTests extends BaseWebSpecuritySpe setup: "Sample Config is loaded" loadConfig(HelloWorldWebSecurityConfigurerAdapter) when: + request.addHeader("Accept", "text/html") springSecurityFilterChain.doFilter(request,response,chain) then: response.getRedirectedUrl() == "http://localhost/login" when: "fail to log in" super.setup() + request.addHeader("Accept", "text/html") request.requestURI = "/login" request.method = "POST" springSecurityFilterChain.doFilter(request,response,chain) @@ -213,8 +216,8 @@ public class SampleWebSecurityConfigurerAdapterTests extends BaseWebSpecuritySpe super.setup() request.servletPath = "/api/admin/test" springSecurityFilterChain.doFilter(request,response,chain) - then: "get 403" - response.getStatus() == 403 + then: "get 401" + response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED when: "request API for admins with user" super.setup() @@ -222,7 +225,7 @@ public class SampleWebSecurityConfigurerAdapterTests extends BaseWebSpecuritySpe request.addHeader("Authorization", "Basic " + "user:password".bytes.encodeBase64().toString()) springSecurityFilterChain.doFilter(request,response,chain) then: "get 403" - response.getStatus() == 403 + response.getStatus() == HttpServletResponse.SC_FORBIDDEN when: "request API for admins with admin" super.setup() @@ -230,7 +233,7 @@ public class SampleWebSecurityConfigurerAdapterTests extends BaseWebSpecuritySpe request.addHeader("Authorization", "Basic " + "admin:password".bytes.encodeBase64().toString()) springSecurityFilterChain.doFilter(request,response,chain) then: "get 200" - response.getStatus() == 200 + response.getStatus() == HttpServletResponse.SC_OK } diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/builders/HttpConfigurationTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/builders/HttpConfigurationTests.groovy index 36b4db138d..b52edb40d5 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/builders/HttpConfigurationTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/builders/HttpConfigurationTests.groovy @@ -33,6 +33,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter import org.springframework.web.filter.OncePerRequestFilter +import spock.lang.Unroll; /** * HttpSecurity tests * @@ -82,7 +83,8 @@ public class HttpSecurityTests extends BaseSpringSpec { } - def "requestMatchers() javadoc"() { + @Unroll + def "requestMatchers javadoc"() { setup: "load configuration like the config on the requestMatchers() javadoc" loadConfig(RequestMatcherRegistryConfigs) when: @@ -90,15 +92,15 @@ public class HttpSecurityTests extends BaseSpringSpec { request.servletPath = "/oauth/a" springSecurityFilterChain.doFilter(request, response, chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED where: - servletPath | status - "/oauth/a" | 403 - "/oauth/b" | 403 - "/api/a" | 403 - "/api/b" | 403 - "/oauth2/b" | 200 - "/api2/b" | 200 + servletPath | _ + "/oauth/a" | _ + "/oauth/b" | _ + "/api/a" | _ + "/api/b" | _ + "/oauth2/b" | _ + "/api2/b" | _ } @EnableWebSecurity diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationsTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationsTests.groovy index 6cf6a4fdf1..6f29ef1a49 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationsTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationsTests.groovy @@ -15,19 +15,20 @@ */ package org.springframework.security.config.annotation.web.configurers; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.vote.AffirmativeBased; +import javax.servlet.http.HttpServletResponse + +import org.springframework.beans.factory.BeanCreationException +import org.springframework.context.annotation.Configuration +import org.springframework.security.access.vote.AffirmativeBased import org.springframework.security.authentication.RememberMeAuthenticationToken import org.springframework.security.config.annotation.BaseSpringSpec import org.springframework.security.config.annotation.SecurityExpressions.* -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; -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; +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 +import org.springframework.security.core.authority.AuthorityUtils +import org.springframework.security.web.access.intercept.FilterSecurityInterceptor public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { @@ -112,19 +113,19 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED when: super.setup() login() springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() login("user","ROLE_INVALID") springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_FORBIDDEN } @EnableWebSecurity @@ -145,25 +146,25 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED when: super.setup() login("user","ROLE_ADMIN") springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() login("user","ROLE_DBA") springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() login("user","ROLE_INVALID") springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_FORBIDDEN } @EnableWebSecurity @@ -185,13 +186,13 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { request.remoteAddr = "192.168.1.1" springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED when: super.setup() request.remoteAddr = "192.168.1.0" springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK } @EnableWebSecurity @@ -212,13 +213,13 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() login() springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_FORBIDDEN } @EnableWebSecurity @@ -239,13 +240,13 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED when: super.setup() login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK } @EnableWebSecurity @@ -276,13 +277,13 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED when: super.setup() login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_FORBIDDEN } @EnableWebSecurity @@ -303,13 +304,13 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK } @EnableWebSecurity @@ -330,19 +331,19 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED when: super.setup() login(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER"))) springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 403 + response.status == HttpServletResponse.SC_FORBIDDEN when: super.setup() login() springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == 200 + response.status == HttpServletResponse.SC_OK } @EnableWebSecurity @@ -373,20 +374,20 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: "Access is granted due to GET" - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() login() request.method = "POST" springSecurityFilterChain.doFilter(request,response,chain) then: "Access is granted due to role" - response.status == 200 + response.status == HttpServletResponse.SC_OK when: super.setup() request.method = "POST" springSecurityFilterChain.doFilter(request,response,chain) then: "Access is denied" - response.status == 403 + response.status == HttpServletResponse.SC_UNAUTHORIZED } @EnableWebSecurity diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurerTests.groovy index fc89846053..50daac2eeb 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HttpBasicConfigurerTests.groovy @@ -15,10 +15,16 @@ */ package org.springframework.security.config.annotation.web.configurers +import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.AnyObjectPostProcessor import org.springframework.security.config.annotation.BaseSpringSpec -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; +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 +import org.springframework.security.web.AuthenticationEntryPoint +import org.springframework.security.web.access.ExceptionTranslationFilter +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint import org.springframework.security.web.authentication.www.BasicAuthenticationFilter /** @@ -40,4 +46,57 @@ class HttpBasicConfigurerTests extends BaseSpringSpec { then: "ExceptionTranslationFilter is registered with LifecycleManager" 1 * opp.postProcess(_ as BasicAuthenticationFilter) >> {BasicAuthenticationFilter o -> o} } + + def "SEC-2198: http.httpBasic() defaults AuthenticationEntryPoint"() { + when: + loadConfig(DefaultsEntryPointConfig) + then: + findFilter(ExceptionTranslationFilter).authenticationEntryPoint.class == BasicAuthenticationEntryPoint + } + + @EnableWebSecurity + @Configuration + static class DefaultsEntryPointConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .httpBasic() + } + + @Override + protected void registerAuthentication(AuthenticationManagerBuilder auth) + throws Exception { + auth + .inMemoryAuthentication() + } + } + + def "http.httpBasic().authenticationEntryPoint used for AuthenticationEntryPoint"() { + setup: + CustomAuthenticationEntryPointConfig.ENTRY_POINT = Mock(AuthenticationEntryPoint) + when: + loadConfig(CustomAuthenticationEntryPointConfig) + then: + findFilter(ExceptionTranslationFilter).authenticationEntryPoint == CustomAuthenticationEntryPointConfig.ENTRY_POINT + } + + @EnableWebSecurity + @Configuration + static class CustomAuthenticationEntryPointConfig extends WebSecurityConfigurerAdapter { + static AuthenticationEntryPoint ENTRY_POINT + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .httpBasic() + .authenticationEntryPoint(ENTRY_POINT) + } + + @Override + protected void registerAuthentication(AuthenticationManagerBuilder auth) + throws Exception { + auth + .inMemoryAuthentication() + } + } } diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpBasicTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpBasicTests.groovy index 57e73c2bb6..7bd5a860a8 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpBasicTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpBasicTests.groovy @@ -57,7 +57,7 @@ public class NamespaceHttpBasicTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == HttpServletResponse.SC_FORBIDDEN + response.status == HttpServletResponse.SC_UNAUTHORIZED when: "fail to log in" setup() login("user","invalid") @@ -132,7 +132,7 @@ public class NamespaceHttpBasicTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - response.status == HttpServletResponse.SC_FORBIDDEN + response.status == HttpServletResponse.SC_INTERNAL_SERVER_ERROR when: "fail to log in" setup() login("user","invalid")