为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Security权限框架理论与实战(五)- 自定义决策

标签:
Spring

AbstractAccessDecisionManager

webp


webp


核心方法


webp


其中的决策类类型-投票器

webp


看一下最常见的投票器


webp


webp


webp

定义了权限前缀


核心方法自然为选举方法

webp

三大投票器

AffirmativeBased

一票通过


webp

/**
 * Simple concrete implementation of
 * {@link org.springframework.security.access.AccessDecisionManager} that grants access if
 * any <code>AccessDecisionVoter</code> returns an affirmative response.
 */public class AffirmativeBased extends AbstractAccessDecisionManager {    public AffirmativeBased(List<AccessDecisionVoter<? extends Object>> decisionVoters) {        super(decisionVoters);
    }    // ~ Methods
    // ========================================================================================================

    /**
     * This concrete implementation simply polls all configured
     * {@link AccessDecisionVoter}s and grants access if any
     * <code>AccessDecisionVoter</code> voted affirmatively. Denies access only if there
     * was a deny vote AND no affirmative votes.
     * <p>
     * If every <code>AccessDecisionVoter</code> abstained from voting, the decision will
     * be based on the {@link #isAllowIfAllAbstainDecisions()} property (defaults to
     * false).
     * </p>
     *
     * @param authentication the caller invoking the method
     * @param object the secured object
     * @param configAttributes the configuration attributes associated with the method
     * being invoked
     *
     * @throws AccessDeniedException if access is denied
     */
    public void decide(Authentication authentication, Object object,
            Collection<ConfigAttribute> configAttributes) throws AccessDeniedException {        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:                return;            case AccessDecisionVoter.ACCESS_DENIED:
                deny++;                break;            default:                break;
            }
        }        if (deny > 0) {            throw new AccessDeniedException(messages.getMessage(                    "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
        }        // To get this far, every AccessDecisionVoter abstained
        checkAllowIfAllAbstainDecisions();
    }
}

ConsensusBased

一半以上功能选举通过


webp

/**
 * Simple concrete implementation of
 * {@link org.springframework.security.access.AccessDecisionManager} that uses a
 * consensus-based approach.
 * <p>
 * "Consensus" here means majority-rule (ignoring abstains) rather than unanimous
 * agreement (ignoring abstains). If you require unanimity, please see
 * {@link UnanimousBased}.
 */public class ConsensusBased extends AbstractAccessDecisionManager {    // ~ Instance fields
    // ================================================================================================

    private boolean allowIfEqualGrantedDeniedDecisions = true;    public ConsensusBased(List<AccessDecisionVoter<? extends Object>> decisionVoters) {        super(decisionVoters);
    }    // ~ Methods
    // ========================================================================================================

    /**
     * This concrete implementation simply polls all configured
     * {@link AccessDecisionVoter}s and upon completion determines the consensus of
     * granted against denied responses.
     * <p>
     * If there were an equal number of grant and deny votes, the decision will be based
     * on the {@link #isAllowIfEqualGrantedDeniedDecisions()} property (defaults to true).
     * <p>
     * If every <code>AccessDecisionVoter</code> abstained from voting, the decision will
     * be based on the {@link #isAllowIfAllAbstainDecisions()} property (defaults to
     * false).
     *
     * @param authentication the caller invoking the method
     * @param object the secured object
     * @param configAttributes the configuration attributes associated with the method
     * being invoked
     *
     * @throws AccessDeniedException if access is denied
     */
    public void decide(Authentication authentication, Object object,
            Collection<ConfigAttribute> configAttributes) throws AccessDeniedException {        int grant = 0;        int deny = 0;        int abstain = 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:
                abstain++;                break;
            }
        }        if (grant > deny) {            return;
        }        if (deny > grant) {            throw new AccessDeniedException(messages.getMessage(                    "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
        }        if ((grant == deny) && (grant != 0)) {            if (this.allowIfEqualGrantedDeniedDecisions) {                return;
            }            else {                throw new AccessDeniedException(messages.getMessage(                        "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
            }
        }        // To get this far, every AccessDecisionVoter abstained
        checkAllowIfAllAbstainDecisions();
    }    public boolean isAllowIfEqualGrantedDeniedDecisions() {        return allowIfEqualGrantedDeniedDecisions;
    }    public void setAllowIfEqualGrantedDeniedDecisions(            boolean allowIfEqualGrantedDeniedDecisions) {        this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
    }
}

UnanimousBased

全票通过才可


webp

/**
 * Simple concrete implementation of
 * {@link org.springframework.security.access.AccessDecisionManager} that requires all
 * voters to abstain or grant access.
 */public class UnanimousBased extends AbstractAccessDecisionManager {    public UnanimousBased(List<AccessDecisionVoter<? extends Object>> decisionVoters) {        super(decisionVoters);
    }    // ~ Methods
    // ========================================================================================================

    /**
     * This concrete implementation polls all configured {@link AccessDecisionVoter}s for
     * each {@link ConfigAttribute} and grants access if <b>only</b> grant (or abstain)
     * votes were received.
     * <p>
     * Other voting implementations usually pass the entire list of
     * <tt>ConfigAttribute</tt>s to the <code>AccessDecisionVoter</code>. This
     * implementation differs in that each <code>AccessDecisionVoter</code> knows only
     * about a single <code>ConfigAttribute</code> at a time.
     * <p>
     * If every <code>AccessDecisionVoter</code> abstained from voting, the decision will
     * be based on the {@link #isAllowIfAllAbstainDecisions()} property (defaults to
     * false).
     *
     * @param authentication the caller invoking the method
     * @param object the secured object
     * @param attributes the configuration attributes associated with the method being
     * invoked
     *
     * @throws AccessDeniedException if access is denied
     */
    public void decide(Authentication authentication, Object object,
            Collection<ConfigAttribute> attributes) throws AccessDeniedException {        int grant = 0;        int abstain = 0;

        List<ConfigAttribute> singleAttributeList = new ArrayList<>(1);
        singleAttributeList.add(null);        for (ConfigAttribute attribute : attributes) {
            singleAttributeList.set(0, attribute);            for (AccessDecisionVoter voter : getDecisionVoters()) {                int result = voter.vote(authentication, object, singleAttributeList);                if (logger.isDebugEnabled()) {
                    logger.debug("Voter: " + voter + ", returned: " + result);
                }                switch (result) {                case AccessDecisionVoter.ACCESS_GRANTED:
                    grant++;                    break;                case AccessDecisionVoter.ACCESS_DENIED:                    throw new AccessDeniedException(messages.getMessage(                            "AbstractAccessDecisionManager.accessDenied",                            "Access is denied"));                default:
                    abstain++;                    break;
                }
            }
        }        // To get this far, there were no deny votes
        if (grant > 0) {            return;
        }        // To get this far, every AccessDecisionVoter abstained
        checkAllowIfAllAbstainDecisions();
    }
}



作者:芥末无疆sss
链接:https://www.jianshu.com/p/d264f8b6ae64


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消