瀏覽代碼

SEC-2198: http.httpBasic() defaults AuthenticationEntryPoint

Rob Winch 12 年之前
父節點
當前提交
87c9a14bff

+ 13 - 5
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
  *
  * <ul>
  * <li>
- * {@link BasicAuthenticationFilter}
- * </li>
+ * {@link BasicAuthenticationFilter}</li>
  * </ul>
  *
  * <h2>Shared Objects Created</h2>
  *
- * No shared objects are populated
+ * <ul>
+ * <li>AuthenticationEntryPoint - populated with the
+ * {@link #authenticationEntryPoint(AuthenticationEntryPoint)} (default
+ * {@link BasicAuthenticationEntryPoint})</li>
+ * </ul>
  *
  * <h2>Shared Objects Used</h2>
  *
  * The following shared objects are used:
  *
  * <ul>
- * <li>{@link HttpSecurity#getAuthenticationManager()} </li>
+ * <li>{@link HttpSecurity#getAuthenticationManager()}</li>
  * </ul>
  *
  * @author Rob Winch
@@ -58,7 +61,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi
 public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>> extends AbstractHttpConfigurer<B> {
     private static final String DEFAULT_REALM = "Spring Security Application";
 
-    private AuthenticationEntryPoint authenticationEntryPoint;
+    private AuthenticationEntryPoint authenticationEntryPoint = new BasicAuthenticationEntryPoint();
     private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
 
     /**
@@ -114,6 +117,11 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>> 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();

+ 9 - 6
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
     }
 
 

+ 11 - 9
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

+ 34 - 33
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

+ 61 - 2
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()
+        }
+    }
 }

+ 2 - 2
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")