Currently I have a monolith application with Java/Spring Boot the following endpoints:
/login
/logout
/some-resource
To access some-resource
, the flow is following:
POST
request to /login
endpoint. If the credentials are correct, a JWT token is returned in header, otherwise a 401./some-resource
. If the token is valid, the resource is returned, otherwise 403.Now I want to split the monolith into 2 services: "AuthServer" and "SomeResourceServer". There will be an API gateway on the top. I am thinking about 2 possible ways to handle authorisation
/login
endpoint. The API gateway forwards it to the "AuthServer". If the credentials are correct, a JWT token is returned in header, otherwise a 401. - This step is the same
/some-resource
. The API gateway calls the "AuthServer" to validate the JWT token. If the token is valid, the API gateway calls "SomeResourceServer" and returns the results. Otherwise 403./login
endpoint. The API gateway forwards it to the "AuthServer". If the credentials are correct, a JWT token is returned in header, otherwise a 401. - This step is the same
/some-resource
. The API gateway simply forwards the request to "SomeResourceServer". Then "SomeResourceServer" calls "AuthServer" to validate the JWT token. If the token is valid, the resource is returned, otherwise 403.In Option 1 the API gateway is responsible to handle authorisation (communicate with "AuthServer"), in option 2 the communication is done between the servers. So which option is more correct? Are there any good/bad practices? Or maybe another way/option?
An API gateway is a service which is the entry point into the application from the outside world. It's responsible for request routing, API composition, and other functions, such as authentication.
The API Gateway is responsible for request routing, composition, and protocol translation. It provides each of the application's clients with a custom API. The API Gateway can also mask failures in the backend services by returning cached or default data.
In the past, most authorization decisions have happened at the gateway — and developers can still enforce authorization there for microservices, if they like. However, for security, performance and availability, it's typically preferable to also enforce authorization steps for each microservice API.
You can strip of the authentication at the gateway and there is nothing wrong in doing so. There is a slight overhead on the gateway and this will not be a problem if
However you have one place to handle authentication and if you strip the token from the call, depending on the number of hops this call has to make this removal of token may help you.
On the other hand II option gives you freedom that all your services are individually secured. If you want some of the resources of some of the service to be available anonymously you can get that as well. You also have control over authorization bit.
Its all about trade offs. But I prefer the second approach as I have more freedom.
Having said that, you really don't need to make a call to auth server to verify the JWT. JWT tokens can be verified independently if you have the public key of signing authority.
Also when requesting for the resource, if token is invalid response code should be 401 and if token is valid Principal is not authorized to access the resource, response should be 403.
API gateway IMO should not have anything to do with Authorization (authentication may be) as it is something which is decided by the service and vary from service to service and resource to resource and should be left for the services to take care of.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With