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

    每天学习一点点,每天进步一点点。