How does User Registration work while using an API Gateway - microservices

I was reading up about API Gateways (Kong) and I wanted to integrate it into my application. Every tutorial I've seen creates consumers for the services using Kong API or through a dashboard like Konga. I already have a user registration/auth service. How can the API Gateway replace that ? How should the user registration be changed so that Kong knows about it ? And how would login work because In all the examples I've seen the ApiKeys or JWT secrets are created in Kong ? Can any body shed some light on how this works in practice ?

In my opinion Kong is not supposed to replace a user registry / authentication service. However, it can help you enforce authentication.
There are several options of securing your APIs against unauthorized access. These include:
API key: this type is used with the key-auth plugin and is not intended for authenticating users (meaning natural persons) but consumers (meaning other systems).
JWT tokens: this type is used with the jwt plugin and is suitable for user authentication. Kong is responsible for validating the JWT tokens (by checking the signature and expiry of the self contained token). You can of course do further checks either with custom Kong plugins or within your upstream service.
So I think you shouldn't think of Kong as a replacement for your user service, but as a complement/addition which helps you enforcing security policies even before the request reaches your upstream service.

Related

How implement a basic IAM oauth2 flow with spring security?

I am currently developing using spring security oauth2.
Currently, the frontend is SPA, and it is developed as react that operates with client side redering.
My rest api has the spring security starters libraries. But I don't know how to use oauth2 flow provided by spring.
So my question is: Can I use spring security as IAM to protect my web and api?
Does spring security have the known oauth2 grants and how use them ?
Implicit grant
Client Credentials Grant
Password grant
Don't use implicit grant
It is not recommended to use the implicit flow (and some servers prohibit this flow entirely) due to the inherent risks of returning access tokens in an HTTP redirect without any confirmation that it has been received by the client.
source: https://oauth.net/2/grant-types/implicit/
With implicit grant, access token is returned immediately without an extra authorization code exchange step. This extra step is usually performed in your backend.
Web > token > Api
SPA frontend and its Rest Api is a very common approach, used since simple startups until big companies. The flow summarized is:
Your users will start the web application.
As they were not signed in before, you web app will show them a login screen (a page provided by the authorization server).
After authenticating, a consent form is showed to the user.
After user consent, the authorization server will send you an authorization code.
The web app will exchange this code for a token.
After getting back this token, the web app store it in the client(browser) and send it as a header when apis needs to be consumed.
Your private rest apis must validate if token of the web app (header) is valid by sending it to one endpoint of the authorization server
If token is valid, your api rest is allowed to respond to the web client. For instance a json with products, employes, some update of customer order details, etc
For this flow to work, you will need:
web spa with a hint of backend. Backend is required because you cannot have a proper user session in static solutions like apache or nginx.
authentication and authorization server: Known as identity and access management (IAM) or some third app which provide you the basic oauth2 endpoints to manage a proper security for your apps.
your apis: foo-api , bar-api, baz-api, etc
spring security
In the minimal scenario in which:
you will have only one web + one rest api, and nothing more in the future (mobiles, iot, etc)
you don't have an authentication/authorization server
you have a mix of functional apis (employee, products, etc) and its security (spring-security) in just one artifact
you don't need user session in your web
you don't need a logout feature
Flow could be reduced to:
Your users will start the web application.
As they were not signed in before, you web app will show them a login screen (a page provided by spring-security).
After authenticating, a consent form is showed to the user.
After user consent, the authorization server will send you an authorization code.
The web app will exchange this code for a token. Since your api is using Spring security, the token generation is covered.
After getting back this token, the web app store it in the client(browser) and send it as a header when apis needs to be consumed.
Your private rest apis must validate if token of the web app (header) is valid by sending it to one endpoint of the authorization server I think the spring security chain filters handle this.
If token is valid, your api rest is allowed to respond to the web client. For instance a json with products, employes, some update of customer order details, etc
Here some samples of token generation and protected endpoints with spring security. I will try to upload a ready to use sample:
https://www.freecodecamp.org/news/how-to-setup-jwt-authorization-and-authentication-in-spring/
IAM
If you will have more applications and complex scenarios in the future, I advice you to choose some open-source iam like:
Glewlwyd,Keycloak,OAuth.io,ORY Hydra,SimpleLogin,SSQ signon,
Commercial services like:
Auth0,Curity Identity Server,FusionAuth,Okta,Red Hat Single Sign-On,cidaas.
Or try to develop a new one using pure spring-security
Lectures
Some recommended answers with more oauth2 details:
https://stackoverflow.com/a/62123945/3957754
https://stackoverflow.com/a/62049409/3957754
https://stackoverflow.com/a/57351168/3957754
https://stackoverflow.com/a/63093136/3957754
https://stackoverflow.com/a/54621986/3957754
https://stackoverflow.com/a/63211493/3957754

Best practices to secure rest api with gateway and spring security OAuth [duplicate]

I have developed a set of microservices (resource servers) using Spring Boot 1.5.x + OAuth2 with JWT. Right now each microservice is protected using Spring Security i.e. JWT access token is verified at individual resource server level. API Gateway does not have spring security in place, so it just routes the requests to appropriate server and propagates the authentication headers to downstream services.
I wanted to know if there are any disadvantages of this setup compared to the one where AccessToken is verified at API gateway level only. Or is it just a matter of opinion? Doesn't keeping security at API Gateway level breaks principle of loose coupling, because each microservice may better understand the role of a given user in its own context?
API management can do a small check on your JWT (fail early), BUT your microservices are the only one that can really manage all the security stuff !
If you set security only on api management it means that someone that can access your network will be able to push request to your API unauthenticated.
You will not be able to log who do what. And finally, if you need to set some kind of ACL, it will not be possible (When you ask to list orders, you can only list YOUR order).
Perhaps you will think of decoding your JWT on the api management layers and push a header with user name to your backend to prevent all the thing I spoke about above, but I think it is not really a good practice.
First, access to network will means I'm able to be anybody. Then JWT is much more than just a username. For instance, perhaps you use scope on your authentication layers. ( scope read orders / scope modify orders / scope delete orders). This is useful to restrict what an application can do (either at client_id level) or what a user accept to give to the application ( scope share email ...).
For this JWT on the backoffice is mandatory.
Ok you can do like username and extract data on api management and put specific headers to call backend, but really ? why do specific stuff ? oauth2 with JWT can do this for you.
Well this is an interesting question. In our team we discussed about this topic a lot. Basically you have some parameters affecting the individual answer to this question. But you should always decode and verify granted tokens on the microservice level, too. Because they contain relevant information for authentication and in some cases even for authorization. If your microservices run in a enclosed environment (e.g. on enclosed Kubernetes cluster, where only the API-Gateway is available to the outside) you could use this "mixed" solution.
You can really consider just to verify the AccessToken at the API-Gateway and let the other microservices rely on the API Gateway. The API Gateway could than exchange the AccessToken into another AuthToken, only valid in the microservice-context. This new generated AuthToken can for example contain more sensitive application-bound information, because it is not exposed to the client. The Client gets only a so called opaque token. See https://medium.com/tech-tajawal/microservice-authentication-and-authorization-solutions-e0e5e74b248a

Recommended way to communicate the user informations (id token) to resource servers in a OpenId Connect context

In a context with the following services:
API Gateway/OIDC client: connect to an external OpenId Connect Provider (to get access, refresh and id tokens) and act as proxy to forward requests to other services with the access token (Authorization code flow)
Several resource servers, incoming requests are handled by the API Gateway and include the access token (for validation, using the keys exposed by the OIDC provider)
I am using the Spring Security 5.2 Oauth2 client/resource server libraries.
What will be the recommended secure way to make all the resource servers services aware of the user information (included in the API Token).
I am evaluating several options:
Include the id_token in the request sent to the services. Each
service can then validate the token (in a filter).
Make the API Gateway act as a token issuer to make a new enhanced token based.
The resources servers will have to validate the token received with
a new key exposed by the API Gateway/Token issuer. With this
solution a custom AuthenticationManager has to be implemented.
I think option 2 is the more secure and future proof, is there any downsides I should consider? Also there are maybe other alternatives.
You should be able to achieve your goals without issuing a second level of token or sending id tokens to APIs. A common gateway solution is as follows:
Open Id Connect Provider (OICP) issues tokens to the client and does all the deep stuff like auditing of tokens issued + UIs for managing them
Client sends access token to resource server via API Gateway
API Gateway validates the access token, which can involve an introspection call to the OICP
API Gateway can send the access token to the user info endpoint of the OICP to get user info, then forward this to resource servers - perhaps via headers
API Gateway can be configured to cache claims (token + user info details) for subsequent calls with the same access token
Resource servers sometimes run in a locked down Virtual Private Cloud and don't need to revalidate the access token (if you are sure this is safe)
AWS API Gateway works like this when calling lambda functions. I actually like the pattern in terms of extensibility and it can also be used in standalone APIs.
My write up may give you some ideas, along with some sample authorizer code and a class that does the OAuth work.

Service to service workflow with AWS cognito and AWS Lambda

I'm rather new to AWS Cognito and AWS Lambda. So far I've played around with Serverless and deployed my REST API via AWS Lambda. However, I would like to make my API available for several external parties. As this is service to service, there is no end user directly calling my API. I make the API available for other businesses which use it in their applications. All functionalities exposed via the API are rather simple, meaning they are not invoking any other AWS services like a Dynamo DB etc.
I have several questions, some are rather high-level others are quite specific to the setup of AWS Cognito. I decided to put all in one post as it makes it much more self-contained and easier understandable.
1. Question, Cognito vs API key: What is the advantage of using AWS Cognito vs AWS Lambda in combination with restricting the access via an API key and IP-Whitelisting? Is one much more secure than other?
Let's assume I want to use AWS Cognito. As this is a service to service case, I've read that the standard is to use token endpoints where the grant_type is client_credential. I've found the following on medium. The first few steps consist of
Create a user pool in AWS Cognito.
Create an App client
Add Resource Servers
Enable the client credentials checkbox for Allower OAuth flows
2. Question, App client: Within the added App client I find the corresponding App client id and App client secret. If I expose my API to several different parties, do I need to add for each party another App client? Otherwise they use all the same credentials. Is this the right way to do it?
3. Question, Resource Server: Here I'm completely stuck. What exactly is the meaning for this? At then end, all I want is that my clients can do a post request against my API and access is granted through Cognito. Some clarification what this is for and how this applies in my case would be appreciated. More than happy to share more insights if needed.
The next part is to configure Cognito Authorizer for the API Gateway. This should be fine.
4. Question, client workflow Regarding my clients workflow. Am I correct that this consist of the following steps:
First, I provide to the client his client_id and client_secret.
then the client implements on his side the following workflow:
Whenever he wants to use my API exposed via API Gateway, he first uses his provided client_id and client_secret to retrieve his bearer token.
He uses this bearer token to make a request to API Gateway with the bearer token in the Authorization header.
If access granted, the client retrieves the output of my API.
Is this correct or am I missing anything?
1-Question, Cognito vs API key
Well as you can see here.
Amazon Cognito user pools let you create customizable authentication
and authorization solutions for your REST APIs.
Usage plans let you provide API keys to your customers — and then
track and limit usage of your API stages and methods for each API key
So the purpose is different, the API Key is used basically to count a customer usage while AWS Cognito is there to authenticate/authorize calls to your API.
Let us say, you have a requirement that a trail user can't call your API more than 100 times.
Then using AWS Cognito, you will allow a user to sign up, also you will provide the same user with an API Key, you will identify the source of the calls using Cognito and with each call API Gateway will decrease the limit assigned to user's API Key by 1.
And you will have the following cases:
When token (obtained through login using username and password), and
API Key are valid, then the call will be successful.
When token is wrong/missing, your caller will get 401 status code.
When API Key is wrong/missing, your caller will get 403 status code.
When API Key is correct but limit is exceeded, your caller will get
429 status code.
2. Question, App client:
Well, client id and client secrets are meant to identify a trusted client (app) rather than a user and each app should have its own client id, so if the caller is an application not a user so yes, create a client id for each separate app. Please be aware that client secrets must be kept confidential so if the caller app can't achieve that, such as single-page Javascript apps or native apps, then the secret shouldn't be issued.
3. Question, Resource Server:
It is your API server.
Check this page.
The resource server is the OAuth 2.0 term for your API server. The
resource server handles authenticated requests after the application
has obtained an access token.
Large scale deployments may have more than one resource server.
Google’s services, for example, have dozens of resource servers, such
as the Google Cloud platform, Google Maps, Google Drive, Youtube,
Google+, and many others. Each of these resource servers are
distinctly separate, but they all share the same authorization server.
4. Question, client workflow
Check Client credentials grant in here
The steps for the process are as follows:
An app makes a POST request to https://AUTH_DOMAIN/oauth2/token, and specifies the following parameters:
grant_type – Set to “client_credentials” for this grant type.
client_id – The ID for the desired user pool app client.
scope – A space-separated list of scopes to request for the generated access token.
In order to indicate that the app is authorized to make the request, the Authorization header for this request is set as “Basic
BASE64(CLIENT_ID:CLIENT_SECRET)“, where
BASE64(CLIENT_ID:CLIENT_SECRET) is the base64 representation of the
app client ID and app client secret, concatenated with a colon.
The Amazon Cognito authorization server returns a JSON object with the following keys:
access_token – A valid user pool access token.
expires_in – The length of time (in seconds) that the provided access token is valid for.
token_type – Set to ” Bearer“.
Note that, for this grant type, an ID token and a refresh token aren’t returned.
The app uses the access token to make requests to an associated resource server.
The resource server validates the received token and, if everything checks out, executes the request from the app.

Securing web app and api using OpenID Connect

I don't want to roll my own security anymore and am looking at using OpenID Connect with my c# API and AngularJS app. I can get all that to work just fine. However, my brain cannot seem to understand how to secure my API correctly for both use cases:
Use Case 1: AngularJS SPA
My AngularJS app connects to my API and sends a bearer token identifying the user and includes user claims. This one is easy and there is tons of documentation on it.
Use Case 2: API to API
Some customers want to access my API directly instead of going through my AngularJS app. In this case, I thought I could use a Client ID/Secret for toen-based authentication which is great except then I know nothing about the user that's using the client id/secret. There could be 10 users using the same custom API that is calling my API. How do I get user info via the API call? I've seen others use API keys that they then lookup the user and create a JWT but I thought there might be an easier way. Any ideas?
The whole point of API to API authentication is that there is no user context. Or well, the user in that case is the machine trying to access your API. You would then need to design your authorization logic around that and implement scope based permissions. Alternatively, your options are to use api keys as you mentioned or if you want OAuth protocol with user context in the api to api scenario - then ResourceOwnerCredentials flow is an option.
API to API communcation
You can use Client Credentials Grant defined through OAuth 2.0. This won't require you to have end user credentials. Now this won't be OpenID Connect. OpenID Connect require the involvement of an end user and bound to authentication. OAuth 2.0 on the other hand is about authorization, checking whether the entity can access the resource.
With Client Credential Grant, your identity server will issue tokens for a specific client. So one of your API becomes the client (resource consumer). From request handling API endpoint, you can accept valid tokens and respond back with resource.
If you require fine grained access control from request handling API, you will require to use token introspection to identify to whom this token was issued. In this case, it will be identification of specific client identity and execute a logic on top of it. You can check the token introspection response to identify such details.
Alternatively, access tokens can be come in form of a JWT. If this is the case, they can be considered as self contained tokens so validation is straightforward.

Resources