从Angular 2向Spring支持的Java应用程序发送POST请求时出现CSRF问题

我有使用Angular 2和基于Java的后端编写的UI,它在Spring Security之上使用OpenID Connect身份validation。

身份validation工作正常,但仅适用于GET请求。 每次在资源上执行POST,PUT或DELETE方法时,我都会收到HTTP 403:

{ "status": 403, "message": "Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.", } 

我像这样使用HttpClient:

 http.post( '/api/my-resource', JSON.stringify(myObject), new RequestOptions({ headers: new Headers({'Content-Type': 'application/json'}) }) ) 

当我添加withCredentials: true 这里提出的RequestOptions,我仍然得到HTTP 403但是有不同的消息:

 { "status": 403, "message": "Could not verify the provided CSRF token because your session was not found.", } 

我需要做些什么才能使HttpClient与CSRF一起工作?

注意:我也看了类似的问题,特别是angular-2-spring-security-csrf-implementation-problems ,但是那里提出的解决方案并没有解决我的问题。 同时我不想禁用CSRF。

添加CSRF cookie配置如下:

 @NgModule({ declarations: [declarations], imports: [imports], providers: [ {provide: XSRFStrategy, useFactory: xsrfFactory} ], bootstrap: [AppComponent] }) export class AppModule { } export function xsrfFactory() { return new CookieXSRFStrategy('XSRF-TOKEN', 'XSRF-TOKEN'); } 

并使用正确的标头名称配置Spring安全性。

  private static final String CSRF_HEADER_NAME = "XSRF-TOKEN"; @Override protected void configure(HttpSecurity http) throws Exception { http ... .and() .csrf() .ignoringAntMatchers(CSRF_IGNORE) .csrfTokenRepository(csrfTokenRepository()) .and() .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class); } private CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setHeaderName(CSRF_HEADER_NAME); return repository; } 

其中CsrfHeaderFilter

 public class CsrfHeaderFilter extends OncePerRequestFilter { private static final String CSRF_COOKIE_NAME = "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, CSRF_COOKIE_NAME); String token = csrf.getToken(); if (cookie == null || token != null && !token.equals(cookie.getValue())) { cookie = new Cookie(CSRF_COOKIE_NAME, token); cookie.setPath("/"); response.addCookie(cookie); } } filterChain.doFilter(request, response); } }