authenticationjwtgraphqlmicroservicesgo-micro

Authentication and authorisation in microservice architecture


I have multiple services:

And let's say they are connected together like this:

example 1

All services are communicating through gRPC on a closed nettwork and the Authorization is done using jwt tokens

Approach 1: The graphql service is responsible for user authentication and making sure that the user is authorized to run the specified procedure. There is no user authentication between the services, but there is TLS authentication. There are no authorization checks done by the services.

Approach 2: Each individual service makes sure that the user is authorized to run a specific procedure. An example could be voting on a post where you would need to be signed in and have over 15 in reputation. Here it would be the Post service's responsibility to check whether the user is signed in or not (authenticated) and whether it's authorized to vote. This will result in large overhead since every procedure call needs to check user authentication and authorisation through the Auth service.

Is there a better approach that still preserves the security of approach 2, but creates a small overhead like approach 1?

-----Update-----

Approach 3: Same as approach 2, but user authentication is only done in the GraphQL service using the Auth service. The authorization is done by checking metadata passed around. And there is TLS authentication between the services.


Solution

  • Let's consider a request that travels from the authenticated user to service A and on to service B. The JWT should be passed on each of these calls.

    Both services would first authenticate the user which is simply done by validating the JWT. Then each service would extract all information necessary to authorize the user from the user, for example the sub claim. It would use this information to decide if the user is authorized with respect to the operation that the service shall perform on behalf of the user. Only after successful authorization would the service actually do anything.

    This would not be overhead but necessary to allow service B to both authenticate and authorize the user. Not passing the JWT from sercice A to service B would make it impossible for service B to know anything about the user.