40

I am currently building an API based around a microservices architecture.

I am using JWT to authenticate users. I understand that when a user sends a login request a JWT containing the users identity and their roles/permissions etc is returned. This token is then sent with the users subsequent requests to tell the server who is sending the request. I think this is the correct understanding.

In a normal monolithic architecture this works well as explained. How can I transfer this to a microservices architecture to establish trust between microservices.

I could forward the users JWT to downstream microservices simply but this doesn't allow the downstream microservice to know who/which upstream microservice is sending the request.

An example would be I have a location microservice. I want to allow the restaurant microservice to make calls to the location microservice. But I also have a product microservice that I do not want to be able to call the location microservice.

Obviously I could just not code the product microservice to call the location microservice but this doesn't stop someone else from doing so.

Any suggestions?

bigwheel
  • 140
  • 9
mwild
  • 1,483
  • 7
  • 21
  • 41
  • seems to be duplicated with https://stackoverflow.com/questions/31044380/microservices-authentication/42734113#42734113 – David Level Aug 11 '17 at 16:53
  • are there any other condition when product service is not allowed to communicate with location service? – Vijay Parmar Aug 17 '17 at 13:13
  • Did you find an answer or you are still searching for one? – xargs Jun 24 '19 at 13:57
  • 1
    @xargs-mkdir I am using kubernetes as my container orchestration system. Kubernetes allows the segregation of namespaces and deployments. So for the example above I do not allow the products namespace to talk to the location namespace. Further than that, for individual user verification I have the users JWT being forwarded to any microservice that requires certain account privileges. – mwild Jun 24 '19 at 14:31
  • this could be your solution https://dev.to/s2agrahari/authentication-between-microservices-part-i-3dpp – Suraj Jun 03 '20 at 17:11
  • Use `openfeign`, it's one of the best way of communication between microservices with authentication. – Thirumal Jul 14 '20 at 18:42

3 Answers3

14

You can make the communication between microservices secure atleast by following two methodologies :

  1. JWt token : Let assume micro service A wants to communicate with micro service B, then the token issued by A and the audience of the token is B. In that case the token is signed by micro service A with its private key. The aud field in JWT will represents the audience, it can be a single service or a set of services. The value of aud parameter should be a pre agreed value between the services. In micro services you can use the regular expression to validate the audience. For example aud can be *.samplemicroservice.com. Audience service B can check whether token is intended for it or not by checking the aud field. Once confirmed it can use issuer's public key to verify it.

  2. Mutual SSL : The straight forward way to achieve it is to use mutual ssl between services. Each service should have SSL enabled and should presents its certificate to the the other service and other service should check the validity of the certificate with a trust store. This should be validated at both microservice A and microservice B to reach a mutual agreement. A self signed certificate can be used as root CA for all services certificates and can be accessed through a trust store.

There can be many variations of these mechanism. Specifically in case of JWT token. For example, You can delegate the token issuing responsibility to one service and can validate token in each of the service using public key of issuer service.

AjayLohani
  • 872
  • 1
  • 6
  • 26
5

Here you have two different problems to solve!

1) User authentication/authorization:

Yours downstream services services should pass the user JWT token to services upstream (dowstream depends on upstream, the downstream is more near of the frontend). This way all services can validate the JWT token, and we can garantee that the token is unchanged.

2) Micro services authorizarion:

This is the second scenario you have, you need to garantee the trust relation between microservices and the authorizations to access a resource. In this case, ever microservices do you have shoul be a client (act as user), in a auth service (key cloak, Authservice...) and before send a request to any upstream dependecy, it should be authenticated, and send his own JWT token, in this way the destination microserveice (the called one) can validate and alow or not alow the caller to access the resource, and later, check the end user credentials.

This kind of approuch can be achieved using the client credentias autorization flow (https://oauth.net/2/grant-types/client-credentials).

See this article: https://developer.okta.com/blog/2018/04/02/client-creds-with-spring-boot

Ibson Machado
  • 143
  • 1
  • 6
0

I guess this solution to this should be that JWT should be passed to the gateway layer / Aggregator / Facade layer.

At this layer, just decode the JWT and set the data in the DTO(any Java Class), so that same is accessible easily.

Now, when this information needs to be passed to any service, these should be passed as params as anyhow API at the service layer should be generic.

Now if you want to establish trust b/w services, you can simply check the parameters as the services are anyhow should not be exposed outside apart from aggregators.

Hope I am making sense.

Ankit Bansal
  • 2,162
  • 8
  • 42
  • 79
  • 2
    Do you need to transform JWT to DTOs? JWT is a well known structure from which every microservice can extract claims, that it needs. You don’t need to support extra DTO classes. – Michael Freidgeim Mar 23 '21 at 12:21