Spring安全性-在/注销时CSRF令牌无效
我有一个应用程序,使用Thymeleaf模板和Spring引导配置。在使用某些端点的同时,我遇到了一个无效的CSRF令牌问题。应用程序在cookies中存储CSRF令牌 在其中一个模板上,当我没有在中包含任何链接(样式表)和脚本(JS)时,注销按钮就是,一切正常。但是,当我包含任何或头时,就会出现“本地主机的CSRF令牌无效:/logout”问题 Spring安全配置:Spring安全性-在/注销时CSRF令牌无效,spring,spring-boot,spring-security,thymeleaf,csrf,Spring,Spring Boot,Spring Security,Thymeleaf,Csrf,我有一个应用程序,使用Thymeleaf模板和Spring引导配置。在使用某些端点的同时,我遇到了一个无效的CSRF令牌问题。应用程序在cookies中存储CSRF令牌 在其中一个模板上,当我没有在中包含任何链接(样式表)和脚本(JS)时,注销按钮就是,一切正常。但是,当我包含任何或头时,就会出现“本地主机的CSRF令牌无效:/logout”问题 Spring安全配置: @Configuration @EnableWebSecurity @Slf4j public class WebSecuri
@Configuration
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.authenticationProvider(authenticationProvider())
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.csrfTokenRepository(new CookieCsrfTokenRepository())
// .disable()
.and()
.exceptionHandling()
.accessDeniedPage("/dashboard")
.and()
.httpBasic()
.disable()
.addFilterBefore(customFilter(), OAuth2LoginAuthenticationFilter.class)
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/", "/home", "/webjars/**", "/static/**", "/css/**", "/js/**")
.permitAll()
.antMatchers("/",
"/home",
"/webjars/**",
"/error",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/logon","/login/**", "/oauth2_register/**","/register/**")
.anonymous()
.anyRequest()
.authenticated()
.and()
.formLogin()
.disable()
.logout()
.deleteCookies("access_token")
.permitAll()
.and()
.oauth2Login()
.authorizationEndpoint()
.authorizationRequestRepository(cookieAuthorizationRequestRepository())
.authorizationRequestResolver(customAuthorizationRequestResolver())
.and()
.loginPage("/login")
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(oAuth2AuthenticationFailureHandler());
}
}
index.html,其中我使用Spring Security提供的默认“/logout”端点:
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="'Welcome '+${user.getUsername()}+'!'"></title>
<!-- When I include the part with Bootstrap, an Invalid CSRF token error is thrown at Spring -->
<!--Bootstrap-->
<!--<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/>-->
<!--<link rel="stylesheet" href="/webjars/bootstrap-social/bootstrap-social.css"/>-->
<!--<link rel="stylesheet" href="/webjars/font-awesome/css/all.css"/>-->
<!--<script src="/webjars/jquery/jquery.min.js"></script>-->
<!--<script src="/webjars/popper.js/popper.min.js"></script>-->
<!--<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>-->
<!--<script th:src="@{js/fade.js}"></script>-->
<!--Bootstrap-->
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="alert alert-danger" role="alert" id="backend-validation-alert" th:if="${errorMessage}">
<span th:text="${errorMessage}"></span>
<script>fade();</script>
</div>
</div>
<h1 th:text="'Welcome '+${user.getUsername()}+'!'"></h1>
<form role="form" th:action="@{/logout}" method="POST">
<div><input type="submit" value="Log out"/></div>
</form>
<form role="form" th:action="@{/user/settings/delete}" method="POST">
<div><input type="submit" value="Delete account"/></div>
</form>
</div>
</body>
</html>
褪色();
当我调试代码并检查CsrfFilter时,我看到在POST表单的Thymeleaf模板上创建了一个不同的隐藏csrf参数,它与cookie中的csrf不匹配,并引发了一个异常。筛选器将正确的XSRF-TOKEN值作为要验证的令牌,但在请求中存储为参数的CSRF令牌是错误的和不同的
有没有人经历过类似的问题?什么时候应该生成新的CSRF令牌?因为在我的例子中,当我检查网络信息时,我看到登录后为每个资源(.js、.css、.html)生成了一个新的CSRF令牌,但只有.html CSRF令牌作为隐藏参数存储在Thymeleaf,这导致无效的CSRF令牌错误
附加说明:我注意到,首先加载初始html,正确的CSRF表单参数在html隐藏输入和cookie中设置。但是,JS和CSS以及其他文件将进入CSRF身份验证,并导致cookie CSRF令牌的更改。我想解决方案将包括以某种方式从身份验证中排除这些头脚本和链接。是否可能重复@MebinJoe nope,我已经在安全配置中配置了tokenrepository,并且已经添加了头名称。请尝试将CSRF令牌添加到您的注销表单中,当我检查生成的HTML时,我已经可以看到生成的_CSRF参数。但是它与我们期望的不同,因为存储的_csrf值是在生成.html之后生成的。但在此之后,由于其他资源的加载,CSRF cookie更改了5次。Spring所做的是比较cookie和参数值,最终失败。我想知道我是否缺少一些配置。。。我尝试了这个解决方案,在HTML中再次生成相同的_csrf值。