Spring Security -- FilterInvocationSecurityMetadataSource 與 AccessDecisionManager


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

每天學習一點點,每天進步一點點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM