Java spring security@Secured和HttpSession配置排序

Java spring security@Secured和HttpSession配置排序,java,spring,security,spring-security,Java,Spring,Security,Spring Security,我正在使用Spring-Security(3.2.5.RELEASE)。我尝试实现以下场景: 我的应用程序中有两种用户:普通用户和管理员 我想在控制器方法上使用@Secured注释(用@RequestMapping注释) 未使用@Secured注释的方法我希望所有人(甚至匿名用户)都可以访问 如果常规用户将特定角色传递给@Secured注释,则允许使用@Secured注释的方法。这些方法也应该始终允许管理员用户使用,但我不希望每次使用@Secured注释时都启用角色管理 这是我的HttpSess

我正在使用
Spring-Security
(3.2.5.RELEASE)。我尝试实现以下场景:

  • 我的应用程序中有两种用户:普通用户和管理员
  • 我想在控制器方法上使用
    @Secured
    注释(用
    @RequestMapping
    注释)
  • 未使用
    @Secured
    注释的方法我希望所有人(甚至匿名用户)都可以访问
  • 如果常规用户将特定角色传递给
    @Secured
    注释,则允许使用
    @Secured
    注释的方法。这些方法也应该始终允许管理员用户使用,但我不希望每次使用
    @Secured
    注释时都启用
    角色管理
  • 这是我的HttpSession配置:

    @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/**")
                    .permitAll()
         [...] 
        }
    
    我可以使用
    @Secured
    注释对我的控制器方法进行注释,它可以正常工作。唯一的问题是如何添加url截获匹配器,以允许所有具有角色
    角色\u ADMIN
    的用户在从
    @Secured
    注释方法收集访问规则之前访问。现在看来,
    @Secured
    方法是过滤器链中的第一个,而在上面代码中添加到
    HttpSession
    的规则是最后一个。我如何添加第一个规则(对于
    ROLE\u ADMIN
    permission)和最后一个规则(对于未使用
    @Secured
    permission注释的所有方法),并且
    @Secured
    注释中的所有规则将由这两个规则包装?更清楚地说,我想实现以下目标(在链中):


    好的,我已经做到了,但和问题中的不完全一样。这就是我所做的:

  • 为管理员用户创建自己的
    AccessDecisionVoter
    ,它将始终返回
    ACCESS\u promited
  • 覆盖默认的AccessDecisionManagers创建:两者!!!一个用于url拦截,一个用于方法拦截
  • 这是我的
    AdminPermitVoter

    public class AdminPermitVoter implements AccessDecisionVoter<Object> {
    
        @Override
        public boolean supports(ConfigAttribute attribute) {
            return true;
        }
    
        @Override
        public boolean supports(Class<?> clazz) {
            return true;
        }
    
        @Override
        public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
            if(isAdmin(extractAuthorities(authentication))) {
                return ACCESS_GRANTED;
            }
            return ACCESS_ABSTAIN;
        }
    
        Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
            return authentication.getAuthorities();
        }
    
        private boolean isAdmin(Collection<? extends GrantedAuthority> authorities) {
            for(GrantedAuthority authority : authorities) {
                if(equalsIgnoreCase(ADMIN_ROLE_NAME, authority.getAuthority())) {
                    return true;
                }
            }
    
            return false;
        }
    }
    
    公共类AdminPermitVoter实现AccessDecisionVoter{
    @凌驾
    公共布尔支持(ConfigAttribute){
    返回true;
    }
    @凌驾
    公共布尔支持(类clazz){
    返回true;
    }
    @凌驾
    公共整数投票(身份验证、对象、集合属性){
    if(isAdmin(提取机构(认证))){
    返回已授予的访问权限;
    }
    返回访问(U)弃权;
    }
    收集
    
    public class AdminPermitVoter implements AccessDecisionVoter<Object> {
    
        @Override
        public boolean supports(ConfigAttribute attribute) {
            return true;
        }
    
        @Override
        public boolean supports(Class<?> clazz) {
            return true;
        }
    
        @Override
        public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
            if(isAdmin(extractAuthorities(authentication))) {
                return ACCESS_GRANTED;
            }
            return ACCESS_ABSTAIN;
        }
    
        Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
            return authentication.getAuthorities();
        }
    
        private boolean isAdmin(Collection<? extends GrantedAuthority> authorities) {
            for(GrantedAuthority authority : authorities) {
                if(equalsIgnoreCase(ADMIN_ROLE_NAME, authority.getAuthority())) {
                    return true;
                }
            }
    
            return false;
        }
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .accessDecisionManager(accessDecisionManager())
                .anyRequest()
                .permitAll()
            [...other configs...]
     }
    
    @Bean(name = "accessDecisionManager")
    public AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter> voters = new ArrayList<>();
        voters.add(new AdminPermitVoter());
        voters.add(new WebExpressionVoter());
        voters.add(new RoleVoter());
        voters.add(new AuthenticatedVoter());
        return new AffirmativeBased(voters);
    }
    
    @Configuration
    @EnableGlobalMethodSecurity(securedEnabled = true)
    public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    
        @SuppressWarnings("rawtypes")
        @Override
        protected AccessDecisionManager accessDecisionManager() {
            List<AccessDecisionVoter> voters = new ArrayList<>();
            voters.add(new AdminPermitVoter());
            voters.add(new RoleVoter());
            voters.add(new AuthenticatedVoter());
            return new AffirmativeBased(voters);
        }
    
    }