Spring 未在响应时发送 CSRF 令牌
Posted
技术标签:
【中文标题】Spring 未在响应时发送 CSRF 令牌【英文标题】:Spring not sending CSRF token on response 【发布时间】:2016-08-03 11:31:52 【问题描述】:我在让我的 Angular2 客户端与我的 Spring 服务器通信时遇到问题,因为我向它添加了 spring-security,即当我尝试向服务器登录 url 发送包含身份验证信息的 JSON 时,我得到一个 403“Invalid CSRF在请求参数 '_csrf' 或标头 'X-CSRF-TOKEN' 上找到令牌 'null'。”
我知道我应该在我的响应的标题上传递一个令牌以供客户端使用,但这个令牌没有被传递。我尝试了this answer,但令牌仍未通过。我也在通过邮递员发送请求,但令牌也没有到达。
webSecurityConfig.xml
:
<http entry-point-ref="restAuthenticationEntryPoint">
<intercept-url pattern="/api/**" access="hasRole('ROLE_USER')"/>
<form-login
authentication-success-handler-ref="mySuccessHandler"
authentication-failure-handler-ref="myFailureHandler"
/>
<logout />
</http>
<beans:bean id="mySuccessHandler"
class="com.eficid.cloud.security.rest.AuthenticationSuccessHandler"/>
<beans:bean id="myFailureHandler" class=
"org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"/>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="temp" password="temp" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
SpringSecurityConfiguration
@Configuration
@ImportResource( "classpath:webSecurityConfig.xml" )
@ComponentScan("com.eficid.cloud.security.rest")
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
public SpringSecurityConfig()
super();
@Override
protected void configure(HttpSecurity http) throws Exception
http.httpBasic().and().authorizeRequests()
.antMatchers("/spring-security-rest/login").permitAll().anyRequest()
.authenticated().and().csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
private Filter csrfHeaderFilter()
return new OncePerRequestFilter()
@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("/");
response.addCookie(cookie);
filterChain.doFilter(request, response);
;
private CsrfTokenRepository csrfTokenRepository()
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
【问题讨论】:
【参考方案1】:可能有错别字:
private CsrfTokenRepository csrfTokenRepository()
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
必须是 X-CSRF-TOKEN 而不是 X-XSRF-TOKEN。建议重构。
查看此链接:How to access Spring CSRF restful web service
【讨论】:
响应中仍未传递标头 你检查过cookie中是否有csrf吗? 我做了,没有返回cookie以上是关于Spring 未在响应时发送 CSRF 令牌的主要内容,如果未能解决你的问题,请参考以下文章
当要发送的请求是多部分请求时,Spring CSRF 令牌不起作用
当 POST 是唯一方法时,如何使用 jQuery 从标头中检索 csrf 令牌?
如何从Postman休息客户端发送spring csrf令牌?
如何从 Postman REST 客户端发送 spring csrf 令牌?