3

I'm investigating microservices architecture and now focusing on the api gateway along with security.

I found out that there are two different approaches:

1- Where authentication is outside of the gateway, meaning, the user

  • has to authenticate first,
  • gets the token,
  • and then can make calls to the services via the gateway The most common scenario I've seen that everyone is implementing/presenting) as described on the diagram link Authentication outside of the gateway

2- Another way is to have everything behind the gateway, which means, user

  • tries to access a secured resource/service via de the gateway,
  • he's being redirected to the identity provider login page via the gateway as well,
  • gets authenticated, the token is passed back to the client/user,
  • and finally reaches the request service, everything through one http call via the gateway which will result in some additional calls (authorization code flow, url call back to the client, as described on the diagram link as well Authentication behind the gateway

And while some might speak about the 2nd approach, I can't seem to find any actual implementation or detailed description. Which makes me wanna ask ... why?

If I'm following a microservices design, I would naturally have the 2nd implementation, but no ... everyone appeared to be using the 1st one.

According to what I've read, yes, it takes more efforts since you'd have to reroute the necessary authentication and authorization endpoint, but is that it? Aren't there any other reasons which would make us favor the 1st one rather the 2nd one?

Any insights?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
MoBe
  • 61
  • 5
  • from client perspective second approach usually is less convenient. Each function he writes would need checking, if it has to authenticate or not and eventually handle it. In the first approach you can easily separate all functions from authentication and to it once before reaching endpoints. – Maciej Wrobel Feb 22 '22 at 10:06
  • Not sure I fully understand. By client you mean for example your webApp right? To me, even in the 1st approach, you would still need to check the token for every function/method you write (unless you don't wanna secure specific methods). But I do agree on the fact it's easier to implement, as opposed to the 2nd approach. I mean, there are pros and cons, i just feel like ... it's not well described in terms of security in general. – MoBe Feb 22 '22 at 16:56
  • 2
    I’m voting to close this question because it is not about programming as defined in the [help]. – desertnaut Apr 05 '22 at 00:12

1 Answers1

2

Short answer:

The second option is the most common. And you're right. If you don't need to redirect the user, don't.

Long answer:

Before microservices, all of the 'services' were different routes within a single application. The application routed user traffic to the right place.

Putting a gateway in the middle is abstracting that first level router from the single application to its own application.

  • If the gateway is only routing traffic to backend services, then it's a load balancer (aka application aware proxy, reverse proxy, etc.) The load balancer is a frontend service that redirects traffic to the right internal backend service.
  • If the gateway is both serving pages, and routing traffic to backend services, then it's a web application and a load balancer.

People who talk about authentication flows that use different user-visible targets (urls) are solving common problems. 3 reasons I can think of:

  1. To make it really clear in diagrams which part is auth and which part is the black box service
  2. As organizations grow, many people build their own services and auth flows. One for the first product, then another one for their next product, and a third for their third product. At some point they need to rationalize how to consolidate their auth into one flow.
  3. Different URLs set different cookie scopes. Sometimes you need many domains to isolate cookies.

Example, take a service like Google Oauth or Okta SAML - you need to login on their domain, and you need a way to get the token back to your domain. Since you can't see google.com or okta.com cookies on yoursite.com, the external flows are necessary. This is often the case as companies add products that have different domains.

Google products redirect a few times every time you login. They are doing cookie management from accounts.google.com to gmail.google.com and keeping google.com cookies isolated the whole time. However, you're hitting the same google load balancer every time (or you theoretically you could).

Jonathan
  • 5,736
  • 2
  • 24
  • 22
  • When you say "... that use different user-visible targets", it's another way of saying "authentication is outside the gateway" right? (different urls so ... the domain changes), cause otherwise I might be confused. – MoBe Feb 14 '22 at 14:06
  • Yes. Change in user visible target is a different URL - well FQDN. But, different FQDNs doesn’t always mean different servers. Sometimes many FQDNs point to the same server but are required for cookie isolation on the browser. – Jonathan Feb 15 '22 at 16:19
  • Ok, I don't know if it's out of scope, but one further question. I just finished implementing the 2nd option: authentication behind my gateway. And to do so, well I had to use [forward headers](https://github.com/IdentityServer/IdentityServer4/issues/4631) in order to achieve authorization code flow. I was just wondering if it's done in the right way: do all microservices need to switch the authority url, from identity provider to gateway? Like, this is how it is done? To me it makes sense since we're routing IdP requests through the gateway, but I'm no expert, so .. I may wanna ask. Thanks – MoBe Feb 18 '22 at 16:16
  • Best to start a new question as I’m not understanding this question – Jonathan Feb 23 '22 at 21:57
  • Sorry, my answer wasn't clear either. Hmmm, IdentityServer introduced the concept of forward headers, which allows you to update all the IdP urls with the incoming host url (the gateway). E.g: is4Url/connect/token becomes gwUrl/connect/token, and this for all is4 endpoints. However, the is4 base url remains the same. I would still ask the question, thank you for your time. – MoBe Feb 24 '22 at 11:30
  • It's been a while, and I realized I didn't get the whole idea. If it's not too late, what did you mean by the "external flows" in the example given? And speaking of the example, you were referring to the scenario where authentication is NOT happening behind the gateway, right? I think that should be it for now :) As for the cookie management, I don't know much about it, if you have some specific references that target the topic, feel free to share, otherwisen I'll give myself a shot with internet ;) thanks Jo – MoBe Mar 24 '22 at 16:33