public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
private static final Log logger = LogFactory.getLog(ProviderManager.class);//记录器
private AuthenticationEventPublisher eventPublisher;//验证事件发布器
private List providers;//认证提供者
protected MessageSourceAccessor messages; //消息源访问器
private AuthenticationManager parent; //父 认证管理器
private boolean eraseCredentialsAfterAuthentication; //擦除安全认证
public ProviderManager(List providers) {//服务管理器
this(providers, (AuthenticationManager)null);
}
public ProviderManager(List providers, AuthenticationManager parent) {
this.eventPublisher = new ProviderManager.NullEventPublisher();//事件发布
this.providers = Collections.emptyList();//赋一个空集合
this.messages = SpringSecurityMessageSource.getAccessor();
this.eraseCredentialsAfterAuthentication = true;
Assert.notNull(providers, "providers list cannot be null");
this.providers = providers;
this.parent = parent;
this.checkState();
}
public void afterPropertiesSet() throws Exception {
this.checkState();
}
private void checkState() {
if (this.parent == null && this.providers.isEmpty()) {
throw new IllegalArgumentException("A parent AuthenticationManager or a list of AuthenticationProviders is required");
}
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null;
Authentication result = null;
boolean debug = logger.isDebugEnabled();
Iterator var6 = this.getProviders().iterator();
while(var6.hasNext()) {
AuthenticationProvider provider = (AuthenticationProvider)var6.next();
if (provider.supports(toTest)) {
if (debug) {
logger.debug("Authentication attempt using " + provider.getClass().getName());
}
try {
result = provider.authenticate(authentication);
if (result != null) {//复制详情
this.copyDetails(authentication, result);
break;
}
} catch (AccountStatusException var11) {//账户状态异常
this.prepareException(var11, authentication);
throw var11;
} catch (InternalAuthenticationServiceException var12) {//内部认证服务异常
this.prepareException(var12, authentication);
throw var12;
} catch (AuthenticationException var13) {//认证异常
lastException = var13;
}
}
}
if (result == null && this.parent != null) {
try {
result = this.parent.authenticate(authentication);
} catch (ProviderNotFoundException var9) {//服务未找到异常
;
} catch (AuthenticationException var10) {//认证异常
lastException = var10;
}
}
if (result != null) {
if (this.eraseCredentialsAfterAuthentication && result instanceof CredentialsContainer) {//擦除密码
((CredentialsContainer)result).eraseCredentials();
}
this.eventPublisher.publishAuthenticationSuccess(result);//事件发布程序。发布认证成功
return result;
} else {
if (lastException == null) {
lastException = new ProviderNotFoundException(this.messages.getMessage("ProviderManager.providerNotFound", new Object[]{toTest.getName()}, "No AuthenticationProvider found for {0}"));
}
this.prepareException((AuthenticationException)lastException, authentication);//事件发布程序,发布认证失败
throw lastException;
}
}
private void prepareException(AuthenticationException ex, Authentication auth) {//准备异常
this.eventPublisher.publishAuthenticationFailure(ex, auth);
}
private void copyDetails(Authentication source, Authentication dest) {//复制详情
if (dest instanceof AbstractAuthenticationToken && dest.getDetails() == null) {
AbstractAuthenticationToken token = (AbstractAuthenticationToken)dest;
token.setDetails(source.getDetails());
}
}
public List getProviders() {//get 认证服务
return this.providers;
}
public void setMessageSource(MessageSource messageSource) {//set信息源
this.messages = new MessageSourceAccessor(messageSource);
}
public void setAuthenticationEventPublisher(AuthenticationEventPublisher eventPublisher) {//set 认证事件发布
Assert.notNull(eventPublisher, "AuthenticationEventPublisher cannot be null");
this.eventPublisher = eventPublisher;
}
public void setEraseCredentialsAfterAuthentication(boolean eraseSecretData) {//set是否测出密码在认证后
this.eraseCredentialsAfterAuthentication = eraseSecretData;
}
public boolean isEraseCredentialsAfterAuthentication() {//是否擦除密码在认证后
return this.eraseCredentialsAfterAuthentication;
}
private static final class NullEventPublisher implements AuthenticationEventPublisher { //认证事件发布
private NullEventPublisher() {//没有事件发布
}
public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {//发布认证失败
}
public void publishAuthenticationSuccess(Authentication authentication) {//发布认证成功
}
}
}