Search code examples
spring-cloudspring-cloud-gatewayspring-authorization-server

Spring cloud gateway + Spring authorization server


I want to configure spring cloud gateway as oauth2 client with authorization-code flow And My gateway should be stateless( it should not maintain any sessions) after successful login I need to return tokens For example: If I hit /login endpoint it should redirect to /oauth2/authorization/spring and that should redirect to /oauth2/authorize endpoint of authorization server and then It should show login page after successful login it should return tokens

Is it possible to achieve with spring cloud gateway and spring authorization server?


Solution

  • OAuth2 clients are stateful by nature (it store tokens). Spring uses session by default to store tokens. You can provide with your own authorized client repository to store the state elsewhere than session, but I don't see a good reason for that: storing tokens only in OAuth2 client memory is probably the most efficient and safest option.

    "Login" use session too and the authorization_code flow makes no exception. If you want to change that, you'll have to provide with your own implementation to to store the state used to prevent various attacks during the flow. Some data is stored in session before the user is redirected to authorization server authorization endpoint and used when the user is redirected back to the client with the authorization-code (to build the parameters in the URI of the request to the token endpoint). Again, this will be quite complicated.

    Exposing tokens to end-user devices, to the code running on it and probably to local storage on this devices, is definitely much more dangerous than providing with a cookie flagged with http-only and secured, along with CSRF protection. This is probably the reason why all major web actors keep providing your devices and browsers with session cookies instead of tokens (Gmail, Github, Facebook, Linkedin and many more use OAuth2, but open your browser debugging tools and try to find a token...)

    In the case where you would need to share sessions between several gateway instances, spring-cloud-gateway integrates pretty well with spring-session. But do you need several gateway instances? And even in that case, do you need to share sessions? (maybe it is just acceptable to run the authorization_code flow if an authenticated user lands on a new gateway instance, as this flow would run silently, with just the latency of a few redirects, and would probably be acceptable overload for the authorization server).

    With all that in mind, opting for a spring-cloud-gateway configured as a plain OAuth2 client with login seems the best option. Use the TokenRelay= filter to have session cookies replaced with an Authorization header containing the access token stored in session before forwarding a request from user devices to resource servers.

    In such an architecture, only the gateway is stateful (all services behind it can be stateless) and the tokens are kept safe on the server. I wrote a tutorial for that.