Browse Source

Add ExpressionUrlAuthorizationCOnfigurer tests

- Demo custom expression root
- Demo @Bean in expression example
Rob Winch 11 years ago
parent
commit
1f833b0d6b

+ 93 - 0
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurerConfigs.java

@@ -18,16 +18,23 @@ package org.springframework.security.config.annotation.web.configurers;
 
 import java.util.Arrays;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.access.AccessDecisionVoter;
 import org.springframework.security.access.expression.SecurityExpressionHandler;
+import org.springframework.security.access.expression.SecurityExpressionOperations;
 import org.springframework.security.access.vote.AffirmativeBased;
+import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
+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.Authentication;
 import org.springframework.security.web.FilterInvocation;
 import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
 import org.springframework.security.web.access.expression.WebExpressionVoter;
+import org.springframework.security.web.access.expression.WebSecurityExpressionRoot;
 
 /**
  *
@@ -60,4 +67,90 @@ public class ExpressionUrlAuthorizationConfigurerConfigs {
                 .formLogin();
         }
     }
+
+    @EnableWebSecurity
+    @Configuration
+    static class UseBeansInExpressions extends WebSecurityConfigurerAdapter {
+
+        @Autowired
+        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+            auth
+                .inMemoryAuthentication()
+                    .withUser("user").password("password").roles("USER");
+        }
+
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            http
+                .authorizeRequests()
+                    .antMatchers("/admin/**").hasRole("ADMIN")
+                    .antMatchers("/user/**").hasRole("USER")
+                    .antMatchers("/allow/**").access("@permission.check(authentication,'user')")
+                    .anyRequest().access("@permission.check(authentication,'admin')");
+        }
+
+        @Bean
+        public Checker permission() {
+            return new Checker();
+        }
+
+        static class Checker {
+            public boolean check(Authentication authentication, String customArg) {
+                return authentication.getName().contains(customArg);
+            }
+        }
+    }
+
+    @EnableWebSecurity
+    @Configuration
+    static class CustomExpressionRootConfig extends WebSecurityConfigurerAdapter {
+
+        @Autowired
+        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+            auth
+                .inMemoryAuthentication()
+                    .withUser("user").password("password").roles("USER");
+        }
+
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            http
+                .authorizeRequests()
+                    .expressionHandler(expressionHandler())
+                    .antMatchers("/admin/**").hasRole("ADMIN")
+                    .antMatchers("/user/**").hasRole("USER")
+                    .antMatchers("/allow/**").access("check('user')")
+                    .anyRequest().access("check('admin')");
+        }
+
+        @Bean
+        public CustomExpressionHandler expressionHandler() {
+            return new CustomExpressionHandler();
+        }
+
+        static class CustomExpressionHandler extends DefaultWebSecurityExpressionHandler {
+
+            @Override
+            protected SecurityExpressionOperations createSecurityExpressionRoot(
+                    Authentication authentication, FilterInvocation fi) {
+                WebSecurityExpressionRoot root = new CustomExpressionRoot(authentication, fi);
+                root.setPermissionEvaluator(getPermissionEvaluator());
+                root.setTrustResolver(new AuthenticationTrustResolverImpl());
+                root.setRoleHierarchy(getRoleHierarchy());
+                return root;
+            }
+        }
+
+        static class CustomExpressionRoot extends WebSecurityExpressionRoot {
+
+            public CustomExpressionRoot(Authentication a, FilterInvocation fi) {
+                super(a, fi);
+            }
+
+            public boolean check(String customArg) {
+                Authentication auth = this.getAuthentication();
+                return auth.getName().contains(customArg);
+            }
+        }
+    }
 }

+ 65 - 0
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationsTests.groovy

@@ -31,6 +31,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
 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.ExpressionUrlAuthorizationConfigurerConfigs.CustomExpressionRootConfig;
 import org.springframework.security.core.authority.AuthorityUtils
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor
 
@@ -475,4 +476,68 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec {
         then:
             1 * al.onApplicationEvent(_ as AuthorizedEvent)
     }
+
+    def "Use @permission.check in access"() {
+        setup:
+            loadConfig(UseBeansInExpressions)
+        when: "invoke standard expression that denies access"
+            login()
+            request.servletPath = "/admin/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "standard expression works - get forbidden"
+            response.status == HttpServletResponse.SC_FORBIDDEN
+        when: "invoke standard expression that allows access"
+            super.setup()
+            login()
+            request.servletPath = "/user/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "standard expression works - get ok"
+            response.status == HttpServletResponse.SC_OK
+        when: "invoke custom bean as expression that allows access"
+            super.setup()
+            login()
+            request.servletPath = "/allow/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "custom bean expression allows access"
+            response.status == HttpServletResponse.SC_OK
+        when: "invoke custom bean as expression that denies access"
+            super.setup()
+            login()
+            request.servletPath = "/deny/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "custom bean expression denies access"
+            response.status == HttpServletResponse.SC_FORBIDDEN
+    }
+
+    def "Use custom expressionroot in access"() {
+        setup:
+            loadConfig(CustomExpressionRootConfig)
+        when: "invoke standard expression that denies access"
+            login()
+            request.servletPath = "/admin/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "standard expression works - get forbidden"
+            response.status == HttpServletResponse.SC_FORBIDDEN
+        when: "invoke standard expression that allows access"
+            super.setup()
+            login()
+            request.servletPath = "/user/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "standard expression works - get ok"
+            response.status == HttpServletResponse.SC_OK
+        when: "invoke custom bean as expression that allows access"
+            super.setup()
+            login()
+            request.servletPath = "/allow/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "custom bean expression allows access"
+            response.status == HttpServletResponse.SC_OK
+        when: "invoke custom bean as expression that denies access"
+            super.setup()
+            login()
+            request.servletPath = "/deny/1"
+            springSecurityFilterChain.doFilter(request, response, chain)
+        then: "custom bean expression denies access"
+            response.status == HttpServletResponse.SC_FORBIDDEN
+    }
 }