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; } }