0

I have some custom roles like:

<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>

when use 'ROLE_USER', the text in "span" can show normally, but when using other roles, the text can't be showed. Then I add 'ROLE_' prefix to my custom roles, it became normal again.

I try to remove the 'ROLE_' prefix constrain like this:

@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();
}

it doesn't work too. Any idea how to remove the mandatory "ROLE_" prefix?

Cherry Zhang
  • 101
  • 1
  • 11
  • Check http://stackoverflow.com/questions/21620076/spring-security-remove-rolevoter-prefix and http://stackoverflow.com/questions/10939792/custom-rolevoter-and-accessing-userrole-for-additional-vote-check – Sully Aug 25 '16 at 10:23

1 Answers1

0

The problem caused by my spring security upgrade to 4.0.3. According the the document Spring security doc,

By default if the supplied role does not start with 'ROLE_' it will be added. This can be customized by modifying the defaultRolePrefix on DefaultWebSecurityExpressionHandler.

I have added the below code to my SecurityConfig.java, and the problem is fixed.

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

Later, I find out the official fix from spring security migrating

One can disable automatic ROLE_ prefixing using a BeanPostProcessor similar to the following:

 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;
}
}

and then defining it as a Bean:

 @Bean
 public static DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
    return new DefaultRolesPrefixPostProcessor();
}
Cherry Zhang
  • 101
  • 1
  • 11