Spring-security: Allow configuration of added SessionAuthenticationStrategy for CsrfConfigurer

Created on 4 May 2018  路  11Comments  路  Source: spring-projects/spring-security

Summary

CsrfConfigurer automatically adds an instance of CsrfAuthenticationStrategy as SessionAuthenticationStrategy. It would be helpful to allow another strategy to be added.

Actual Behavior

An instance of CsrfAuthenticationStrategy is configured automatically.

Expected Behavior

The CsrfConfigurer contains a method to configure the used SessionAuthenticationStrategy.

Version

5.0.4.RELEASE

config enhancement

Most helpful comment

@rwinch the problem is when you configure CSRF the configurer automatically adds CsrfAuthenticationStrategy. Setting the sessionAuthenticationStrategy does not override the CSRF strategy, it just adds to the list of strategies. And the problem with the CSRF strategy is it generates a new token every request.

With a STATELESS app, we want to store the CSRF token on the client on login and pass it back each time similar to a JWT token. So we would add the CSRF token to the client as a cookie that is hidden from JS and pass the CSRF token to the JS as a HTTP header and store it in session storage for example. Each request would ensure the cookie and passed token match.

However, when the CSRF token is recreated on each request, the cookie and passed token can get out of sync when making concurrent requests.

Anyway, that was my idea of how CSRF would work in a STATELESS app. Maybe there's another approach? I've just disabled CSRF in the mean time. But the above cookie/header approach could work if we can override the default strategy like @mvitz setup in this PR.

All 11 comments

If someone could confirm that extending the CsrfConfigurer to accept an SessionAuthenticationStrategy to override the default behaviour would be accepted I would create a MR.

This would solve my problem in #5299. Thanks @mvitz!

Any thoughts on this @rwinch?

@mvitz & @samiconductor, having the same problem here with a Spring MVC stateless application with JWT tokens. After authentication, CsrfAuthenticationStrategy is generating CSRF tokens for each resource, but saves the initial html csrf token as thymeleaf hidden field. Therefore, any POST requests are failing.

CsrfConfigurer automatically adds an instance of CsrfAuthenticationStrategy as SessionAuthenticationStrategy. It would be helpful to allow another strategy to be added.

First, why do you want to change the authentication strategy? Second, can you clarify why you want to do that vs

http
    .sessionManagement()
        .sessionAuthenticationStrategy(someStrategy);

@rwinch the problem is when you configure CSRF the configurer automatically adds CsrfAuthenticationStrategy. Setting the sessionAuthenticationStrategy does not override the CSRF strategy, it just adds to the list of strategies. And the problem with the CSRF strategy is it generates a new token every request.

With a STATELESS app, we want to store the CSRF token on the client on login and pass it back each time similar to a JWT token. So we would add the CSRF token to the client as a cookie that is hidden from JS and pass the CSRF token to the JS as a HTTP header and store it in session storage for example. Each request would ensure the cookie and passed token match.

However, when the CSRF token is recreated on each request, the cookie and passed token can get out of sync when making concurrent requests.

Anyway, that was my idea of how CSRF would work in a STATELESS app. Maybe there's another approach? I've just disabled CSRF in the mean time. But the above cookie/header approach could work if we can override the default strategy like @mvitz setup in this PR.

@samiconductor Thanks for the clarification. This makes more sense to me now. I'd love for you to submit a PR that allows configuring the strategy as you suggested. Once you have confirmed you are still able to work on it, I will mark this issue as such. If you need any help, don't hesitate to reach out

@rwinch Sure no problem. Oh right, this isn't a PR. @mvitz had started it here a while ago but we couldn't figure out how to pass the tests. Will look into it again soon.

If you have specific questions, feel free to ask here.

Used your commit @mvitz, thanks! Just moved the tests from groovy to the new java ones.

@rwinch integration tests failed for me (mostly ldap) but units passed.

@samiconductor Thanks for the PR!

@rwinch integration tests failed for me (mostly ldap) but units passed.

Strange as they worked fine for me. If you continue to see errors, can you please create a ticket with what happens and details on how to reproduce?

Was this page helpful?
0 / 5 - 0 ratings