oauth2 access_denied 不允许访问_自定义AccessDecisionManager实现类选举法(少数服从多数且超过半数同意)的访问决策...

53b2797996dbd82a3997f8225522658d.png

前面讲过 Spring Security 框架实现的一个 AccessDecisionManager,是少数服从多数的授权访问决策。但是,在具体业务场景中,可能还会遇到类似于选举法的授权场景,即少数服从多数且超过半数同意。那么,本次便参考此授权决策方案,自定义一个 AccessDecisionManager

由于核心授权逻辑还是少数服从多数,所以我们部分参考一下 ConsensusBased 的授权决策逻辑。

public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException {
    int grant = 0;
    int deny = 0;

    for (AccessDecisionVoter voter : getDecisionVoters()) {
        int result = voter.vote(authentication, object, configAttributes);

        if (logger.isDebugEnabled()) {
            logger.debug("Voter: " + voter + ", returned: " + result);
        }

        switch (result) {
            case AccessDecisionVoter.ACCESS_GRANTED:
                grant++;

                break;

            case AccessDecisionVoter.ACCESS_DENIED:
                deny++;

                break;

            default:
                break;
        }
    }

    boolean moreThanHalf = moreThanHalf(grant);

    if (grant > deny) {
        if (moreThanHalf) {
            return;
        } else {
            throw new AccessDeniedException(messages.getMessage(
                "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
        }
    }

    if (deny > grant) {
        throw new AccessDeniedException(messages.getMessage(
            "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
    }

    if ((grant == deny) && (grant != 0)) {
        if (this.allowIfEqualGrantedDeniedDecisions && moreThanHalf) {
            return;
        }
        else {
            throw new AccessDeniedException(messages.getMessage(
                "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
        }
    }

    // To get this far, every AccessDecisionVoter abstained
    checkAllowIfAllAbstainDecisions();
}

具体授权决策逻辑为:如果授予权限多于拒绝权限,再看是否授予权限多于半数(投票器总数一半),如果多于半数,则授予权限;否则拒绝授权;如果授予权限等于拒绝权限,同 ConsensusBased 一样,看是否允许两者相等,即 allowIfEqualGrantedDeniedDecisions 参数配置,默认为不允许。如果允许相等,且此时授予权限多于半数,则授予权限,否则拒绝授权。

修改一下 Spring Security 的配置,将新自定义的 AccessDecisionManager 配置上去。

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

    return new MoreThanHalfBased(voters);
}

准备工作就绪后,启动系统,登录系统,访问个人中心页面,此时,由于只有一个 AccessDecisionVoter,半数为0,当前授予权限的 AccessDecisionVoter 为1,超过半数,所以可以正常访问个人中心。

aac36c0d67f84eb3fd2e38a8e678a116.png

如果想要尝试更细致的场景,可以自定义其它的 AccessDecisionVoter ,并配置到该 AccessDecisionManager 中,以达到真正的少数服从多数且超过半数的业务场景。

不过,这好像并不容易。

然而,不管怎么样,其精髓我们掌握了,不是吗?

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

源码

github

liuminglei/SpringSecurityLearning

gitee

luas/SpringSecurityLearning

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

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值