Spring Security 动态url权限控制

基础准备:

1.一些基础依赖,lombok,security

2.基础的controller,mapper,pojo,service建好

 3.先实现自定义用户登录

UserServiceImpl.java
 
SecurityConfig.java

4.完成基础自定义用户登录之后,开始给用户设置权限了。

        4.1 User.java要实现UserDetails,并重写里面的方法

                

        4.2 UserServiceImpl.java这里进行一些修改

                

 

运行一下程序,打印一下登录用户拥有什么角色,效果:

 

5.接下来是进行过滤器的编写了。

@Component
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    //用来路径匹配的一个工具类
    AntPathMatcher pathMatcher = new AntPathMatcher();

    @Autowired
    MenuService menuService;

    //主要业务在这里写
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        //获取当前的请求路径
        String requestUrl = ((FilterInvocation) o).getRequestUrl();
        System.out.println("我请求的url是>>>"+requestUrl);

        //查询所有的菜单
        List<Menu> menus = menuService.getAllMenus();

        System.out.println(menus);

        //遍历菜单
        for (Menu menu : menus) {
            //与请求地址进行匹配
            if (pathMatcher.match(menu.getPattern(),requestUrl)){
                //此处为地址匹配上的业务
                //1.从查询到的菜单集合中,拿到对应的角色
                List<Role> roles = menu.getRoles();
                //2.把结果return出去
                String[] roleArr = new String[roles.size()];
                for (int i = 0; i < roleArr.length; i++) {
                    roleArr[i] = roles.get(i).getName();
                    System.out.println(roleArr);
                }
                return SecurityConfig.createList(roleArr);
            }
        }
        //这是地址匹配不上的,那么就给一个ROLE_login作为标识符
        return SecurityConfig.createList("ROLE_login");

    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
}

再看看控制台,看看对应的角色是不是也设置上去了

以上完成了根据url分析出该url需要的角色

下一步就是判断当前登录用户有没有对应的角色

@Component
//该类是根据过滤器执行完返回的configAttributes,判断是否登录成功
public class MyAccessDecisionManager implements AccessDecisionManager {
    /**
     *
     * @param authentication 当前登录的用户
     * @param object
     * @param configAttributes 过滤器返回的值
     * @throws AccessDeniedException
     * @throws InsufficientAuthenticationException
     */
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        //1.过滤器返回的值,根据“ROLE_XXX“,判断是不是与请求地址匹配
        //匹配不上就给用户加上”ROLE_login“
        for (ConfigAttribute attribute : configAttributes) {
            //如果是ROLE_login,说明没有匹配上地址
            if ("ROLE_login".equals(attribute.getAttribute())){
                if (authentication instanceof AnonymousAuthenticationToken){
                    //没有登录
                    throw new AccessDeniedException("请登录");
                }
                else {
                    //登录了
                    return;
                }
            }

            //地址匹配上
            //1.当前用户拥有的角色
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                //如果当前用户拥有的角色 跟 请求地址所需要的角色匹配上的话
                if (authority.getAuthority().equals(attribute.getAttribute())){

                    System.out.println("我具备的角色>>>"+authority.getAuthority()+" 和 所需要的角色"+attribute.getAttribute()+" 匹配上咯");
                    return;
                }
            }

            //以上两个情况都没有,抛出一个异常
            throw new AccessDeniedException("非法请求");


        }


    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return false;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
}

以上两个类都要交给Spring管理,然后在SecurityConfig中注入

 

测试结果:

在地址栏输入”localhost:9009/admin/hello

首先是要你登录

但是在此之前,MyFilterInvocationSecurityMetadataSource.java会发生作用,根据我们输入的url判断出该url需要哪些角色,我在控制栏中打印了一下:

说明 /admin/hello 这个url是需要角色为admin的用户才能访问

此时MyFilterInvocationSecurityMetadataSource.java这个类的返回值就是url所需的角色

下一步,用户登录成功后,同时会查询该用户拥有哪些角色

我登录的是root用户,拥有dba和admin的角色

 到此,该用户是可以访问localhost:9009/admin/hello这个地址的

 

 用角色为user的用户登录,看看访问能不能访问admin/hello

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值