功能
这是一个抽象类,定义了认证处理的过程。是一个模板类。
处理步骤
- 根据RequestMatcher,判断是否需要进行认证处理。(这里每个filter实现类,都需要传入一个处理的url路径,当我们的请求match这个路径时,才会被该filter处理)
- 进行认证处理
- sesssion处理
- 认证失败的处理
- 允许通过设置属性值continueChainBeforeSuccessfulAuthentication,直接跳过认证成功处理。
- 认证成功的处理
源码
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 判断该filter是否能处理该次请求,即请求的路径和该filter配置要处理的url是否match
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
Authentication authResult;
try {
authResult = attemptAuthentication(request, response);
if (authResult == null) {
//没有得到认证结果,表明子类实现中无法处理该类型的认证
return;
}
sessionStrategy.onAuthentication(authResult, request, response);
}
catch (InternalAuthenticationServiceException failed) {
unsuccessfulAuthentication(request, response, failed);
return;
}
catch (AuthenticationException failed) {
// Authentication failed
unsuccessfulAuthentication(request, response, failed);
return;
}
// 认证成功后,通过设置属性值 continueChainBeforeSuccessfulAuthentication
// 可以跳过认证成功后逻辑的处理
if (continueChainBeforeSuccessfulAuthentication) {
chain.doFilter(request, response);
}
//认证成功后处理
successfulAuthentication(request, response, chain, authResult);
}
认证失败后处理
protected void unsuccessfulAuthentication(HttpServletRequest request,
HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
SecurityContextHolder.clearContext();
// 子类可以配置 rememberMeServices
rememberMeServices.loginFail(request, response);
// 子类可以配置 failureHandler
failureHandler.onAuthenticationFailure(request, response, failed);
}
认证成功后处理
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(authResult);
// 子类可以配置 rememberMeServices
rememberMeServices.loginSuccess(request, response, authResult);
// Fire event 出发成功事件,如果有订阅者,则可以接受到该事件
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
authResult, this.getClass()));
}
// 子类可以配置 successHandler
successHandler.onAuthenticationSuccess(request, response, authResult);
}
如何使用
当然框架中给我们提供了很多实现类,我们可以参照着来实现我们自定义认证处理器。
但是在使用的时候需要注入一些配置,配合使用。
下面列出几个关键的配置项:
- 注入AuthenticationManager来处理子类中定义的 authenticationToken
- 通过 setFilterProcessesUrl 方法设置需要拦截的请求
- 子类通过实现 attemptAuthentication 来尝试认证处理
- 认证成功后,将会将成功认证的信息 Authentication 保存到线程本地 SecurityContext中
- 子类通过注入 rememberMeServices,来进行相应的处理
- 子类通过注入successHandler 和failureHandler来进行相应处理