@@ -27,6 +27,9 @@ import org.springframework.beans.factory.config.BeanPostProcessor
27
27
import org.springframework.context.ApplicationListener
28
28
import org.springframework.context.annotation.Bean
29
29
import org.springframework.security.access.AccessDecisionManager ;
30
+ import org.springframework.security.access.PermissionEvaluator
31
+ import org.springframework.security.access.hierarchicalroles.RoleHierarchy
32
+ import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl
30
33
import org.springframework.security.access.event.AuthorizedEvent
31
34
import org.springframework.security.access.vote.AffirmativeBased
32
35
import org.springframework.security.authentication.RememberMeAuthenticationToken
@@ -37,6 +40,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity
37
40
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
38
41
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
39
42
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurerConfigs.CustomExpressionRootConfig
43
+ import org.springframework.security.core.Authentication
40
44
import org.springframework.security.core.authority.AuthorityUtils
41
45
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor
42
46
@@ -572,4 +576,119 @@ public class ExpressionUrlAuthorizationConfigurerTests extends BaseSpringSpec {
572
576
}
573
577
574
578
}
579
+
580
+ def " permissionEvaluator autowired" () {
581
+ setup :
582
+ loadConfig(PermissionEvaluatorConfig )
583
+ when : " invoke hasPermission expression that allows access"
584
+ super . setup()
585
+ login()
586
+ request. servletPath = " /allow/1"
587
+ springSecurityFilterChain. doFilter(request, response, chain)
588
+ then : " permissionEvaluator with id and type works - allows access"
589
+ response. status == HttpServletResponse . SC_OK
590
+ when : " invoke hasPermission expression that denies access"
591
+ super . setup()
592
+ login()
593
+ request. servletPath = " /deny/1"
594
+ springSecurityFilterChain. doFilter(request, response, chain)
595
+ then : " permissionEvaluator with id and type works - denies access"
596
+ response. status == HttpServletResponse . SC_FORBIDDEN
597
+ when : " invoke hasPermission expression that allows access"
598
+ super . setup()
599
+ login()
600
+ request. servletPath = " /allowObject/1"
601
+ springSecurityFilterChain. doFilter(request, response, chain)
602
+ then : " permissionEvaluator with object works - allows access"
603
+ response. status == HttpServletResponse . SC_OK
604
+ when : " invoke hasPermission expression that denies access"
605
+ super . setup()
606
+ login()
607
+ request. servletPath = " /denyObject/1"
608
+ springSecurityFilterChain. doFilter(request, response, chain)
609
+ then : " permissionEvaluator with object works - denies access"
610
+ response. status == HttpServletResponse . SC_FORBIDDEN
611
+ }
612
+
613
+ @EnableWebSecurity
614
+ static class PermissionEvaluatorConfig extends WebSecurityConfigurerAdapter {
615
+ @Override
616
+ protected void configure (HttpSecurity http ) throws Exception {
617
+ http
618
+ .authorizeRequests()
619
+ .antMatchers(" /allow/**" ). access(" hasPermission('ID', 'TYPE', 'PERMISSION')" )
620
+ .antMatchers(" /allowObject/**" ). access(" hasPermission('TESTOBJ', 'PERMISSION')" )
621
+ .antMatchers(" /deny/**" ). access(" hasPermission('ID', 'TYPE', 'NO PERMISSION')" )
622
+ .antMatchers(" /denyObject/**" ). access(" hasPermission('TESTOBJ', 'NO PERMISSION')" )
623
+ .anyRequest(). permitAll();
624
+ }
625
+
626
+ @Override
627
+ protected void configure (AuthenticationManagerBuilder auth ) throws Exception {
628
+ auth
629
+ .inMemoryAuthentication()
630
+ .withUser(" user" ). password(" password" ). roles(" USER" )
631
+ }
632
+
633
+ @Bean
634
+ public PermissionEvaluator permissionEvaluator (){
635
+ return new PermissionEvaluator (){
636
+ @Override
637
+ public boolean hasPermission (Authentication authentication , Object targetDomainObject , Object permission ) {
638
+ return " TESTOBJ" . equals(targetDomainObject) && " PERMISSION" . equals(permission);
639
+ }
640
+ @Override
641
+ public boolean hasPermission (Authentication authentication , Serializable targetId , String targetType ,
642
+ Object permission ) {
643
+ return " ID" . equals(targetId) && " TYPE" . equals(targetType) && " PERMISSION" . equals(permission);
644
+ }
645
+ };
646
+ }
647
+
648
+ }
649
+
650
+ @EnableWebSecurity
651
+ static class RoleHierarchyConfig extends WebSecurityConfigurerAdapter {
652
+ @Override
653
+ protected void configure (HttpSecurity http ) throws Exception {
654
+ http
655
+ .authorizeRequests()
656
+ .antMatchers(" /allow/**" ). access(" hasRole('XXX')" )
657
+ .antMatchers(" /deny/**" ). access(" hasRole('NOPE')" )
658
+ .anyRequest(). permitAll();
659
+ }
660
+
661
+ @Override
662
+ protected void configure (AuthenticationManagerBuilder auth ) throws Exception {
663
+ auth
664
+ .inMemoryAuthentication()
665
+ .withUser(" user" ). password(" password" ). roles(" USER" )
666
+ }
667
+
668
+ @Bean
669
+ public RoleHierarchy roleHierarchy (){
670
+ return new RoleHierarchyImpl (" USER > XXX" );
671
+ }
672
+
673
+ }
674
+
675
+ def " roleHierarchy autowired" () {
676
+ setup :
677
+ loadConfig(PermissionEvaluatorConfig )
678
+ when : " invoke roleHierarchy expression that allows access"
679
+ super . setup()
680
+ login()
681
+ request. servletPath = " /allow/1"
682
+ springSecurityFilterChain. doFilter(request, response, chain)
683
+ then : " permissionEvaluator with id and type works - allows access"
684
+ response. status == HttpServletResponse . SC_OK
685
+ when : " invoke roleHierarchy expression that denies access"
686
+ super . setup()
687
+ login()
688
+ request. servletPath = " /deny/1"
689
+ springSecurityFilterChain. doFilter(request, response, chain)
690
+ then : " permissionEvaluator with id and type works - denies access"
691
+ response. status == HttpServletResponse . SC_FORBIDDEN
692
+ }
693
+
575
694
}
0 commit comments