I have a redirect widget that calls the AWS Lambda using AWS API Gateway. it returns a twiml-gather then will call an external API base on the output I receive on the twiml-gather
for security reasons, I would like to make my AWS API Gateway have an OAuth or API key
right now, I'm not sure how can i achieve this given that using the redirect widget doesnt have an option to input a http-headers (can't use the Twilio function because of 10 seconds time limit)
You can make use of the X-Twilio-Signature here.
You also find some Twilio blog posts on this topic.
Validating Requests are coming from Twilio
https://www.twilio.com/docs/usage/security
If your application exposes sensitive data, or is possibly mutative to your data, then you may want to be sure that the HTTP requests to your web application are indeed coming from Twilio, and not a malicious third party. To allow you this level of security, Twilio cryptographically signs its requests.
Related
I have been working on creating a platform utilizing microservices architecture with an API Gateway. One question that I'm stuck on, is how to have the API Gateway handle both authenticated and unauthenticated endpoints.
Here is a simplified and rough diagram of the system I am thinking about
For my system, I'll be using Auth0, and I think I want to have the service check if the token is valid using the public key, instead of the gateway doing it. This gives me more flexibility if I want to make one of my services public someday. And I think I want to keep my gateway small.
But how will the gateway handle a mixture of both authenticated an unauthenticated endpoints? I.E. I want to make the GET endpoint "open", and the POST endpoint require login. Which entity should manage whether an endpoint is "open" or "requires login", the gateway or the service?
Should I always have the gateway pass along the request to the service, regardless of whether the user is logged in or not, and have the service return a 401?
Or should the gateway contain some logic about which endpoints require login, and return 401 if there is no token in the request? Skipping the service entirely.
Yes it is configured on the gateway you will be using. For example on AWS API gateway you can have a lambda custom gateway authorizer for access points. The authorizer function can 'authorize' by returning ok for all request to that endpoint.
More reading here
This is one of main responsibilities of API Gateways in my opinion. It may depend on the specific API Gateway but one elegant solution that we used was:
All microservices define their endpoints and if they are protected or not in a descriptor file.
When it is deployed (perhaps in CI) it registers these definitions in the API Gateway
API Gateway accepts the request and check if it is protected or not
API Gateway may enrich request with user info if protected
All requests beyond Gateway is accepted secure to be accepted by services
This way we separate the concern of authentication from business logic / features
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.
I was able to access the API by generating API key and using a Google web client. Now, I like to access the API using a simple HTTP client like curl without using any client libraries supplied by Google, I know this should be theoretically possible since those libraries have to use HTTP at their core. Has anyone done it? if so can someone point me in the right direction?
This is possible! Some applications use their own backend services to make calls on Google API (without Client Lib then).
You need to get some things, like on client calls -> clientID, authorization etc...
Get more informations about CURL on Google here : https://developers.google.com/gdata/articles/using_cURL
Concerning the OAuth 2.0 with a backend service : https://developers.google.com/api-client-library/php/auth/web-app
OAuth2 or Single Sign On will allow you to access to Calendar.
I am having a difficulty in terms of architecture and wondering if someone has some insights.
The plan
I will have multiple microservices (different laravel projects, catalog.microservice.com, billing.microservice.com) each providing an API.
On top of these will be an angular fronted consuming those APIs.
I will have another micro service (passport.microservice.com) for auth now thanks to laravel 5.3 passport this is even easier.
The flow:
User goes to catalog.microservice.com
user need to authenticate and provides a user and password
request is made by angular (aka client) to passport.microservice.com through password grand type to get an authorization token
now that I have a token I am authorized to call a resource from catalog.microservice.com
catalog.microservice.com needs to know if the token is valid and makes a request (some kind of middleware?) to passport.microservice.com
passport.microservice.com returns the user, scope etc.
Questions:
Is this a good approach?
The token validation in catalog.microservice.com can be a middleware?
The common approach in microservices architecture is to use a single authentication 'gateway', and usually it's a part of an API gateway.
So besides your passport.ms.com, you have somewhat of a proxy that will check access token from the header and if it's invalid - give an error. If the token is valid - proxy the request to corresponding microservice.
This way you don't have to repeat yourself - you don't have to implement authentication N times for each microservice.
Then, if you need more granular control - what exactly a user can access (usually called authorisation), then you traditionally implement it at each specific microservice.
In short, your microservices shouldn't care if the incoming request is authenticated - it's already been pre-filtered for them. Microservices only decide whether the user X can do action Y.
PS. You can combine API gateway with Passport/Oauth facility or you may run them separately - that's up to you. AWS already offers API gateway as a service (proving how trendy microservices are becoming) but I couldn't find any good open source analogues.
Your api should have a gateway that handles the Authentication and communicates to different micro-services.
Its makes sense to authenticate (or reject unauthorised) users at the top level, combine responses from different services and then your clients(Web or mobile) can consume that data.
An advantage of this is that your clients only need to remember just one url.
Example: Only microservice.com is needed and not catalog.microservice.com, users.microservice.com, passport.microservice.com etc.
A single endpoint address (URL) is much easier to remember and configure than many individual API addresses.
Here is a link to an image describing this architecture.
Api Architecture image
There are SNS application with 2 servers. Web backend server and REST API server.
The web server allows user login/logout with username/password, and show user information
The REST API server provides APIs like /topics, /comments, it should be stateless without session
The REST API will serve other web applications
There are some potential solutions, but neither is security.
Base Auth, the browser hold the username/password
Token with expiry timestamp, the problem is user could stay on the page until token expires
So, is there a way to protect the REST API when calling it from AJAX?
If I have understood your problem correctly I may suggest you use the Token solution. In order to maintain security you may generate new token on every request (& send it to client in response), which should be used to make next request, and disable token if it is once used or has expired.
Sorry, I meant to mention it as a comment, but I don't have enough reputation.