访问权限冲突定义_自定义AccessDecisionVoter以实现必须全部拥有请求所需权限才可访问的权限需求...

558ef5a3271dce66d23b8dda76bbbcb6.png

前面我们说了 AccessDecisionVoter 的一些基本用法,以及常用的一些 AccessDecisionVoter 实现,当然,也试着自定义了一个 AccessDecisionVoter

细心的同学可能有所发现,这个自定义的 AccessDecisionVoter 不寻常。为什么呢?因为它内部的授权决策逻辑刚好就是必须拥有当前请求所需的全部权限才会授权成功。同时,这也是这次我们要着重说的内容。

@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
    if (authentication == null) {
        return ACCESS_DENIED;
    }

    int result = ACCESS_ABSTAIN;
    Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication);

    for (ConfigAttribute attribute : attributes) {
        if (this.supports(attribute)) {
            result = ACCESS_DENIED;

            // Attempt to find all matching granted authority
            for (GrantedAuthority authority : authorities) {
                if (attribute.getAttribute().equals(authority.getAuthority())) {
                    result = ACCESS_GRANTED;
                    break;
                }
            }

            if (result == ACCESS_DENIED) {
                return ACCESS_DENIED;
            }
        }
    }

    return result;
}

从代码逻辑中不难判断,只要所需权限,任意一个不再用户授权范围内,即会授权失败。既然如此,那么我们就尝试一下吧。

首先,定义一个新的角色 User_2

INSERT INTO SYS_ROLE(`ID`, `NAME`, `CODE`) VALUES ('617fe676082c40e0a06b9a9646cfb1e7', '普通用户', 'User_2');

然后,将 User_2 角色与 个人中心功能(/user/index)关联起来,即分配个人中心资源权限给 User_2 角色。

INSERT INTO SYS_ROLE_FUNC(`ID`, `ROLE_ID`, `FUNC_ID`) VALUES ('83f1e68a08ac4e1b9b5cd45628f64235', '617fe676082c40e0a06b9a9646cfb1e7', '8fc7c56295e542aaa436c4dbf0048578');

如此一来,个人中心就需要用户同时拥有 UserUser_2 权限才可以访问。

最后,修改一下 Spring Security 的配置,将自定义的 AccessDecisionVoter 配置到 AccessDecisionManager 中。

private AccessDecisionManager accessDecisionManager() {
    List<AccessDecisionVoter<? extends Object>> voters = new ArrayList<>();
    voters.add(new AllMatchRoleVoter());

    return new AffirmativeBased(voters);
}

准备工作就绪,我们启动系统,访问个人中心。登录后,果然跳转到了无权限页面。

0a6069a36d9128aee448023c895cbd78.png

初步验证成功,我们此时再分配 User_2 角色给 zhangsan 用户。

INSERT INTO SYS_USER_ROLE(`ID`, `USER_ID`, `ROLE_ID`) VALUES ('a27108d05c5843bf92eed3ae47ef4220', '2031a4adc78942d59188cea7927e6304', '617fe676082c40e0a06b9a9646cfb1e7');

不用重启系统,我们先访问一下首页(/index)。然后,点击右上角 退出登录 按钮,先退出系统,再登录一次,然后再访问个人中心页面。此时,已经可以正常访问了。

8c469b25865f67b94312b5d8e0f84beb.png

注意,为何我们需要先访问一下首页(/index),然后退出登录,再重新登录一次呢(当然,也可以直接访问退出登录页面 /logout,如果你配置的是这个路径的话)?其实,只要你细心,便不难发现个中缘由。

用户的权限正是在系统登录时,由配置的 UserDetailsService 获取,中途只要不退出系统,便不会再次主动去获取。因此,需要我们退出系统,重新登录一次,才能获取最新分配的权限。当然,重启系统肯定也可以,不过没有必要。

其它详细源码,请参考文末源码链接,可自行下载后阅读。

源码

github

liuminglei/SpringSecurityLearning

gitee

luas/SpringSecurityLearning

我是银河架构师,十年饮冰,难凉热血,愿历尽千帆,归来仍是少年!

如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!


文章不定时更新,可微信搜索「银河架构师」,精彩内容,先睹为快!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值