7

How specifically is the state parameter related to the _csrf token in Spring OAuth2? Is state an encrypted version of _csrf as we would expect it to be?

Also, what specific Java syntax should be used to encode and encrypt a new _csrf value before encapsulating it into a new state parameter in Spring OAuth2?

THE CONTEXT

A client app redirects the user's web browser from the client app to the authorization server's authserver/login page. Then, in the authorization server app, a custom implementation of OncePerRequestFilter is used to redirect a request to /oauth/authorize?(list of params) into additional authentication steps, which ultimately redirect back into a new request to /oauth/authorize?(list of params). The problem is that the _csrf token changes during the additional authentication steps, and the documentation indicates that _csrf is used as the state parameter. This implies that the state value probably needs to be updated by the authorization server to reflect the new _csrf value.

HOW state IS GENERATED

The problem is that the encoded and encrypted value for state has already been set by the client app before the client app uses an OAuth2ClientAuthenticationProcessingFilter to transfer information for the authentication server to use while authenticating the user via the authentication steps mentioned above.

Some research indicates that the state key is generated by the client using a DefaultStateKeyGenerator, which in turn uses a RandomValueStringGenrator to generate a 6 character state value.

For example, in the original request made to /oauth/authorize?(list of params), the raw _csrf value is encoded into fupS1L, as shown in the following url:

/oauth/authorize?client_id=acme&redirect_uri=http://localhost:8080/login&response_type=code&state=fupS1L

If the _csrf value changes to a69fd23a-a393-4b27-a685-a323fd31db9a during the redirect flow, the value of fupS1L in the state parameter will no longer be valid, and the resulting token will not be authorized to permit access to protected resources.

What specific syntax do I use in order to convert the new _csrf value into an encrypted value similar to fupS1L that can be passed into a functional state parameter?

Also, is there any relationship between the state variable and the _csrf token? The RandomValueStringGenerator used by DefaultStateKeyGenerator seems to simply create a random 6 character String. I would like an authoritative answer by someone who has worked deeply with the code or even written it. I am doing a deep review of the code, so a casual passer by who reads the RandomValueStringGenerator source code and says state is not related to the csrf token would not be adding any value. The author of the API, however, would help us all out a lot by telling us how this works.

NOTE TO SPRING

It should not require this much digging to find documentation of such a simple thing.

Lii
  • 11,553
  • 8
  • 64
  • 88
CodeMed
  • 9,527
  • 70
  • 212
  • 364

1 Answers1

0

I know it's quite old since its been asked. Still sharing what I know now, as I have worked through a similar requirement to pass a deeplink in the 'state' parameter. I wanted to redirect to this deeplink when flow comes back from the auth-server after a successful oauth sign-in session.

Primarily I followed this SOF answer -> https://stackoverflow.com/a/52462787/5107365. This suggests to extend the DefaultStateKeyGenerator to use the deeplink parameter from the request to AAS to encrypt+encode to set into the 'state' parameter. And, then the custom implementation of OAuth2ClientAuthenticationProcessingFilter.AuthenticationSuccessHandler is used to override determineTargetUrl method to decode+decrypt the state parameter when the flow comes back after successful auth. Hopefully it will help somebody who is in need of a similar requirement.

Raj
  • 778
  • 1
  • 10
  • 14