我有一些自定义角色,如:
<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_"前缀?
我的spring安全升级到4.0.3导致的问题。根据Spring安全文档
默认情况下,如果提供的角色不以'ROLE_'开头,它将以'ROLE_'开头补充道。这可以通过修改defaultRolePrefix来定制DefaultWebSecurityExpressionHandler .
我已将以下代码添加到我的SecurityConfig.java中,问题已解决。
@Bean
DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {
DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
handler.setDefaultRolePrefix("");
return handler;
}
后来,我从spring安全迁移中找到了官方修复
可以使用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();
}