Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Spring Security 3.2.0.RELEASE, how can I get the CSRF token in a page that is purely HTML with no tag libs

Tags:

Today I upgraded from Spring Security 3.1.4 with the separate java config dependency, to the new 3.2.0 release which includes java config. CSRF is on by default and I know I can disable it in my overridden configure method with "http.csrf().disable()". But suppose I don't want to disable it, but I need the CSRF token on my login page where no JSP tag libs or Spring tag libs are being used.

My login page is purely HTML that I use in a Backbone app that I've generated using Yeoman. How would I go about including the CSRF token that's contained in the HttpSession in either the form or as a header so that I don't get the "Expected CSRF token not found. Has your session expired?" exception?

like image 849
Patrick Grimard Avatar asked Dec 31 '13 19:12

Patrick Grimard


People also ask

How do I get CSRF token in Spring Security?

You can obtain the CSRF using the request attribute named _csrf as outlined in the reference. To add the CSRF to an HTML page, you will need to use JavaScript to obtain the token that needs to be included in the requests.

Is CSRF enabled by default in Spring Security?

As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration.

What is CSRF token in Spring Security?

CSRF (Cross Site Request Forgery) is a technique in which an attacker attempts to trick you into performing an action using an existing session of a different website. Spring Security when combined with Thymeleaf templates, automatically inserts a token into all web forms as a hidden field.


2 Answers

You can obtain the CSRF using the request attribute named _csrf as outlined in the reference. To add the CSRF to an HTML page, you will need to use JavaScript to obtain the token that needs to be included in the requests.

It is safer to return the token as a header than in the body as JSON since JSON in the body could be obtained by external domains. For example your JavaScript could request a URL processed by the following:

CsrfToken token = (CsrfToken) request.getAttribute("_csrf"); // Spring Security will allow the Token to be included in this header name response.setHeader("X-CSRF-HEADER", token.getHeaderName()); // Spring Security will allow the token to be included in this parameter name response.setHeader("X-CSRF-PARAM", token.getParameterName()); // this is the value of the token to be included as either a header or an HTTP parameter response.setHeader("X-CSRF-TOKEN", token.getToken()); 

Your JavaScript would then obtain the header name or the parameter name and the token from the response header and add it to the login request.

like image 55
Rob Winch Avatar answered Sep 24 '22 02:09

Rob Winch


Although @rob-winch is right I would suggest to take token from session. If Spring-Security generates new token in SessionManagementFilter using CsrfAuthenticationStrategy it will set it to Session but not on Request. So it is possible you will end up with wrong csrf token.

public static final String DEFAULT_CSRF_TOKEN_ATTR_NAME = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN"); CsrfToken sessionToken = (CsrfToken) request.getSession().getAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME); 
like image 39
bsmk Avatar answered Sep 22 '22 02:09

bsmk