AccessDecisionManager核心

 

 

AccessDecisionManager
public interface AccessDecisionManager {
    void decide(Authentication var1, Object var2, Collection<ConfigAttribute> var3) throws AccessDeniedException, InsufficientAuthenticationException;

    boolean supports(ConfigAttribute var1);//支持

    boolean supports(Class<?> var1);//支持
}
AbstractAccessDecisionManager
public abstract class AbstractAccessDecisionManager implements AccessDecisionManager, InitializingBean, MessageSourceAware {
    protected final Log logger = LogFactory.getLog(this.getClass());
    private List<AccessDecisionVoter<? extends Object>> decisionVoters;
    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
    private boolean allowIfAllAbstainDecisions = false;

    protected AbstractAccessDecisionManager(List<AccessDecisionVoter<? extends Object>> decisionVoters) {
        Assert.notEmpty(decisionVoters, "A list of AccessDecisionVoters is required");
        this.decisionVoters = decisionVoters;
    }

    public void afterPropertiesSet() throws Exception {
        Assert.notEmpty(this.decisionVoters, "A list of AccessDecisionVoters is required");
        Assert.notNull(this.messages, "A message source must be set");
    }

    protected final void checkAllowIfAllAbstainDecisions() {
        if (!this.isAllowIfAllAbstainDecisions()) {
            throw new AccessDeniedException(this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
        }
    }

    public List<AccessDecisionVoter<? extends Object>> getDecisionVoters() {
        return this.decisionVoters;
    }

    public boolean isAllowIfAllAbstainDecisions() {
        return this.allowIfAllAbstainDecisions;
    }

    public void setAllowIfAllAbstainDecisions(boolean allowIfAllAbstainDecisions) {
        this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
    }

    public void setMessageSource(MessageSource messageSource) {
        this.messages = new MessageSourceAccessor(messageSource);
    }

    public boolean supports(ConfigAttribute attribute) {// 只要有一个匹配,返回true
        Iterator var2 = this.decisionVoters.iterator();

        AccessDecisionVoter voter;
        do {
            if (!var2.hasNext()) {
                return false;
            }

            voter = (AccessDecisionVoter)var2.next();
        } while(!voter.supports(attribute));

        return true;
    }

    public boolean supports(Class<?> clazz) {//只要有一个不匹配,返回false
        Iterator var2 = this.decisionVoters.iterator();

        AccessDecisionVoter voter;
        do {
            if (!var2.hasNext()) {
                return true;
            }

            voter = (AccessDecisionVoter)var2.next();
        } while(voter.supports(clazz));

        return false;
    }
}

AffirmativeBased一票通过

public class AffirmativeBased extends AbstractAccessDecisionManager {
    public AffirmativeBased(List<AccessDecisionVoter<? extends Object>> decisionVoters) {
        super(decisionVoters);
    }

    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException {
        int deny = 0;
        Iterator var5 = this.getDecisionVoters().iterator();

        while(var5.hasNext()) {
            AccessDecisionVoter voter = (AccessDecisionVoter)var5.next();
            int result = voter.vote(authentication, object, configAttributes);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Voter: " + voter + ", returned: " + result);
            }

            switch(result) {
            case -1:
                ++deny;
                break;
            case 1:
                return;
            }
        }

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

 

UnanimousBased一票反对

 

public class UnanimousBased extends AbstractAccessDecisionManager {
    public UnanimousBased(List<AccessDecisionVoter<? extends Object>> decisionVoters) {
        super(decisionVoters);
    }

    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((Object)null);
        Iterator var7 = attributes.iterator();

        while(var7.hasNext()) {
            ConfigAttribute attribute = (ConfigAttribute)var7.next();
            singleAttributeList.set(0, attribute);
            Iterator var9 = this.getDecisionVoters().iterator();

            while(var9.hasNext()) {
                AccessDecisionVoter voter = (AccessDecisionVoter)var9.next();
                int result = voter.vote(authentication, object, singleAttributeList);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Voter: " + voter + ", returned: " + result);
                }

                switch(result) {
                case -1:
                    throw new AccessDeniedException(this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
                case 1:
                    ++grant;
                    break;
                default:
                    ++abstain;
                }
            }
        }

        if (grant <= 0) {
            this.checkAllowIfAllAbstainDecisions();
        }
    }
}

ConsensusBased少数服从多数


public class ConsensusBased extends AbstractAccessDecisionManager {
    private boolean allowIfEqualGrantedDeniedDecisions = true;

    public ConsensusBased(List<AccessDecisionVoter<? extends Object>> decisionVoters) {
        super(decisionVoters);
    }

    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException {
        int grant = 0;
        int deny = 0;
        int abstain = 0;
        Iterator var7 = this.getDecisionVoters().iterator();

        while(var7.hasNext()) {
            AccessDecisionVoter voter = (AccessDecisionVoter)var7.next();
            int result = voter.vote(authentication, object, configAttributes);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Voter: " + voter + ", returned: " + result);
            }

            switch(result) {
            case -1:
                ++deny;
                break;
            case 1:
                ++grant;
                break;
            default:
                ++abstain;
            }
        }

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

    public boolean isAllowIfEqualGrantedDeniedDecisions() {
        return this.allowIfEqualGrantedDeniedDecisions;
    }

    public void setAllowIfEqualGrantedDeniedDecisions(boolean allowIfEqualGrantedDeniedDecisions) {
        this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
    }
}

AccessDecisionVoter访问决策投票器


public interface AccessDecisionVoter<S> {
    int ACCESS_GRANTED = 1;
    int ACCESS_ABSTAIN = 0;
    int ACCESS_DENIED = -1;

    boolean supports(ConfigAttribute var1);

    boolean supports(Class<?> var1);

    int vote(Authentication var1, S var2, Collection<ConfigAttribute> var3);
}

 RoleVoter角色投票
public class RoleVoter implements AccessDecisionVoter<Object> {
    private String rolePrefix = "ROLE_";

    public RoleVoter() {
    }

    public String getRolePrefix() {
        return this.rolePrefix;
    }

    public void setRolePrefix(String rolePrefix) {
        this.rolePrefix = rolePrefix;
    }

    public boolean supports(ConfigAttribute attribute) {//权限不为空并且是以指定的前缀开头,返回true
        return attribute.getAttribute() != null && attribute.getAttribute().startsWith(this.getRolePrefix());
    }

    public boolean supports(Class<?> clazz) {
        return true;
    }

    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
        if (authentication == null) {//如果认证的token为空,直接投反对票
            return -1;
        } else {//如果不为空
            int result = 0;//设置为弃权
            Collection<? extends GrantedAuthority> authorities = this.extractAuthorities(authentication);
            Iterator var6 = attributes.iterator();

            while(true) {//循环,整个循环完成还没有匹配,那么反对
                ConfigAttribute attribute;
                do {
                    if (!var6.hasNext()) {//如果权限的集合为空,投弃权票,如果不为空,并且不匹配,那么投反对票
                        return result;
                    }

                    attribute = (ConfigAttribute)var6.next();
                } while(!this.supports(attribute));//如果权限支持,进行下一步

                result = -1;//先设置为反对
                Iterator var8 = authorities.iterator();

                while(var8.hasNext()) {//循环token,如果有匹配的,选择同意
                    GrantedAuthority authority = (GrantedAuthority)var8.next();
                    if (attribute.getAttribute().equals(authority.getAuthority())) {
                        return 1;
                    }
                }
            }
        }
    }

    Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
        return authentication.getAuthorities();
    }
}
AuthenticatedVoter认证投票

public class AuthenticatedVoter implements AccessDecisionVoter<Object> {
    public static final String IS_AUTHENTICATED_FULLY = "IS_AUTHENTICATED_FULLY";
    public static final String IS_AUTHENTICATED_REMEMBERED = "IS_AUTHENTICATED_REMEMBERED";
    public static final String IS_AUTHENTICATED_ANONYMOUSLY = "IS_AUTHENTICATED_ANONYMOUSLY";
    private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();

    public AuthenticatedVoter() {
    }

    private boolean isFullyAuthenticated(Authentication authentication) {//不是匿名的并且不是记住我的认证,否则为false
        return !this.authenticationTrustResolver.isAnonymous(authentication) && !this.authenticationTrustResolver.isRememberMe(authentication);
    }

    public void setAuthenticationTrustResolver(AuthenticationTrustResolver authenticationTrustResolver) {//设置认证信任分解器
        Assert.notNull(authenticationTrustResolver, "AuthenticationTrustResolver cannot be set to null");
        this.authenticationTrustResolver = authenticationTrustResolver;
    }

    public boolean supports(ConfigAttribute attribute) {//权限不为空 并且 是全部认证或者匿名认证的或者记住我认证的
        return attribute.getAttribute() != null && ("IS_AUTHENTICATED_FULLY".equals(attribute.getAttribute()) ||
"IS_AUTHENTICATED_REMEMBERED".equals(attribute.getAttribute()) || "IS_AUTHENTICATED_ANONYMOUSLY".equals(attribute.getAttribute())); } public boolean supports(Class<?> clazz) { return true; } public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { int result = 0;//暂时设置为弃权 Iterator var5 = attributes.iterator(); ConfigAttribute attribute; do { do { if (!var5.hasNext()) {//属性集合为空,投弃权票, return result; } attribute = (ConfigAttribute)var5.next(); } while(!this.supports(attribute));//如果权限不为空,并且是全部认证或者匿名认证,或者记住我认证的一种,那么进行下一步认证 result = -1;//先设置为反对 if ("IS_AUTHENTICATED_FULLY".equals(attribute.getAttribute()) && this.isFullyAuthenticated(authentication)) { return 1;//如果是全部认证的,投同意 } if ("IS_AUTHENTICATED_REMEMBERED".equals(attribute.getAttribute()) && (this.authenticationTrustResolver.isRememberMe(authentication) || this.isFullyAuthenticated(authentication))) { return 1;//如果是记住我认证的,投同意 } } while(!"IS_AUTHENTICATED_ANONYMOUSLY".equals(attribute.getAttribute()) || !this.authenticationTrustResolver.isAnonymous(authentication) && !this.isFullyAuthenticated(authentication) && !this.authenticationTrustResolver.isRememberMe(authentication)); return 1;//如果是不是匿名认证的,同意 } }
ConfigAttribute
public interface ConfigAttribute extends Serializable {
    String getAttribute();
}

SecurityConfig安全配置

public class SecurityConfig implements ConfigAttribute {
    private final String attrib;

    public SecurityConfig(String config) {
        Assert.hasText(config, "You must provide a configuration attribute");
        this.attrib = config;
    }

    public boolean equals(Object obj) {
        if (obj instanceof ConfigAttribute) {
            ConfigAttribute attr = (ConfigAttribute)obj;
            return this.attrib.equals(attr.getAttribute());
        } else {
            return false;
        }
    }

    public String getAttribute() {
        return this.attrib;
    }

    public int hashCode() {
        return this.attrib.hashCode();
    }

    public String toString() {
        return this.attrib;
    }

    public static List<ConfigAttribute> createListFromCommaDelimitedString(String access) {
        return createList(StringUtils.commaDelimitedListToStringArray(access));
    }

    public static List<ConfigAttribute> createList(String... attributeNames) {//可变参数,传递一组String参数,添加到集合中
        Assert.notNull(attributeNames, "You must supply an array of attribute names");
        List<ConfigAttribute> attributes = new ArrayList(attributeNames.length);//以可变参数的长度创建一个集合
        String[] var2 = attributeNames;//将可变参数赋值给一个数组
        int var3 = attributeNames.length;//获得可变参数的长度

        for(int var4 = 0; var4 < var3; ++var4) {//循环遍历,添加到集合中
            String attribute = var2[var4];
            attributes.add(new SecurityConfig(attribute.trim()));
        }

        return attributes;//返回一个集合
    }
}

AuthenticationTrustResolver认证信任分解器
public interface AuthenticationTrustResolver {
    boolean isAnonymous(Authentication var1);//是否是匿名

    boolean isRememberMe(Authentication var1);//是否是记住我
}

 

AuthenticationTrustResolverImpl认证信任分解器的实现
public class AuthenticationTrustResolverImpl implements AuthenticationTrustResolver {
    private Class<? extends Authentication> anonymousClass = AnonymousAuthenticationToken.class;
    private Class<? extends Authentication> rememberMeClass = RememberMeAuthenticationToken.class;

    public AuthenticationTrustResolverImpl() {
    }

    Class<? extends Authentication> getAnonymousClass() {
        return this.anonymousClass;
    }

    Class<? extends Authentication> getRememberMeClass() {
        return this.rememberMeClass;
    }

    public boolean isAnonymous(Authentication authentication) {
        return this.anonymousClass != null && authentication != null ? this.anonymousClass.isAssignableFrom(authentication.getClass()) : false;
    }

    public boolean isRememberMe(Authentication authentication) {
        return this.rememberMeClass != null && authentication != null ? this.rememberMeClass.isAssignableFrom(authentication.getClass()) : false;
    }

    public void setAnonymousClass(Class<? extends Authentication> anonymousClass) {
        this.anonymousClass = anonymousClass;
    }

    public void setRememberMeClass(Class<? extends Authentication> rememberMeClass) {
        this.rememberMeClass = rememberMeClass;
    }
}

 

 
posted @ 2018-06-07 20:55  chenhonggao  阅读(8048)  评论(0编辑  收藏  举报