FilterInvocationSecurityMetadataSource
前言
FilterInvocationSecurityMetadataSource 翻譯過來叫做:過濾器調用安全元數據源。一般情況下,我們如果需要自定義權限攔截,則需要涉及到 FilterInvocationSecurityMetadataSource 這個接口了。
繼承關系
FilterInvocationSecurityMetadataSource 有一個默認的實現類 DefaultFilterInvocationSecurityMetadataSource,該類的主要功能就是通過當前的請求地址,獲取該地址需要的用戶角色。
FilterInvocationSecurityMetadataSource 接口是一個空接口,沒有任何方法,它繼承自接口 SecurityMetadataSource,接口 SecurityMetadataSource 的源碼如下:
public interface SecurityMetadataSource extends AopInfrastructureBean {
Collection<ConfigAttribute> getAttributes(Object var1) throws IllegalArgumentException;
Collection<ConfigAttribute> getAllConfigAttributes();
boolean supports(Class<?> var1);
}
用法
示例:
@Component
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Autowired
MenuService menuService;
// AntPathMatcher 是一個正則匹配工具
AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
String requestUrl = ((FilterInvocation) o).getFullRequestUrl();
List<Menu> menus = menuService.getAllMenusWithRole();
for (Menu menu: menus){
if (antPathMatcher.match(menu.getUrl(), requestUrl)){
List<Role> roles = menu.getRoles();
String[] str = new String[roles.size()];
for (int i=0; i<roles.size(); i++){
str[i] = roles.get(i).getName();
}
return SecurityConfig.createList(str);
}
}
// 沒有匹配上的,只要登錄之后就可以訪問,這里“ROLE_LOGIN”只是一個標記,有待進一步處理。
return SecurityConfig.createList("ROLE_LOGIN");
}
...
}
這個類的作用是根據用戶傳來的請求地址,分析請求需要的角色,並將所需要的角色放在 Collection中
AccessDecisionManager
前言
AccessDecisionManager 顧名思義,訪問決策管理器。AccessDecisionManager 是一個接口,它有三個實現類:

- AffirmativeBased (默認使用這個)
- ConsensusBased
- UnanimousBased
用法
示例
@Component
public class CustomUrlDecisionManager implements AccessDecisionManager {
@Override
// 用戶的角色在 authentication里,資源需要的角色在 collection 中
public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
for (ConfigAttribute configAttribute : collection) {
String needRole = configAttribute.getAttribute();
if ("ROLE_LOGIN".equals(needRole)){
if (authentication instanceof AnonymousAuthenticationToken){
throw new AccessDeniedException("尚未登錄,請登錄!");
}else {
return;
}
}
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (GrantedAuthority authority : authorities) {
if (authority.getAuthority().equals(needRole)){
return;
}
}
}
throw new AccessDeniedException("權限不足,請聯系管理員!");
}
...
}
這個類的作用:判斷當前用戶是否具備指定的角色。
當前用戶的角色在 authentication中,需要的角色在 collection中,
參考資源
https://blog.csdn.net/lichuangcsdn/article/details/95041605
https://wangsong.blog.csdn.net/article/details/79019510
https://blog.csdn.net/liuminglei1987/article/details/107904526
每天學習一點點,每天進步一點點。
