Authorization in API Gateway vs Microservice Endpoints - security

I'm trying to build a microservice architecture. I've learned some benefits of API gateway like: load balancing, invoking multiple microservices and aggregating the results, cache management etc. So I decided to include it in my system.
My question is whether I should implement authorization in gateway layer or separately in each microservice endpoints ? For example authenticating user on gateway and passing user claims in decrypted form to be used in authorization logic to each service call ?
It seems like it make sense and saves processing time to authorize some aggregates before even calling each service. However, authorization logic is really a concern of individual service.
What is your advice ?

each microservices endpoint. implementing the authorization in API gateway will make your system rigid. If at any later stage you have to separate logic for authorization (say, internal user, external user, open api). This will be very difficult to incorporate.
Authorization should happen at each API level.

You can use API Gateway Pattern / API Gateway. Then you can also offload the authentication/authorization responsibility of the microservice. It will be easy for user or developer that is calling the services. API GW support External /Internal GW even. It may support Role base permissions. eg: WSO2 APIM.
You will get below advantages when you have API /MS GW:
An API Gateway is the single point of entry for any microservice call.
It can work as a proxy service to route a request to the concerned microservice.
It can aggregate the results to send back to the consumer.
This solution can create a fine-grained API for each specific type of client.
It can also convert the protocol request and respond.

Related

how to obtain JWT token in a api gateway architecture

Currently doing some research to setup an (azure) api gateway with oauth (jwt token) security.
an external partner/app sends a request to an api endpoint published on the gateway including a valid JWT-token in the header that gets validated by the gateway against AzureAD for example. When validated the request is routed to the backend service. No problems here.
My question is, what is best practice for the external app to obtain that JWT-token (to use for the api call) ?
Obviously, It could send a request to AzureAD with a clientid+secret to obtain a valid JWT token. But to do so it has to call my internal AzureAD directly ? Is this the way to do it ?
or should I expose a 'get-jwt-token' api on my api gateway and route that request to AD ? How should I secure that API ? with basic auth ?
or am I missing something, and is there a much better best/proven practice ?
HOSTING BEST PRACTICE
A reverse proxy or API gateway is placed in front of both APIs and the Authorization Server (AS). This ensures that an attacker who somehow gains access to the back end entry point cannot access data sources.
OAUTH REQUESTS TO GET TOKENS
OAuth requests are typically proxied straight through the reverse proxy / API gateway to the AS with no extra logic. All credentials, auditing of login attempts etc remain in the AS.
MANAGED SERVICES
If using Azure AD as a cloud managed AS, this is a special case: the system is already hardened for internet clients, so most companies don't add their own proxying - though it is possible to do so.
FURTHER INFO
The first of these covers the infra setup and the second gives you an idea of extensibility options once a reverse proxy / gateway is in place.
IAM Primer
API Gateway Guides

Where is the best place to perform authentication in a microservice architecture?

I see different opinions among software engineers regarding where to place authentication in a Microservice architecture.
Many support the idea that authentication should be placed at the API gateway level and only the Authorization at Microservice level.
For authentication I mean checking a JWT that was issued after authentication with credentials, for example...
Now, if the API gateway is the only entry point of our backend then it is reasonable to have it in the Frontline when it comes to authenticate the requests.
The problem is that the API gateway, being a proxy, shouldn't really be bound to the underlying services, right?
Let's say that some of the endpoints require authentication and some of them are publicly accessible. I feel that in this case it's better to have it at the Microservice, since the Microservice knows all the details of the API that it exposes.
Otherwise the API gateway should ask the Microservice if the endpoint is public or not or get this information from a database.
But wouldn't be too much of overhead to perform this request to the service/database everytime the gateway is hit?
Furthermore, depending on the framework we use to implement the security layer we might not have the chance to check the accessibility of an endpoint at runtime. So, whenever we make an endpoint public we should redeploy the gateway to get the new information about what requires authentication and what not.
What are your suggestions regarding this topic?
Looking at it strictly from a security perspective.
From what I have seen with microservice architectures, the gateway only performs authentication, each micro service / endpoint needs to handle its own authorization checks at a bare minimum.
So for your public URLs, the gateway would not perform any authentication checks.
For your private/secured endpoints, the gateway will perform authentication checks and authorization checks at a microservice level, but you will still need to handle the business rules to be followed.
Example:
/public/article1 - does not need any authentication or authorization checks
/private/newsletter - requires authentication from gateway, but may not require authorization checks from the microservice
/private/account - should require both authentication + authorization check from gateway as well as from the microservice to make sure you are accessing only your account.

Azure B2C Microservice Authentication and GraphQL Layer

We have few micro-services that are used by a UI. Azure B2C is our auth provider. Each micro-service(API) requires an access token and needs to talk to a database for authorization. This database has role based access permission.
This is how it looks today:
With this we have two problems:
As Azure B2C do not allow adding scopes from multiple resources into one access token, we have to get multiple access tokens.
We are now at a stage where the UI need to call two or more APIs to display the data on one page.
We wanted to use GraphQL as an API Gateway. Something like this:
All the micro-services are placed inside a private vnet and only GraphQL API is allowed to talk to them. GraphQL Layer handles all authentication and authorization.
Now the questions are:
Do you see any problems with this approach?
Is it okay to use a client and secret for communication between GraphQL layer and other API's? or Is there an provision in Azure B2C that can do this validation with out GraphQL layer requesting individual access tokens?
what are the additional advantages of adding Azure API Management to this (other than logging, analytics, rate limiting etc)? Do I need to worry about SSL termination?
Option 2 looks like a good architecture.
A common pattern is for the UI to call a dedicated 'entry point' API, which then orchestrates calls to microservices in a private network - as in your second diagram.
Eg an Online Sales UI calls only an Online Sales API
This also helps to keep UI specific requirements out of microservices and keep responsibilities clean.
In OAuth terms as you say there will be a single resource - the entry point API - and you should only need a single access token.
The entry point API's token (or its claims) can then be forwarded directly to Microservices and used to identify the user there if needed.
I'd avoid getting additional tokens for microservices and just enforce authorization based on roles from your user database.
In some cases it may also make sense to also enforce rules such as 'Online Sales API not allowed to call Payroll microservice'.
Personally I would develop entry point APIs using the same technology as microservices.

How to properly use express-gateway for authentication of a web app?

I am fairly new to the concept of microservices and api gateways in general. I am trying to understand the role that an api gateway plays in a modern web application using many microservices. I have been reading the documentation and tutorials of express-gateway but am a bit confused on how a web application would perform authentication with an api gateway set up like express-gateway.
My web app would have multiple microservices that it would talk to. I thought that putting an API gateway in front of all my microservices would make it so that each microservice would not need to worry about whether a user/request is authenticated or not, because if the microservice was being talked to it meant that the api gateway had verified the request was a valid user. Is my understanding of this correct?
Assuming that my thought of the api gateway serving as a gatekeeper to other microservices is correct, my follow up question is with the specifics of how it is performed.
Does this mean that all user creation and authentication is performed by the api gateway? Meaning that I would have no custom user creation/login microservices? Or would I have a publically reachable through the api gateway custom user creation microservice which upon creation would itself create the user accounts within the api gateway? Is user information now duplicated by my microservice in a database somewhere and the express-gateway's own storage? I guess my general confusion is around does an api gateway take the role of authentication/user creation entirely away from a web app's own microservices, or do you still need both parts?
I thought that my own authentication microservice would first validate a user then work with the api gateway to generate a valid short lived token, but reading about creating user or app accounts for authentication in express-gateway has made me confused on the roles each play.
to have an overview of the role of an API Gateway in a microservice based solution, I suggest you to have a look to this presentation I did couple of months ago. That should clarify the things a little bit.
Is my understanding of this correct?
Yes, you got it. If you have a look to the video, you can actually see that concept in practice as well.
For the storage, that kind of depends.
Express Gateway offers a subset of identity services such as users, applications and credentials. They're good enough for most application usages but you might find yourself with the needs of using an external service, such as Auth0.
Now, features aside — where you store the data, it's up to you. You can keep some of the data in Express Gateway and some of it in your own database — or entirely in Express Gateway. There's not a good or bad strategy here.

How to handle user authentication with microservices in AWS?

I'm reading a tutorial provided by AWS explaining how to break up a monolithic NodeJS application into a microservice architectured one.
Here is a link to it.
One important piece is missing from the simple application example they've provided and that is user authentication.
My question is, where does authentication fit into all this?
How do you allow users to authenticate to all these services separately?
I am specifically looking for an answer that does not involve AWS Cogntio. I would like to have my own service perform user authentication/management.
First, there is more than one approach for this common problem.
Here is one popular take:
Divide your world to authentication (you are who you say you are) and authorization (you are permitted to do this action).
As a policy, every service decides on authorization by itself. Leave the authentication to a single point in the system - the authentication gateway - usually combined inside the API gateway.
This gateway forwards requests from clients to the services, after authenticating, with a trusted payload stating that the requester is indeed who they say they are. Its then up to the service to decide whether the request is allowed.
An implementation can be done using several methods. A JWT is one such method.
The authenticator creates a JWT after receiving correct credentials, and the client uses this JWT in every request to each service.
If you want to write your own auth, it can be a service like the others. Part of it would be a small client middleware that you run at all other service endpoints which require protection (golang example for middleware).
An alternative to a middleware is to run a dedicated API Gateway that queries the auth service before relaying the requests to the actual services. AWS also has a solution for those and you can write custom authentication handlers that will call your own auth service.
It is important to centralize the authentication, even for a microservices approach for a single product. So I'm assuming you will be looking at having an Identity Service(Authentication Service) which will handle the authentication and issue a token. The other microservices will be acting as the service providers which will validate the token issued.
Note: In standards like OpenID connect, the id_token issued is in the format of JWT which is also stateless and self-contained with singed information about the user. So individual Microservices doesn't have to communicate with the authentication service for each token validation. However, you can look at implementing or using Refresh tokens to renew tokens without requiring users to login again.
Depending on the technology you choose, it will change the nature how you issue the tokens and validate.
e.g:
ExpressJS framework for backend - You can verify the tokens and routes in a Node Middleware Handler using Passport.
If you use API Gateway in front of your Microservice endpoints you can use a Custom Authorizer Lambda to verify the tokens.
However, it is recommended to use a standard protocol like OpenID connect so that you can be compatible with Identity Federation, SSO behaviors in future.
Since you have mentioned that you are hoping to have your own solution, it will come also with some challenges to address,
Password Policies
Supporting standards (OpenID Connect)
Security (Encryption at rest and transit especially for PIDs)
SSO, MFA & Federation support etc.
IDS/IPS
In addition to non-functional requirements like scalability, reliability, performance. Although these requirements might not arise in the beginning, I have seen many come down the line, when products get matured, especially for compliance.
That's why most people encourage to use an identity server or service like Cognito, Auth0 & etc to get a better ROI.

Resources