[SpringSecurity5.6.2源码分析十六]:DefaultLoginPageGeneratingFilter和DefaultLogoutPageGe

208 阅读1分钟

前言

  • 在SpringSecurity中是有默认的登录页和登出页面的
  • 登录页:image.png
  • 登出页:image.png

1. DefaultLoginPageConfigurer

  • DefaultLoginPageConfigurer作为登录页过滤器和登出页过滤器的配置类
  • 由于默认的登录页和登出页都没什么好配置的,所以其方法也很少

1.1 init(...)

  • 这个方法主要是注册一个解析隐藏域的函数,这样在登录页登出页发起请求时就能携带CsrfToken给服务器了
@Override
public void init(H http) {
   //为登入和登出页过滤器设置获取Csrf令牌的函数
   Function<HttpServletRequest, Map<String, String>> hiddenInputs = request -> {
      CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
      if (token == null) {
         return Collections.emptyMap();
      }
      return Collections.singletonMap(token.getParameterName(), token.getToken());
   };
   this.loginPageGeneratingFilter.setResolveHiddenInputs(hiddenInputs);
   this.logoutPageGeneratingFilter.setResolveHiddenInputs(hiddenInputs);
   http.setSharedObject(DefaultLoginPageGeneratingFilter.class,
         loginPageGeneratingFilter);
}

1.2 configure(...)

public void configure(H http) {
   AuthenticationEntryPoint authenticationEntryPoint = null;
   //从异常处理配置类中获取身份验证入口点
   ExceptionHandlingConfigurer<?> exceptionConf = http.getConfigurer(ExceptionHandlingConfigurer.class);
   if (exceptionConf != null) {
      authenticationEntryPoint = exceptionConf.getAuthenticationEntryPoint();
   }
   //当过滤器可用并且没有身份验证入口点的时候
   if (this.loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) {
      this.loginPageGeneratingFilter = postProcess(this.loginPageGeneratingFilter);
      //添加登入过滤器到HttpSecurity中
      http.addFilter(this.loginPageGeneratingFilter);
      //当配置了登出配置类的时候,才加入登出过滤器
      LogoutConfigurer<H> logoutConfigurer = http.getConfigurer(LogoutConfigurer.class);
      if (logoutConfigurer != null) {
         http.addFilter(this.logoutPageGeneratingFilter);
      }
   }
}

2. DefaultLoginPageGeneratingFilter

  • DefaultLogoutPageGeneratingFilter:生成一个默认的登录页面
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
      throws IOException, ServletException {
   //是否是认证失败Url的请求
   boolean loginError = isErrorPage(request);
   //是否是登出成功的请求
   boolean logoutSuccess = isLogoutSuccess(request);
   //判断是否需要生产登录页
   if (isLoginUrlRequest(request) || loginError || logoutSuccess) {
      String loginPageHtml = generateLoginPageHtml(request, loginError, logoutSuccess);
      response.setContentType("text/html;charset=UTF-8");
      response.setContentLength(loginPageHtml.getBytes(StandardCharsets.UTF_8).length);
      response.getWriter().write(loginPageHtml);
      return;
   }
   chain.doFilter(request, response);
}

3. DefaultLogoutPageGeneratingFilter

  • DefaultLogoutPageGeneratingFilter:生成一个默认的注销页面
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws ServletException, IOException {
   //确定是否是登出请求
   if (this.matcher.matches(request)) {
      // 生成登出页
      renderLogout(request, response);
   }
   else {
      if (logger.isTraceEnabled()) {
         logger.trace(LogMessage.format("Did not render default logout page since request did not match [%s]",
               this.matcher));
      }
      filterChain.doFilter(request, response);
   }
}