Adding the password grant type to Spring Authorization Server
security api gatewayFrom time to time, I’ve created sample applications that included an API Gateway that authenticates client requests and passes to the backend services a JWT containing the client’s identity and roles. The big picture is as follows:
First, I’ll describe the request flow and then I’ll explain how I enhanced the Spring Authorization Server.
Using a security server
To avoid reinventing the wheel, the applications use an off-the-shelf security service that’s responsible for:
- Authenticating client credentials
- Issuing a JWT, which is signed with a private key
- Providing access to the corresponding public key that a backend service uses to validate the JWT
The flow is as follows:
- The API Gateway authenticates the client’s credentials (username/password aka API key/secret)
- The API Gateway invokes a backend service with a (REST) requests, which includes a JWT, which contains the client’s identity and roles.
- The backend service validates the JWT
- The backend service authorizes the client to access the requested resource.
Using Spring Authorization Server
In the past, I’ve used Keycloak as the security service. The API gateway used an OAuth password grant type to authenticate the client’s credentials with Keycloak and obtain a JWT. The backend services obtained the public key from Keycloak via its JWKS endpoint.
But for a recent project, I decided to use Spring Authorization Server. However, I ran into a problem: Spring Authorization Server doesn’t support the password grant type. That’s because the password grant type is removed from the OAuth 2.1 specification. It’s considered insecure because requires the application to handle the human user’s credentials, which defeats the purpose of OAuth.
Adding password grant type to Spring Authorization Server
While password grant is insecure for human users, it still seemed a good fit my API gateway scenario. After all, the API Gateway is part of the application that issued the client’s credentials. Consequently, I decided to add the password grant type to Spring Authorization Server. A quick Google search discovered a code sample on StackOverflow that I was able to adapt to a new version of Spring Authorization Server.
Here’s the code
You can find the code in this Github repository.