16

The problem is to get the CSRF tokens working between Spring Security and Angular.

Spring Security CSRF Token Interceptor for Angular seems like something that should do the job, but there is no 'X-CSRF-TOKEN' in the HEAD response from the server.

My current tiny implementation is available in GitHub (Tag v.1.0) and I would appreciate a lot if somebody who knows the topic would have a quick look on the code, the problem should be easy to spot.

Based on the documentation, I am under the impression that CSRF should have been enabled automatically, but that seems not to be the case.

I am using Spring Boot and prefer the annotation-based configuration over XML, if something needs to be configured differently.

Any other approaches to make Spring Security work against Angular?

2
  • Have you looked at the upcoming 4.0 release? CSRF protection is enabled by default. Commented Dec 13, 2014 at 9:59
  • I am using 3.2 and it has CSRF by default as well. However, I just noticed that the Interceptor has a closed issue that explains with code samples how to set the CSRF to the header. Need to study that now... Commented Dec 13, 2014 at 10:08

2 Answers 2

17

Angular looks for a cookie called "XSRF-TOKEN" I believe, so the easiest thing to do for the client is to send that. You can do it in a Filter for instance (example from https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/single/src/main/java/demo/UiApplication.java#L65):

    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 = new Cookie("XSRF-TOKEN", csrf.getToken());
                    cookie.setPath("/");
                    response.addCookie(cookie);
                }
                filterChain.doFilter(request, response);
            }
        };
    }

Update: since spring security 4.2 the correct cookie name for angular is used by default if you use the cookie csrf repository(the link is still the best source), i.e. there is no longer any need for a custom filter. Example:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                ...
                .and()
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
Sign up to request clarification or add additional context in comments.

7 Comments

I hardly understand how this protect you against CSRF attack? The mechanism should be opposite, you always set a cookie value and when it comes back you should verify that angular has set the same value as Header of the incoming HTTP request.
Yeah but Spring Security does that bit for you (did you follow the link?). This is just an adapter for the existing CRSF filter in Spring to angular conventions. It works, trust me.
That depends on whether you want a client side or server side solution.
This is my current favourite solution, as I am having problems with the Interceptor. However, this solution seems to work without problems (and is easy to adopt).
|
2

I am answering the question myself as there was a hidden one in the original GitHub repository: Issue #1.

The solution was to add a couple of lines of Java code that adds the CSRF parameters as Http message headers.

I added a working solution to the GitHub repo with Tag v.2.0.

1 Comment

Not a working solution for me after all, as I started getting "Cross-Origin Request Blocked" error messages (with Google geocoding) after adding this module. Issue reported.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.