Search code examples
springspring-bootcsrfresttemplate

How to pass CSRF token with the RestTemplate


I have two Spring Boot REST applications. One of the applications calls other with Spring RestTemplate. Lets call these applications server and client app.

Server app is sending XSRF-TOKEN token as cookie, this is done for the UI part. However there's no way (None that I know of) for the server to distinguish between the request coming from browser and a request coming from the client app. So I can not selectively send the CSRF token from the server to browser only.

Is there a built in mechanism in Spring which allows RestTemplate to detect CSRF cookie/header and replay the request?

If not how can I do the same manually? Should I wait for the CSRF exception to occur and then read the cookie fro the response and replay it?

If it were to be done once then it would be OK, however to wait for the exception for every RestTemplate call doesn't seem right.

I may try to store the token once and set in from the next time, however how would it deal with the multiple server app scenario (Which I have to implement next). As CSRF token of one server app would be invalid for the other, so I won't be able to store a single token, but I would have to store a map of tokens which would have an entry for every new server app URL.

This all seems too complicated, I would rather have Spring handle it.

Any clues are appreciated.

Thanks


Solution

  • For now I have implemented a REST service without protection in the server app which can be called to get CSRF cookies. I had to allow session to be created always so that CSRF cookie doesn't change in one session and so that I could avoid the error Could not verify the provided CSRF token because your session was not found.

    Client app calls CSRF rest service to get the cookies and then sends it with the next service call.

    It seems a much to call the CSRF token service for each REST call via RestTemplate however it saves me from implementing complicated logic of storing the session. CSRF token service just delivers the cookies so it's network call doesn't take much time compared to the actual service call.

    I was also thinking of using a persistent storage (SQL Database or Redis) to store the CSRF token for the server app and then let the client app directly read it from the persistent storage.

    However I couldn't figure out how to associate the Session + Server app + CSRF token together to identify token needed by client. As client doesn't have the session initially, so it can't uniquely find CSRF token for it's token from the database. This method is complicated further by the fact that RestTemplate doesn't store the session for the next call.