如果我們正使用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;@Overridepublic String getAuthority() {
return "Role_" + role;}}
否則你會發現
@PreAuthorize 中的角色不能正確被識別,這是因為Spring Security框架內的DefaultMethodSecurityExpressionHandler
在驗證表達式時是有”ROLE_”前綴的。
有人就問了,那我就是不想要這個前綴,怎么辦?(其實這個人就是我)
兩個辦法,方法1:定義一個GrantedAuthorityDefaults並注入,that’s all
@BeanGrantedAuthorityDefaults grantedAuthorityDefaults() {return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix}
方法2:在WebSecurityConfigurerAdapter自定義實現中,重寫方法,替換默認的DefaultWebSecurityExpressionHandler設置
@Overridepublic void configure(WebSecurity web) throws Exception {web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
@Overrideprotected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
root.setDefaultRolePrefix(""); //remove the prefix ROLE_
return root;
}});}