0
votes

My system uses AngularJS 1.6 and Spring Boot2.0. My front end is just a simple form that customers can use to buy tickets for an event. When the page loads it will GET the details of the current active event, then the users can fill the form to be POSTed. No login/registration so it's just like a google form. I've built them as separate projects so they will be running in different ports. Now I want to enable csrf protection but I can't seem to make it work.

I tried to follow this tutorial but without the authentication part: https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii. When I did this I encountered a "CORS header ‘Access-Control-Allow-Origin’ missing" on the GET event details part so I added a CORS filter:

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
chain.doFilter(request, response);

After adding that, my GET works but I encounter the same CORS error when I POST the customer's details. I can already see the XSRF-TOKEN in the cookie when I use postman but somehow my backend blocks the incoming POST. From my understanding, angular automatically uses a received XSRF token so I didn't modify anything in the frontend when implementing spring security.

I've also tried this one: https://sdqali.in/blog/2016/07/20/csrf-protection-with-spring-security-and-angular-js/. And the exact same result, if I just follow the tutorial, CORS error on GET then when I add simple CORS filter, CORS error on POST. My filters seems to get mixed up on run time.

I've tried playing around the codes in these tutorials along with some answers to related questions here in stack but all of them don't have to deal with the CORS problem.

1
To enable CORS on spring-boot, you should check the following documentation: docs.spring.io/spring/docs/current/spring-framework-reference/… If you are also using spring-security, check: docs.spring.io/spring-security/site/docs/current/reference/html/… Each of these solution should be a bit cleaner that the one you are using currently. - vdubus

1 Answers

0
votes

To begin, you should check my comment on how to enable CORS with spring-boot and spring-security.

As for CSRF protection, spring-boot 2 with spring-security enable that directly. Yet, to use it with AngularJS, you need to follow this guide: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#csrf-cookie

We are also working on a project with a frontend AngularJS 1.6 and a backend spring-boot 2, but, as we didn't deploy our frontend and our backend on the same url, we got into a problem.

Example:

  • https://project.company.com/frontend
  • https://project.company.com/backend

The cookie generated by the server was set on the domain https://project.company.com with context /backend, which was unreadable from our frontend application in AngularJS.

To fix that, we forced our server to send a cookie with a context / so that it could be read from both applications.

@Configuration
@EnableWebSecurity
public class LdapAuthenticationSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        final CookieCsrfTokenRepository csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
        csrfTokenRepository.setCookiePath("/"); // Make sure that the cookie can be read from the backend and the frontend on the same domain.
        http.csrf().csrfTokenRepository(csrfTokenRepository);
        http.cors();
    }
}

In the case where your applications are deployed on different domains, but with the same base like this:

  • https://frontend.company.com
  • https://backend.company.com

I would suggest to force the cookie send by the server with a domain like .company.com. But to do so, you will need to modify the way spring-security manage the cookie creation.