X-CSRF-TOKEN 不是 Spring Boot 生成的
Posted
技术标签:
【中文标题】X-CSRF-TOKEN 不是 Spring Boot 生成的【英文标题】:X-CSRF-TOKEN is not generated by Spring Boot 【发布时间】:2016-07-15 16:18:11 【问题描述】:我按照这里的指南:http://spring.io/guides/gs/rest-service/ 构建了我的休息服务示例,现在我正在尝试启用 CSRF 保护。我读到它应该默认启用,所以如果我不包括:
http.csrf().disable()
在我的WebSecurityConfigurerAdapter
配置中,CSRF 保护应默认启用,但似乎并非如此。问题是 X-CSRF-TOKEN 没有生成,也没有以任何方式包含在我的 HTTP 响应中。
我应该做什么来生成 x-csrf-token 并将其包含在响应中,当然还有 csrf 保护完全工作?
我注意到,使用类似的 spring mvc 配置,我得到了生成的 x-csrf-token,简单地包括:
在我的安全配置文件中。但是,使用 Spring Boot 时,我可能会遇到问题,并且无法生成 csrf 令牌。任何人都可以帮助我,也许指向我一个工作的例子?我的安全配置是:
@Override
protected void configure(HttpSecurity http) throws Exception
http
// .csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(new RestAuthenticationEntryPoint())
.and()
.formLogin()
.successHandler(new RestAuthenticationSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout()
.logoutSuccessHandler(new RestLogoutSuccessHandler());
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(restUserDetailService);
【问题讨论】:
提供有问题的spring安全配置java代码 感谢 Kunal,在上面添加了我的 configure() 方法。 你如何调用你的休息服务? 如果您只创建非浏览器客户端使用的服务,您可能希望禁用 CSRF 保护。检查when to use csrf 最后解决了我对spring security csrf-protection for rest services这篇文章的问题,希望对像我一样与spring
战斗的其他人有用!
【参考方案1】:
我们在安全测试中遇到了非常相似的问题,我们怀疑我们不小心在 websecurityconfig 类的 configure 方法中禁用了 csfr,默认情况下它是启用的。通过如下所示更改配置方法,我们让spring自动生成csfr令牌。
websecurityconfig 类配置方法==>
@Override
protected void configure(HttpSecurity http) throws Exception
http
.authorizeRequests()
.antMatchers("/", "/login","/loginError","/home","/interruption").permitAll()
.antMatchers("/admin").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.HALLEYYNT01.role())
.antMatchers("/requests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.CCHALLEYLOGIN.role())
.antMatchers("/solrequests").hasAuthority(Roles.ROLE_PREFIX.role()+Roles.SOLHALLEYLOGIN.role())
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
//.failureUrl("/loginError")
.loginProcessingUrl("/authenticate")
.defaultSuccessUrl("/")
.and()
.logout().clearAuthentication(true).invalidateHttpSession(true).deleteCookies("JSESSIONID")
.logoutSuccessUrl("/login");
//.and()
//.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
【讨论】:
【参考方案2】:要将 CSRF Token 包含在您的 csrf 保护中,您可以包含 CSRFTokenRepository 以生成令牌。为了说明您的情况,添加一条简单的线就足够了:
@Override protected void configure(HttpSecurity http) throws Exception http. .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //HERE ! Defaults XSRF-TOKEN as cookie name and X-XSRF-TOKEN as header name .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic() .authenticationEntryPoint(new RestAuthenticationEntryPoint()) .and() .formLogin() .successHandler(new RestAuthenticationSuccessHandler()) .failureHandler(new SimpleUrlAuthenticationFailureHandler()) .and() .logout() .logoutSuccessHandler(new RestLogoutSuccessHandler());
【讨论】:
【参考方案3】:使用 Spring security 5.3.0.Final,生成 CSRF 令牌的方法之一是使用以下代码在 cookie 中进行设置。
http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
您还需要在请求中包含生成的 CSRF 令牌以供服务器授权。
<form>
<input type="hidden" name="_csrf" value="$cookie['XSRF-TOKEN'].getValue()" />
//Code goes here
</form>
如果您使用的是 JS 框架,则需要通过在请求标头中设置令牌来包含令牌。
这是一个 JQuery ajax 调用示例。
// Get the CSRF token from the cookie
const csrfCookie= document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1');
// Add the CSRF token to each ajax request header
settings.beforeSend = function(xhr)
xhr.setRequestHeader('X-XSRF-TOKEN', springCsrfCookie);
;
$.ajax(settings);
Spring 在此处记录了其他满足您需求的实现。 https://docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/reference/html5/#servlet-csrf
【讨论】:
【参考方案4】:您可以配置CookieCsrfTokenRepository
。
使用 Java 配置将 CSRF 令牌存储在 Cookie 中
@Override
protected void configure(HttpSecurity http)
http
.csrf(csrf ->
csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
【讨论】:
以上是关于X-CSRF-TOKEN 不是 Spring Boot 生成的的主要内容,如果未能解决你的问题,请参考以下文章
easy-rules-centraldogma-spring-boot-starter 引入外部rule
404-not-found-while-running-spring-boot-rest-api
自定义spring-boot-autocofigure使用maven打包的时候报错了:Failed to execute goal org.springframework.boot:spring-bo