I have a Spring Security OAuth2 server that generates JWT tokens for frontend applications.
This tokens will be sent in the calls to the backends, passing through an API Gateway (WSO2 API Manager).
What I would like is to have the backend APIs registered in WSO2 and be able to validate that externally generated JWT token.
Is this possible? Can you provide a sample of the different places of the WSO2 APIM that would need to be configured to include this logic?
NOTICE: The WSO2 will never need to create the token, it'll always have been created previously, it only needs to validate it.
After a lot of trial and error and some help from Stackoverflow (kudos to Bee) this is my working solution. I hope it helps others since it was really tricky to make it work:
1. Implement a JWTAuthHandler to validate the JWT tokens:
2. Override your API definition (
/repository/deployment/server/synapse-configs/default/api/yourapi.xml
) to use the jwt handler and remove the APIAuthenticationHandler and the ThrottleHandler (the latter needs to be removed because of a well known bug for non-oauth2-authenticated apis):It should have something like this:
IMPORTANT:
The processing backend is usually derived (in normal OAuth2 requests) from the OAuth2 access token. Since here we replaced it, WSO2 can't determine which environment to invoke so it'll call PRODUCTION as default. To work around this, insert some extra field in your JWT, in my case environment, that helps you decide. Then, create an
AuthenticationContext
with the appropiate environment as shown. That's it!If you directly edit yourapi.xml descriptor it'll be replaced the next time you publish it. To automate its generation edit the velocity template (
/repository/resources/api_templates/velocity_template.xml
). In my case I only want it to apply to some applications, so I use a tag (jwt-auth) to select them.velocity_template.xml:
Indeed you could write a custom handler to authenticate on your own (basic authentication, jwt bearer). Good job finding that quickly. Maybe as an improvement you could cache the validated jwt token (or jwt hash) as the validation may take some time and performance.
As a default solution (without any customization) you could use JWT grant exchanging a token from a trusted IdP for an internal APIM token.