Amazon (AWS) API Gateway - Authentication - python

I have a python microservice which I would love to connect to AWS API Gateway. - The problem is that I have researched ways to make both secure, but not really came to a conclusion.
I came across a site saying I should use SSL Certifications to only enable requests from API Gateway.
Can someone enlighten me on what's the best practice for authentication between the client and API Gateway and the API itself?

There are a very large number of ways to authenticate between the client and API Gateway. There is no "best" way.
To authenticate between API gateway and the back-end servers, you would use SSL authentication as described here: http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html

There are couple of approaches to implement authentication in API gateway. Different approach serves different purposes and level of security you expects to achieve.
For most of the cases you can write your custom authorizer lambda for authentication. With help of JWT you can create a reasonably secure Authentication for your API. If you use IAM authentication API Gateway directly supports it. Only limitation is you need to use AWS SDK to invoke the API for convenience. Since API gateway uses SSL by default, data transfer is already encrypted.
If you have very specific security requirements then you can use SSL certificates. This is generally preferred when communicating between API's in Service Orchestration like scenarios in SOA.

You ask what the "best practice" is, and, since we are in Amazon's AWS ecosystem, that's surely to use AWS Cognito.
If you go this route, you will have vendor lockin for your authentication flow, but it works very well as they are built to play nicely together. Logins occur via calls to AWS Cognito endpoints: successful ones will receive session tokens which can then be used in future for any API Gateway calls.
To enable, just click into any API Gateway Method, click into Method Request, edit Authorization, and you will see your AWS Cognito User Pools you have created.
This takes a bit of configuration, but it works very well.

Related

Can I expose the API URL to the public in a Python library?

I have built a Django API which has a lot of proprietary algorithms for analyzing stock portfolios. The API is hosted in AWS and this API is also connected to the website where I show the visualizations of the calculated metrics.
I want to build a library to provide these metrics in Python like pandas. Users can install this package using pip install .
In my Python library code, I would expose only the API URL and I will call the API with different parameters and endpoints. Paid users will get a unique access code in email using which only they can access the Python package functions. I don't want to expose my Django API code to the public as the analysis itself requires a lot of stock price data from the Database and also there are a lot of proprietary algorithms.
Does the solution make sense? Should I hide the API URL or just leave it.
Hiding the API URL is security through obscurity and should be avoided.
To protect your API from being abused by public users, you can either develop your own protection mechanism, e.g: rolling out your custom API key provisioning, with rate limiter, and IP address filtering, etc...
Or you can use AWS API Gateway to proxy traffic to your back-end API. API Gateway alone might not be useful, but the services supporting it is really helpful without requiring you to write additional codes
API Gateway supports API Key with Usage Plans, helping to rate limit your authenticated users.
You can enable AWS WAF to protect your API from malicious scripts, or other attacks
To make sure that your back-end servers only receive traffic from API Gateway, you can configure a client-certificate. This way, your server is protected even if your back-end's API URL is publicly exposed.

Securing Google Cloud Functions using WSO2

I'm writing an application (web and mobile) where I would like to use WSO2 for user authentication, authorization and SSO.
My mobile app will authenticate the users against the WSO2-is.
All the API's used by the app are google cloud functions written in python.
I would like to bring a security layer to my GCF's.
From my understanding I can use WSO2-am as a bridge between the app and the GCF to provide security, but I would like to leverage the high scalability of the GCF archicteture and avoid the WSO2-am being a bottleneck.
Is it possible use the WSO2-am and make the GCF to check the permissions access against it, allowing the app calling the API directly instead of using the WSO2-am as a bridge ?
If yes, may you provide some documentation/blogpost/whatever that could help ?
In WSO2 APIM, the gateway does all the authentication and authorization stuff when the requests go through it (to the backend).
So, in the case of,
(1) OAuth2 tokens, the gateway talks to the key manager to validate the token, subscription (API-to-Application) and token scopes.
(2) Self-contained JWT tokens, the gateway can do all these validations itself.
So now in your case, since you don't want to send the requests through the gateway, you have to do what gateway does, within the cloud function itself. In that case, the JWT tokens will be the best choice as they can be validated without connecting to the key manager.
In addition to that, the gateway keeps a token cache so that it doesn't have to validate the same token again and again. You can have a similar cache (if possible) within your cloud functions too. However, in your case, you will have to externalize the cache due to the short-lifetime nature of cloud functions.
Here is the gateway code[1] which does the token, scopes and subscription validations. You can use it as a guide to write yours.
[1] https://github.com/wso2/carbon-apimgt/blob/master/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/jwt/JWTValidator.java

Firebase (client-side vs server-side)

I'm building a PWA with django/python on the server-side and vue on the client-side and want to use firebase as a database as well as make use of the firebase authentication.
After some thorough research I realised that I had to make a few choices.
Question 1: Authentication
I can do authentication on the client-side or server-side. Which one would be best (more secure) ?
Question 2: Database
In terms of CRUDS I am a bit conflicted. Do I write all my data to firestore from the client-side?
Do I rather use api's to communicate with my backend and then write data to firestore from the backend? What are the security implications of doing this?
Should I just use both in terms of context? If there are no security implications I would do my authentication client-side and my CRUDS from the server-side. I think I would also have to check authentication to write to the database from the backend.
Authentication of a user's credentials should always happen on a server, as it can't be securely done on the client's computer. What Firebase Authentication allows however, is that the authentication runs on Google's servers, while you control it from a simple client-side API call.

Best pattern for AWS Cognito / React frontend / Django Rest backend

Struggling to get this fully working - here is my app workflow:
React frontend - user authenticates w/ Cognito directly (using AWS Amplify) - I've got this working fine. The frontend needs to handle this, as it makes separate direct calls to other AWS services.
DRF backend - React then makes API calls to DRF endpoints using Amplify.API, which includes the x-amz-security-token in the request header (this appears to be the Session Token returned by Amplify's call to the cognito-idp service). So now the backend has the Session Token (but not the Access Token or Refresh Token)
The backend then simply needs to verify that the frontend user (whose authenticated identity I assume is represented by the Session Token) is a valid and currently authenticated user according to Cognito. So the backend needs to make a separate call to Cognito to verify this.
This is where I'm failing - I've looked at django-warrant, but I can't discern from the documentation whether this is appropriate for my use case (or even how to really use it - the default setup suggested results in various boto3 errors to do w/ lack of credentials, etc.). I've also looked at warrant and directly at boto3 and botocore but it is not clear to me where to make all this happen. Am I missing seeing some kind of is_user_valid and is_session_token_valid methods in these libraries?
If someone knows how to do this directly w/ django-warrant it would help, and if not a little advice on the best way forward would also be appreciated (do I write my own authentication backed or middleware to intercept the request, authenticate somehow w/ boto3 or botocore, or what?)
Many thanks

RESTful API using OAuth where authentication tokens are sent as part of the HTTP request

I am pretty new to developing APIs. This is part of my class project and the goal is to create a RESTful API in python where the delegation is done via OAuth and these tokens should be sent as part of the HTTP request.
I was advised that I should create an API that involves delegating the OAuth model into a proxy-like approach where authentication tokens are sent as part of the HTTP request. What exactly does a proxy-like approach mean? Any ideas?
I would really appreciate if anyone could help me out with this and also on how to create an API (even if it is not python specific, I can take cue from that)
If you are new to REST services, then this link will be nice kick start for you.
You can find here how to develop a basic rest api in python and the same with authentication.
So what is OAuth?
OAuth can be many things. It is most commonly used to allow an application (the consumer) to access data or services that the user (the resource owner) has with another service (the provider), and this is done in a way that prevents the consumer from knowing the login credentials that the user has with the provider.
For example, consider a website or application that asks you for permission to access your Facebook account and post something to your timeline. In this example you are the resource holder (you own your Facebook timeline), the third party application is the consumer and Facebook is the provider. Even if you grant access and the consumer application writes to your timeline, it never sees your Facebook login information.
This usage of OAuth does not apply to a client/server RESTful API. Something like this would only make sense if your RESTful API can be accessed by third party applications (consumers).
In the case of a direct client/server communication there is no need to hide login credentials, the client (curl in the examples above) receives the credentials from the user and uses them to authenticate requests with the server directly.

Categories

Resources