15

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:

  1. The user makes a POST request to /login endpoint. If the credentials are correct, a JWT token is returned in header, otherwise a 401.
  2. The users sends the JWT token along with the request to /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


Option 1

  1. The user makes request to /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
  2. The users sends the JWT token along with the request to /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.

Option 2

  1. The user makes request to /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
  2. The users sends the JWT token along with the request to /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?

Community
  • 1
  • 1
Archie
  • 962
  • 2
  • 9
  • 20

1 Answers1

9

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

  1. you intend to make all your resources secure.
  2. you make sure that any call that reaches the the resource service is from a secure zone i.e request should not come directly to service as it will not have any means to authenticate.
  3. No Authorization. JWT tokens also has vital info about the roles which help application decide on the authorization. If it is ok for you to loose that bit of info, then thats fine.

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.

Anunay
  • 1,823
  • 2
  • 18
  • 25
  • 1
    Thanks for useful information! regarding verification of JWT tokens independently, I think that it depends on what kind of check do yo want to make, for example if you want to check whether token was created before password check or whether token was invalidated (with logout request), In this kind of cases I would say that request to the Auth-server will be better. Also it will make sense to validate token with Auth-server if you'll combine this request with role retrieving. What do you think? – haykart Jun 06 '18 at 10:25
  • 2
    There are two types of token access token and refresh token . AT is short lived and we can pass it along independently verifying just with the public key. Logout scenarios can be handled by the refresh token. i.e AT will not get refreshed after logout. If you application can live with that min time that AT has to be alive for i think you can avoid the server call. Talking about roles, they can be part of the the token as well. No one can modify it. Form microservices standpoint calling auth server time again can be a major disadvantage and thats where JWT shines. But its all about trade offs. – Anunay Jun 06 '18 at 12:42
  • Thanks a lot for explanation! Now it is more clear for me. Just one more thing, could you please share some tutorial/article links in your answer regarding this topic?. I believe it will be very useful, thanks again :) – haykart Jun 07 '18 at 07:40
  • I do not have any doc that i can share right away, but will suggest to read more about JWT and OIDC (thats what I used) – Anunay Jun 09 '18 at 04:56