7

I am in the process of developing a node.js microservices-based application. The individual microservices are developed including one that already handles the authentication, authorization and registration processes. I am reviewing using kong as the api gateway but am looking for clarity regarding how I can handle authentication, etc. through kong but still use the user service I already created, which already has a db associated with it.

Ideally, I would prefer if I could have kong pass the authentication information to the user service to validate the user's login credentials (username and password) and have kong generate the jwt token provided the authentication was successful.

Is this possible with kong or would I have to somehow move all of this functionality to kong, authentication, authorization and registration?

Update

I found the following article outlining an approach using a custom Authentication server, but this seems pretty involved: Custom Authentication Service in Kong API Gateway.

In a nutshell, I would like the user to pass a username/password combination to kong, which kong would somehow pass upstream to the endpoint of the user service I already have. This would then validate the user and confirm or deny user/pass is correct. From this point, kong would generate the jwt and return to the user. If this were possible it would be great. If I have a implement a custom authorization service that could work as well, but definitely not preferred.:-)

halfer
  • 19,824
  • 17
  • 99
  • 186
user1790300
  • 2,143
  • 10
  • 54
  • 123
  • Hello ! 4 years after and there's still no clear documentation on this anywhere ! can you please share your solution how did u manage jwt validationw and passing the user data into other microservices ! i am trying to work on an exactly the same concept nodejs ms with kong api gatway and i am stuck on the auth part of it . can you provide some help or maybe we can contact each other via whatsup if you have time to discuss it with me – nermineslimane Feb 17 '22 at 11:41

1 Answers1

8

So, what I would say from actively using Kong in a couple of places, I would suggest that you either use JWTs, and the JWT plugin with Kong, or use the OAuth2 plugin, but a combination of both is (as far as I know) actually not possible with Kong. But, bear with me for a little while.

Using JWTs

For your situation, using a JWT might be a fairly simple solution. The only misconception I see right now in your assumptions is that Kong actually helps you in crafting JWT tokens, which is not the case. Kong can only validate JWT, but not craft them; this has to be done by your own Authorization Service. Then again, how you want to pass the token to the consuming service is again something which depends on the type of the service.

Here, you might want to use an OAuth2 flow, e.g. the Implicit Grant if your client is an SPA, or some other grant (such as the Resource Owner Password Grant), but in both cases, Kong will not help you in implementing it. You will need to implement the /authorize (for the implicit grant) or the /token endpoints (for the Resource Owner Password Grant) by yourself. Once more: Kong will only validate the JWT which you craft, and not craft the token. Implementing those end points is not really difficult, but requires reading the RFC 6749 (which is worth the effort).

When crafting your tokens, check the documentation of Kong on what Kong expects from the JWT, especially regarding the iss claim, which has to match a certain property inside your API definition. You can either retrieve that manually for your API, or you can use the Kong Admin API to do that (port 8001). The former is easier, the latter requires some coding but is more reliable and flexible.

Using the OAuth2 Plugin

The solution outline you found in that other question suggests a different solution, where you actually implement a real OAuth2 Authorization Server, and make use of the Kong OAuth2 plugin.

This really requires digging into the OAuth2 spec, and also understanding quite well how Kong does this (which is a little special). The answer I provided in that question outlines the necessary steps.

Common properties of the solutions

With both solutions you get the benefit of Kong validating your calls to your API, and only letting calls with a valid token pass. The JWT option leaves you with crafting your token, and will also require your API backend implementation to inspect the token and take out which claims it needs, such as something like a "User ID" or "Scopes" from the JWT token. Kong will not do that work for you, it will just validate that the JWT token is correctly signed.

The second option offloads that more to Kong, where you, when authorizing the user, add an X-Authenticated-UserId and (optionally) an X-Authenticated-Scope to the opaque token, which in turn is enriched to the call to your backend API via headers. Which means that your API does not have to do any extra work in taking the token apart - the information is readily available via Kong-injected extra headers.

Community
  • 1
  • 1
donmartin
  • 1,753
  • 2
  • 15
  • 30
  • First off, thank you for answering this question. I have been looking all of the internet for this. Honestly, I would prefer just using the jwt approach for now. The doc. seemed like it was indicating that the jwt plugin for Kong did the jwt creation, which was confusing me. Just for more clarity, it seems like the flow would have to go like this. 1) User hits login endpoint which gets re-routed upstream to the login endpoint for the user service. 2) Upon successful login, the upstream api returns a jwt token. 3) Subsequent requests will pass this token, Kong makes sure jwt is present? – user1790300 Oct 18 '17 at 21:15
  • Kindaish, yes. Depending on the type of your client, you would work it differently. For an SPA: 1) Check localStorage for token, use it if valid and present, 2) Redirect to **your** `/authorize` end point on your Authorization Server, 3) In your AS, establish identity (over whatever means), and 4) craft the JWT token, and 5) redirect back to the SPA with the token in the fragment (`.../#access_token=&...`), 6) Use the token with your API endpoint (=Kong), which validates it. – donmartin Oct 19 '17 at 10:46
  • "Kong will only validate the JWT which you craft, and not craft the token" Wish I could find this statement more easily on Kong's doc. Thank you! – Amit Levy Oct 31 '21 at 09:21