SpringBoot with XSSFilter fails to authenticate due to missing CSRF Token

我正在使用一个启用了csrf的springboot thymeleaf应用程序。为了防止我的应用程序出现XSS漏洞,我按照这个的教程添加了一个过滤器。我把XSSFilter、XSSRequestWrapper和XSSUtils的文件从这里复制过来。可能我在带状功能中唯一添加的新东西就是这段代码。

String returnValue = Jsoup.clean(value, Whitelist.none());
returnValue = Parser.unescapeEntities(returnValue, true);
return returnValue;

我不得不添加这个,因为Jsoup clean在添加amp;来代替&。

我的应用程序有一个登录页面,只有当用户成功通过认证后,才允许他进入。在没有过滤器的情况下,该应用程序工作得非常好。但是,当我添加了过滤器后,应用程序就不能登录,也不会显示任何错误。这是我的index.html,其中thymeleaf插入了csrf令牌。

<html xmlns:th="http://www.thymeleaf.org"
   xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
   <head id="Head1" >
      <title>Home</title>
      <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
      <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE11"/>
      <meta name="_csrf" th:content="${_csrf.token}"/>
      <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
      <link rel="stylesheet" th:href="@{css_page_specific/index.css}">
      <link rel="stylesheet" th:href="@{css_general/toggle-button-modern.css}">
      <script type="text/javascript" th:src="@{commons.js}"></script>
   </head>
   <form method="post" id="init-form2" th:action="@{/login}"  style="max-width: 350px; margin: 0 auto;">
   <div class="form-group">
      <input type="text" name="username" id="ad-auth-username" placeholder="id">
   </div>
   <div class="form-group">
      <input type="password" name="password" id="ad-auth-password" placeholder="Password">
   </div>

   

这是我的登录控制器。

      @Controller
public class LoginController {

    @GetMapping("/login")
    public String showLoginForm(Model model) {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
            return "login";
        }

        return "redirect:/";
    }

    @GetMapping("/logout")
    public String logoutPage(HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/";
    }
} 

这里是我的网络安全配置。

   @Override
protected void configure(HttpSecurity http) throws Exception {

    http.requiresChannel().anyRequest().requiresSecure().and().authorizeRequests().antMatchers("/login","/css_general/**","/css_page_specific/**","/**/*.js","/**/*.css")
        .permitAll()
        .anyRequest()
        .authenticated()
        .and().formLogin(form -> form
            .loginPage("/login")
            .defaultSuccessUrl("/index.html")
            .failureUrl("/login?error=true")
        )
        .sessionManagement().invalidSessionUrl("/login")
        .and()
        .httpBasic()
       .and()
    .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login").invalidateHttpSession(true).deleteCookies("JSESSIONID")
            .permitAll()
            .and()
            .cors().disable()
            .headers()
            .xssProtection()
            .and()
            .contentSecurityPolicy("script-src 'self'");
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/css_general/**", "/css_page_specific/**","/resources/static/css_general/**","/resources/static/css_page_specific/**","/static/css_page_specific/**","/static/css_general/**");
}

现在在我的过滤器中,如果我不放xss剥离逻辑并放一个断点,我看到它包含3个参数。

username, password and _csrf. 

这个过滤链经过,最终允许传递给csrfFilter,而csrfFilter则成功了。我能够成功登录。

但是,如果我输入XSSFilter代码,我没有看到3个参数中的任何一个被传递,最终csrf过滤器失败,我停留在登录页面上,没有任何错误信息。我知道过滤器是为每个请求调用的,但我检查了每个请求,我就是没有看到这些参数被传递,这就是我怀疑csrfFilter失败的原因。

我怎样才能让xss过滤器工作并成功登录?我只在登录页面使用了thymeleaf,其余的页面只是通过常规的json请求和响应与服务器交换数据。

在没有添加XSSFilter的情况下,成功地进行了认证。在过滤器中收到3个参数 - 用户名、密码和_csrf。添加XSSFilter后,无法认证和登录 - 在过滤器中收到0个参数。我怎样才能将传递给应用程序的所有输入限制为有效的、允许列表的内容,并确保服务器发送的所有响应/输出都是HTML/URL/JavaScript编码的,这取决于应用程序使用数据的环境?


StackOverflow:java - SpringBoot with XSSFilter fails to authenticate due to missing CSRF Token - Stack Overflow