如果我们正使用Spring Security提供默认的基于方法的权限认证注解如下:
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public void moveTo(String id, String parentId) {
// ...
}
而在我们自定义实现的GrantedAuthority,或是SS提供的SimpleGrantedAuthority,
public interface GrantedAuthority extends Serializable {
/**
* 这里返回的即是hasAnyRole(..)中的角色
*/
String getAuthority();
}
这里的getAuthority需要加上”ROLE_”的前缀:
public final class SimpleGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final String role;
@Override
public String getAuthority() {
return "Role_" + role;
}
}
否则你会发现
@PreAuthorize 中的角色不能正确被识别,这是因为Spring Security框架内的DefaultMethodSecurityExpressionHandler
在验证表达式时是有”ROLE_”前缀的。
有人就问了,那我就是不想要这个前缀,怎么办?(其实这个人就是我)
两个办法,方法1:定义一个GrantedAuthorityDefaults并注入,that’s all
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}
方法2:在WebSecurityConfigurerAdapter自定义实现中,重写方法,替换默认的DefaultWebSecurityExpressionHandler设置
@Override
public void configure(WebSecurity web) throws Exception {
web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
root.setDefaultRolePrefix(""); //remove the prefix ROLE_
return root;
}
});
}