CSRF 过滤顺序和随机令牌生成
CSRF Filter Orders and Random Token Generating
我在 XSRF 令牌生成和更新必要的 cookie 值方面遇到了一些奇怪的行为。当我加载我网站的登录页面时——一个 Angular front-end 和一个 Spring-boot back-end——生成了一个 XSRF 令牌。不理想,但如果这是正常的并且是预期的,那么我可以接受。转到着陆页时生成的唯一请求是 "GET" 个请求。
我登录应用程序后,它会验证第一个 XSRF-TOKEN 并验证其有效性,然后继续登录。但是,更改 Web 服务上的 XSRF-TOKEN 后会立即生成一个新的 CSRF 令牌。因此,front-end 和后端现在不同步。我不确定如何在成功登录后更新 XSRF-TOKEN 或防止它被更改,因为这似乎没有任何好处......至少从我读过的内容来看。
网络安全
@Override
protected void configure(HttpSecurity http) throws Exception {
CsrfHeaderFilter csrfHeaderFilter = new CsrfHeaderFilter();
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of API URI").permitAll()
.anyRequest().authenticated();
// Configurations for CSRF end points
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
.antMatchers("Login API URI").permitAll()
.and()
.addFilterAfter(csrfHeaderFilter, CsrfFilter.class);
// Logout configurations
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
csrf 部分被分开,希望只有在 post 请求与该 URI 一起发送时才会生成 csrf 令牌。事实似乎并非如此。似乎无论向后端发送什么 URI,都会调用 CSRF Header 过滤器。
CSRF Header 过滤器 -- 必需,因为必须更新 cookie 的域以允许前端和后端访问 XSRF-TOKEN.
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || (token != null && !token.equals(cookie.getValue()))) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
cookie.setDomain(<omitted>);
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
我认为我的过滤器的组织方式存在问题,但我已经尝试了所有方法,从将不同的 http.httpBasic() 部分组合成一个组到对 csrf() 使用 antIgnores,再到不处理带有 GET 请求的 CSRF 令牌。任何指导或建议将不胜感激!
如果您还需要什么,请告诉我,我会尽力提供。
谢谢!
我怀疑过滤顺序有问题。在 Spring-Boot Security 中建立了一个过滤器层次结构。在将值添加到 cookie 之前,需要生成 XSRF-TOKEN。如果在生成新值之前将旧值添加到Cookie,则前后端将不同步,直到执行浏览器刷新。
这就是我在过滤顺序末尾添加过滤器的原因。如果有人有更好的切入点,我会相应地更新它并更新此答案以反映它。
@Override
protected void configure(HttpSecurity http) throws Exception {
CsrfHeaderFilter csrfHeaderFilter = new CsrfHeaderFilter();
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of API URI").permitAll()
.anyRequest().authenticated();
// Configurations for CSRF end points
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
.antMatchers("Login API URI").permitAll()
.and()
.addFilterAfter(csrfHeaderFilter, ExceptionTranslationFilter.class);
// Logout configurations
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
我在 XSRF 令牌生成和更新必要的 cookie 值方面遇到了一些奇怪的行为。当我加载我网站的登录页面时——一个 Angular front-end 和一个 Spring-boot back-end——生成了一个 XSRF 令牌。不理想,但如果这是正常的并且是预期的,那么我可以接受。转到着陆页时生成的唯一请求是 "GET" 个请求。
我登录应用程序后,它会验证第一个 XSRF-TOKEN 并验证其有效性,然后继续登录。但是,更改 Web 服务上的 XSRF-TOKEN 后会立即生成一个新的 CSRF 令牌。因此,front-end 和后端现在不同步。我不确定如何在成功登录后更新 XSRF-TOKEN 或防止它被更改,因为这似乎没有任何好处......至少从我读过的内容来看。
网络安全
@Override
protected void configure(HttpSecurity http) throws Exception {
CsrfHeaderFilter csrfHeaderFilter = new CsrfHeaderFilter();
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of API URI").permitAll()
.anyRequest().authenticated();
// Configurations for CSRF end points
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
.antMatchers("Login API URI").permitAll()
.and()
.addFilterAfter(csrfHeaderFilter, CsrfFilter.class);
// Logout configurations
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
csrf 部分被分开,希望只有在 post 请求与该 URI 一起发送时才会生成 csrf 令牌。事实似乎并非如此。似乎无论向后端发送什么 URI,都会调用 CSRF Header 过滤器。
CSRF Header 过滤器 -- 必需,因为必须更新 cookie 的域以允许前端和后端访问 XSRF-TOKEN.
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || (token != null && !token.equals(cookie.getValue()))) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
cookie.setDomain(<omitted>);
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
我认为我的过滤器的组织方式存在问题,但我已经尝试了所有方法,从将不同的 http.httpBasic() 部分组合成一个组到对 csrf() 使用 antIgnores,再到不处理带有 GET 请求的 CSRF 令牌。任何指导或建议将不胜感激!
如果您还需要什么,请告诉我,我会尽力提供。
谢谢!
我怀疑过滤顺序有问题。在 Spring-Boot Security 中建立了一个过滤器层次结构。在将值添加到 cookie 之前,需要生成 XSRF-TOKEN。如果在生成新值之前将旧值添加到Cookie,则前后端将不同步,直到执行浏览器刷新。
这就是我在过滤顺序末尾添加过滤器的原因。如果有人有更好的切入点,我会相应地更新它并更新此答案以反映它。
@Override
protected void configure(HttpSecurity http) throws Exception {
CsrfHeaderFilter csrfHeaderFilter = new CsrfHeaderFilter();
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("List of API URI").permitAll()
.anyRequest().authenticated();
// Configurations for CSRF end points
http.httpBasic()
.authenticationEntryPoint(new AuthenticationFailureHandler())
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
.antMatchers("Login API URI").permitAll()
.and()
.addFilterAfter(csrfHeaderFilter, ExceptionTranslationFilter.class);
// Logout configurations
http.logout()
.permitAll()
.logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}