sec:authorize不适用于自定义角色

时间:2016-08-25 09:41:47

标签: spring-mvc spring-security thymeleaf

我有一些自定义角色,如:

<span sec:authentication="principal.authorities">[MENU_USER, BUTTON_ADD_USER,ROLE_USER, MENU_PRIVILEGE, BUTTON_EDIT_USER]</span>
     <div sec:authorize="hasRole('MENU_USER')">
         <span>This content is only shown to administrators.</span>
     </div>

当使用'ROLE_USER'时,“span”中的文本可以正常显示,但是当使用其他角色时,文本无法显示。然后我将'ROLE_'前缀添加到我的自定义角色中,它再次变为正常。

我尝试删除'ROLE_'前缀约束,如下所示:

@Bean
AccessDecisionManager accessDecisionManager() {
    RoleVoter voter = new RoleVoter();
    voter.setRolePrefix("");
    List<AccessDecisionVoter<? extends Object>> voters= new ArrayList<>();

    voters.add(new WebExpressionVoter());
    voters.add(voter);
    voters.add(new AuthenticatedVoter());
    AffirmativeBased decisionManger = new AffirmativeBased(voters);
    return decisionManger;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .accessDecisionManager(accessDecisionManager())
            .antMatchers("/webjars/**", "/login").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
            .loginProcessingUrl("/j_spring_security_check")
            .usernameParameter("j_username")
            .passwordParameter("j_password")
            .defaultSuccessUrl("/home", true)
            .failureUrl("/test")
            .and()

         //logout is    
        .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login?logout")
        .permitAll();
}

它也不起作用。知道如何删除强制性“ROLE_”前缀?

1 个答案:

答案 0 :(得分:0)

我的Spring安全性升级到4.0.3引起的问题。根据文件Spring security doc

  

默认情况下,如果提供的角色不是以&#39; ROLE _&#39;这将是   添加。这可以通过修改defaultRolePrefix来自定义   DefaultWebSecurityExpressionHandler。

我已将以下代码添加到我的SecurityConfig.java中,问题已修复。

@Bean
DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {
    DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
    handler.setDefaultRolePrefix("");
    return handler;
}

稍后,我会从spring security migrating

中找到官方修正案
  

可以使用BeanPostProcessor禁用自动ROLE_前缀   类似于以下内容:

 package sample.role_;

 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.core.PriorityOrdered;
 import   org.springframework.security.access.annotation.Jsr250MethodSecurityMetadataSource;
 import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
 import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
 import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;

 public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor,   PriorityOrdered {

@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
        throws BeansException {

    // remove this if you are not using JSR-250
    if(bean instanceof Jsr250MethodSecurityMetadataSource) {
        ((Jsr250MethodSecurityMetadataSource) bean).setDefaultRolePrefix(null);
    }

    if(bean instanceof DefaultMethodSecurityExpressionHandler) {
        ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
    }
    if(bean instanceof DefaultWebSecurityExpressionHandler) {
        ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
    }
    if(bean instanceof SecurityContextHolderAwareRequestFilter) {
        ((SecurityContextHolderAwareRequestFilter)bean).setRolePrefix("");
    }
    return bean;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
        throws BeansException {
    return bean;
}

@Override
public int getOrder() {
    return PriorityOrdered.HIGHEST_PRECEDENCE;
}
}
  

然后将其定义为Bean:

 @Bean
 public static DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
    return new DefaultRolesPrefixPostProcessor();
}