CSRF (also known as XSRF) is a well known web security attack allowing hackers to steel your identity and perform requests on website where your are already logged into. This tutorial shows how to Angular Spring Security CSRF configuration.
Table of contents
Server side configuration
Spring Boot is used in this tutorial. We will not discuss the creation of the application here but you can find more information on Github.
Spring Security configuration
There is many ways to protect your application against CSRF attacks. We will see here the mainly used solution that uses Cookies. Below the Spring Security configuration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.roufid.tutorials.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.csrf.CsrfFilter; import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { private static final String[] CSRF_IGNORE = {"/signin/**", "/signup/**"}; @Override protected void configure(HttpSecurity http) throws Exception { http .httpBasic() .and() .csrf() // csrf config starts here .ignoringAntMatchers(CSRF_IGNORE) // URI where CSRF check will not be applied .csrfTokenRepository(csrfTokenRepository()) // defines a repository where tokens are stored .and() .addFilterAfter(new CustomCsrfFilter(), CsrfFilter.class); // Csrf filter in which we will add the cookie } private CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setHeaderName(CustomCsrfFilter.CSRF_COOKIE_NAME); return repository; } } |
Let’s now see the CSRF filter.
CSRF filter
We create a filter that will create a cookie with the CSRF token for every request. Below the implementation :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.roufid.tutorials.config; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.WebUtils; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CustomCsrfFilter extends OncePerRequestFilter { public 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); } } |
Tha’ts all for the server side configuration. Let’s deal now the client side.
Client side configuration
Angular really simplified the CSRF integration. All you have to do is add the HttpClientXsrfModule with the name of the cookie or the header containing the CSRF token. Note that if no names are supplied, the default cookie name is XSRF-TOKEN and the default header name is X-XSRF-TOKEN.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http'; import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {AppComponent} from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule, HttpClientXsrfModule.withOptions({cookieName: 'XSRF-TOKEN'}) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } |
Configuration for older Angular version
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@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'); } |
Tha’ts it.
The tutorial source code is available on Github. Download the source