// 用户名,密码认证
// 异常处理:通过过滤器自身捕获异常,将结果放到响应体中,直接返回。
class UsernamePasswordAuthenticationFilter {
//实现类 AntPathRequestMatcher 属性pattern=‘/login’ ,httpMethod=POST
private RequestMatcher requiresAuthenticationRequestMatcher;
// 认证管理器对象
private AuthenticationManager authenticationManager;
// 接口SessionAuthenticationStrategy.onAuthentication(...)
// 实现类NullAuthenticatedSessionStrategy 不做任何处理
// 实现类CompositeSessionAuthenticationStrategy多个策略组合执行
private SessionAuthenticationStrategy sessionStrategy;
// 接口AuthenticationSuccessHandler.onAuthenticationSuccess(...)
// 实现类SimpleUrlAuthenticationSuccessHandler
// 实现类SavedRequestAwareAuthenticationSuccessHandler
// 实现类ForwardAuthenticationSuccessHandler
private AuthenticationSuccessHandler successHandler;
// 接口AuthenticationFailureHandler.onAuthenticationFailure(...)
// ForwardAuthenticationFailureHandler
// SimpleUrlAuthenticationFailureHandler
// ExceptionMappingAuthenticationFailureHandler
// DelegatingAuthenticationFailureHandler多个失败认证处理组合执行
private AuthenticationFailureHandler failureHandler;
void doFilter(ServletRequest req, ServletResponse res, FilterChain chain){
// 放行请求路径不为/login && POST的请求
if (!this.requiresAuthentication(request, response)) {
chain.doFilter(request, response);
} else {
try {
// 调用IOC中的ProviderManager对象进行认证处理
authResult = this.attemptAuthentication(request, response)->{
return this.getAuthenticationManager().authenticate(authRequest);
};
//主要负责处理认证成功的时候session需要执行的逻辑
this.sessionStrategy.onAuthentication(authResult, request, response);
// 捕获AuthenticationException异常
} catch(AuthenticationException var9){
this.unsuccessfulAuthentication(request, response, var8)->{
//清除authResult
SecurityContextHolder.clearContext();
// failureHandler为SimpleUrlAuthenticationFailureHandler
// 其属性defaultFailureUrl=‘/login/?error’
// 其属性RedirectStrategy redirectStrategy = new
// DefaultRedirectStrategy();
this.failureHandler.onAuthenticationFailure(...)->{
//this.defaultFailureUrl != null
// 重定向到/login?error路径,进行登陆
this.redirectStrategy.sendRedirect(request, response,
this.defaultFailureUrl);
}
}
// 过滤链调用结束
return;
}
// 成功之后的认证处理
this.successfulAuthentication(request, response, chain, authResult);
}
}
}
// 异常处理:通过过滤器自身捕获异常,接口AuthenticationEntryPoint.commence()
// 处理异常后,直接返回。
class BasicAuthenticationFilter {
// 接口AuthenticationEntryPoint.commence(...)
// 实现类BasicAuthenticationEntryPoint
// 实现类DelegatingAuthenticationEntryPoint
// 实现类DigestAuthenticationEntryPoint
// 实现类HttpStatusEntryPoint
private AuthenticationEntryPoint authenticationEntryPoint;
//接口AuthenticationDetailsSource.buildDetails(...)
// 实现类WebAuthenticationDetailsSource
// buildDetails(HttpServletRequest context)->{new
// WebAuthenticationDetails(context);}
// 类WebAuthenticationDetails对象的属性String remoteAddress,String sessionId;
private AuthenticationDetailsSource<HttpServletRequest, ?>
authenticationDetailsSource;
void doFilterInternal(...){
String header = request.getHeader("Authorization");
try {
String[] tokens = this.extractAndDecodeHeader(header, request);
UsernamePasswordAuthenticationToken authRequest = new
UsernamePasswordAuthenticationToken(username, tokens[1]);
//接口Authentication.getPrincipal()/isAuthenticated()/getPrincipal()
setAuthenticated(boolean var1)
// 实现类UsernamePasswordAuthenticationToken
// 其中一个属性private Object details;
// 从请求中获取remoteAddress和sessionId构成对象,
// 设置到authRequest.details中
authRequest.setDetails(this.authenticationDetailsSource.buil
dDetails(request));
// 调用认证管理器认证
Authentication authResult =
this.authenticationManager.authenticate(authRequest);
// SecurityContextHolder类
// 属性private static SecurityContextHolderStrategy strategy;
// 接口SecurityContextHolderStrategy.clearContext()/setContext()
// 实现类ThreadLocalSecurityContextHolderStrategy
// 属性private static final ThreadLocal<SecurityContext> contextHolder;
// 实现类 GlobalSecurityContextHolderStrategy
// 属性private static SecurityContext contextHolder;
// 实现类 InheritableThreadLocalSecurityContextHolderStrategy
// 属性private static final ThreadLocal<SecurityContext> contextHolder;
// 接口SecurityContext.getAuthentication()|setAuthentication(...)
// 实现类SecurityContextImpl
// 属性private Authentication authentication
// 该属性储存...AuthenticationToken对象
SecurityContextHolder.getContext().setAuthentication(authResult);
// BasicAuthenticationFilter。onSuccessfulAuthentication(..) doNothing
this.onSuccessfulAuthentication(request, response, authResult);
} catch (AuthenticationException var10){
// DelegatingAuthenticationEntryPoint
// 属性LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>
// entryPoints;
// key=RequestHeaderRequestMatcher类
// 属性expectedHeaderName=X-Requested-With
// 属性expectedHeaderValue=XMLHttpRequest
// value=HttpStatusEntryPoint类
// 属性HttpStatus枚举 UNAUTHORIZED(401, "Unauthorized")
// 属性private AuthenticationEntryPoint defaultEntryPoint;
// realmName = "Realm"
this.authenticationEntryPoint.commence(request, response, var10)->{
BasicAuthenticationEntryPoint.commence()->{
response.addHeader("WWW-Authenticate", "Basic realm=\"" +
this.realmName + "\"");
response.sendError(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
};
return;
}
}
}
//异常处理:捕获FilterSecurityInterceptor中抛出的异常
// 如果异常为AuthenticationException及子类,调用接口AuthenticationEntryPoint.commence
// ()方法的子类实现处理
// 如果异常为AccessDeniedException及子类,调用接口AccessDeniedHandler.handle
// ()方法的子类实现处理
public class ExceptionTranslationFilter {
// 接口AccessDeniedHandler.handle() 处理AccessDeniedException异常
// 实现类DelegatingAccessDeniedHandler
// 实现类AccessDeniedHandlerImpl
// 实现类InvalidSessionAccessDeniedHandler
private AccessDeniedHandler accessDeniedHandler;
// 与BasicAuthenticationFilter类中的authenticationEntryPoint相同
private AuthenticationEntryPoint authenticationEntryPoint;
//接口AuthenticationTrustResolver.isAnonymous()|isRememberMe()
// 实现类AuthenticationTrustResolverImpl
// 属性anonymousClass = AnonymousAuthenticationToken.class;
// 属性rememberMeClass = RememberMeAuthenticationToken;
private AuthenticationTrustResolver authenticationTrustResolver;
public void doFilter(...){
try {
chain.doFilter(request, response)—>{
// FilterInvocation类
// 属性chain,请求,响应
FilterInvocation fi = new FilterInvocation(request, response, chain);
this.invoke(fi)->{
//过滤器仅执行1次的逻辑
InterceptorStatusToken token = super.beforeInvocation(fi)—>{
// 根据url获取Collection<ConfigAttribute>
Collection<ConfigAttribute> attributes =
this.obtainSecurityMetadataSource().getAttributes(object);
//attributes不为null,则
//判断SecurityContextHolder中的authentication.isAuthenticated()
// 为ture,则返回,为false,则调用
// this.authenticationManager.authenticate(authentication)
// 将结果返回
Authentication authenticated = this.authenticateIfRequired();
try {
//AffirmativeBased类
// 属性List<AccessDecisionVoter<T> decisionVoters;
// 值为decisionVoters[0]=WebExpressionVoter
//WebExpressionVoter类
// 属性SecurityExpressionHandler<FilterInvocation>
// expressionHandler;
// 值DefaultWebSecurityExpressionHandler
this.accessDecisionManager.decide(authenticated, object,
attributes);
} catch (AccessDeniedException var7) {
//发布AuthorizationFailureEvent事件
this.publishEvent(new AuthorizationFailureEvent(object,
attributes, authenticated, var7));
// 抛出,由上层捕获
throw var7;
}
if (this.publishAuthorizationSuccess) {
//发布AuthorizedEvent事件
this.publishEvent(new AuthorizedEvent(object, attributes,
authenticated));
}
};
};
};
this.logger.debug("Chain processed normally");
//捕获当前过滤器和接下来的过滤器所抛出的异常
} catch (IOException var9) {
throw var9;
} catch (Exception var10) {
// 获取Cause的异常
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(var10);
// 如果为AuthenticationException的子类,则
RuntimeException ase = (AuthenticationException)this.throwableAnalyzer
.getFirstThrowableOfType(...);
if (ase == null) {
//如果为AccessDeniedException异常及子类,则
ase = (AccessDeniedException)this.thr
owableAnalyzer.getFirstThrowableOfType(...);
}
if (ase == null) {
// 其他情况
if (var10 instanceof ServletException) {
throw (ServletException)var10;
}
if (var10 instanceof RuntimeException) {
throw (RuntimeException)var10;
}
throw new RuntimeException(var10);
}
if (response.isCommitted()) {
throw new ServletException("Unable to handle the Spring Security Exception because the response is already committed.", var10);
}
// 处理异常
this.handleSpringSecurityException(request, response, chain,
(RuntimeException)ase)-{
// 异常为AuthenticationException及子类
if (exception instanceof AuthenticationException) {
// 清除SecurityContext
SecurityContextHolder.getContext().setAuth
entication((Authentication)null);
this.requestCache.saveRequest(request, response);
// 使用AuthenticationEntryPoint的接口实现类处理异常
this.authenticationEntryPoint.commence(request, response, reason);
}else if (exception instanceof AccessDeniedException) {
//如果authentication对象不是AnonymousAuthenticationToken或者
// RememberMeAuthenticationToken,则
//使用AccessDeniedHandler接口的AccessDeniedHandlerImpl实现类
this.accessDeniedHandler.handle(...)—>{
//如果有错误页面,设置响应403,重定向到错误页面
//否则,设置响应403
};
//否则,传入InsufficientAuthenticationException
this.sendStartAuthentication(...);
}
};
}
}
}