I would appreciate with anyone can help me to direct myself to a best or simplest approach.
I have a requirement to do a communication between my app and a partner with JWT token
The steps are the following:
- The user is already authenticated in MyApp using another user credentials solution
- MyApp should generate a JWT token with some user information like subscription id
- MyApp redirects to the partner url with the JWT token
- Partner uses the public key (that must be exposed in a JWKS endpoint) to validate that the jwt token was issued by my app.
My Main doubts are the following:
a. Do I need use spring oauth2 authorization server or can I use just some spring security components to generate the token and expose the jwks endpoint? b. If I use spring oauth2 authorization server, how can I customize /oauth2/token to receive user information to generate the token? c. If I use spring oauth2 authorization server, how can I rootate my public key? d. If I use only spring security components, can you share some tutorial to generates the JWT? e. If I use only spring security components, would it be simple to generate jwks informatino in the endpoint?
Regarding the item a)
It would not be necessary an authorization server like a client credentials flow, my app could generate the JWT token by it owns, I'm using the spring authorization server only for the benefits to have all the structure to generate the tokens. Is it really necessary or the best approach to take advantage of spring boot structure or would be simplest to use some spring security components to generate the token?
Regarding the item b)
If the best decision it to use the Spring Oauth2 Authorization Server, my idea was to use /oauth2/token with client credentials, but the problem is how can I generate a JWT token with some user specific information if I don't have the user information in POST /oauth2/token request? Is it possible to customize the authorization server request to receive the information I need in the body or header? I searched in google and seems that is possible. I just want to confirm that it is ok to do that.
Regarding the item c)
Is it possible to rotate the public key without downtime in the spring oauth2 authorization server?
Would be the process just generate a new jks, change it in the path the server points to and call like a POST /refresh in the authorization server?
CodePudding user response:
JWTs are signed, you'll have expose the public key, so yes, use an authorization-server to issue tokens and expose key.
You can use any OAuth2 authorization-server but OIDC implementations will be easier to use for other actors.
Spring-security authorization-server has very limited built-in features. You should have a look at other solutions before making a choice. There are plenty either on premise (like Keycloak) or SaaS (like Auth0 or whatever your cloud provider proposes if you are hosted in the cloud).
OAuth2 has many advantages over internal security (this is probably why your partner is asking for it). I recommend that you actually switch all your security to OAuth2. Once you have chosen an authorization-server and configured it to use your existing users database, configure:
- UI applications as OAuth2 clients (using an OIDC client lib for your UI framework)
- REST APIs as resource-servers:
Then you can customize the token JWT recovering the custom_value sent in the request
@Bean public OAuth2TokenCustomizer<JwtEncodingContext> jwtEncodingContextOAuth2TokenCustomizer(UserRepository userRepository){ return (context -> { Authentication authentication = context.getPrincipal(); if (authentication.getPrincipal() instanceof String) { OAuth2AuthorizationGrantAuthenticationToken tok = (OAuth2AuthorizationGrantAuthenticationToken) context.getAuthorizationGrant(); context.getClaims().claim("custom_clain", tok.getAdditionalParameters().get("custom_value")); } }); }
Then the output token will have the claim custom value