I created an API with AWS API gateway that triggers a lambda function. Now I want to restrict access to this API. I own an OpenID connect identity provider.
I want to require people to authenticate with my OpenID identity provider before accessing the API. What is the best way to do that? Apparently, I need an authorizer for my API. I read a lot of documentation, and from what is mentioned here, it seems that this would be possible with amazon cognito. However, here I can only find a way to use cognito user pools, while I want to use a cognito identity pool.
I want the typical authentication scenario, e.g. user calls the api, is redirected to my openid id provider, logs in, and can then access my api (which delivers html so all of this will be taking place in a web browser).
Is this actually possible with cognito, or do I need to write a custom lambda authorizer? If so, is there any documentation on writing an authorizer lambda that uses openid, prefereably in .NET?
You are mixing Authentication and Authorization.
Federated Identity Provider to Cognito:
You can use OpenID Federated Identity provider for Authentication.
Below documentation provides on how to configure it,
https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html
Once authenticated you can create a signed URL to protect your assets for the URL which you want to allow to.
Creating Signed URLs:
Below documentation providers on how to created signed URL's using C#.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateSignatureInCSharp.html
Custom Authorizer:
Following commit on github shows an example implementation of C# custom authorizer.
https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/pull/13/commits/79d75fb7c5ee4f29fa06fd2ec28c704224cf8a7a
Hope it helps.
Related
I am watching an AWS reInvent video: https://www.youtube.com/watch?v=kmVUbngCyOw&feature=emb_logo&ab_channel=AmazonWebServices where it suggests to use Cognito pool per tenant.
This is what the authentication looks like and introduces an Auth manager to Auth against Cognito and gets back a JWT token based on OpenIdConnect.
I was reading another blog post here: https://medium.com/#tarekbecker/serverless-enterprise-grade-multi-tenancy-using-aws-76ff5f4d0a23
and It suggested using a Custom Authorizer attached to the API gateway.
Am I right in understanding that we should basically be authenticating in 2 places ->
From the web app using Auth Service
At API gateway using custom authorizer
Generally, people use the AWS SDK to authenticate the user from Cognito and it handles the whole authentication logic. AWS-SDK is available in almost all popular languages.
As API gateway is the frontline service or the publically exposed service through which you can access the microservices hosted using Lambda. Also, ApiGateway interacts as an intermediary/broker service between any client application including Web and Lambda microservices.
Custom Authorizer is used for implementing the custom authorization logic at the API Gateway service i.e. if a user role doesn't have any access to certain Apis it'd just give an error to the user trying to access those resources.
For example how we used Custom Authorizer in the past. We had users with 2 role types
Admin
User
We had to restrict the access of the admin Apis. So we added all this logic to authorize access to the Apis based on the information we get in the bearer token.
https://aws.amazon.com/blogs/compute/introducing-custom-authorizers-in-amazon-api-gateway/
I have a lambda function running behind the aws api gateway, that acts as the backend for my website. It uses a cognito authorizer to authenticate the users of my website. This works fine.
Now I need to authenticate a c# backend service against the api that is not running in the cloud has no user interaction. It should just synchronize data.
My initial plan was to configure cognito credentials and log into the cloud via the cognito sdk but this is not possible as the app would then need developer access to my cloud.
I also thought about using the api gateway api keys but I would still need the cognito authentication then.
So how can I authenticate my c# service against my aws api without user interaction being nessecary?
You could use Cognito User Pool Authentication.
This is an OpenID implementation where Cognito issues JSON Web Tokens (JWTs) where the signature of a JWT can be verified with a public endpoint.
In the context of API Gateway, you would use a Lambda as a custom authorizer, but the tokens could be verified in any environment/language with a relevant JWT Library.
More reading: Verifying a JWT issued by Cognito
I would like to make a simple API available to a client. The client uses the output of my API within his application. The API is a pretty simple one. I'm deploying with the serverless framework to AWS Lambda. The functions exposed via the API don't use any other AWS services (like S3 etc).
My question is what kind of authentication to use. I was thinking to try to use cognito for this.
1. Question:
Does this make sense? Or is for this simple use case even an easier option available?
2. Question:
So I get this right. I would first create a user pool. Then create an identity pool based on this user pool?
3. Question:
At the end, my client gets the access token from cognito and attaches is to the header in the request. This gives him then access through API Gateway to my REST API and the lambda function is triggered. But how does the client in the first place can create an "account" doe the user pool? Am I involved i this?
Cognito Authentication does sound like a good option for this use-case. You can have a flow as follows:
Cognito User Pool Authentication -> Token passed as header to the API in API Gateway -> API returns JSON data after successful authentication
[a].
I would like to emphasise that a Cognito User Pool is enough to satisfy this use-case. Cognito User Pools are used for Authentication, and Cognito Identity Pools are used for Authorization. Cognito Identity Pools essentially generates temporary AWS credentials, which are vended by AWS STS. Hence, I do not see where you would require Cognito Identity Pools here.
And to generate a JWT Token, you would need to have the user perform a successful authentication operation. To perform a successful authentication operation that returns tokens, you could have a look at the InitiateAuth API call[b].
References
[a]. https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
[b]. https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html
We have our rest API deployed on AWS Lambda behind API Gateway. For users that use our web client, they are authenticated using API Gateway Authorizer through JWT token from Cognito.
Now we want to give users the ability to create their own API credentials (API key and secrets) so that they can use the REST APIs directly without using the web client. How can we achieve that?
yes you can do it you can use federated identity and make user to signup and they can get their own api key and secrets. you can also change the flow of the cognito as per your need and make new lambda and add it to cognito as trigger.
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
I'm using AWS Gateway as my web API with AWS Lambda as my serverless backend. Lambda functions are only invoked by my Gateway APIs. Through Lambda I call and execute operations on other AWS Services (RDS, SNS, etc.).
I want only my clients to get access to my web APIs. To do so I setup all of my Gateway APIs with AWS_IAM authorization. An unauthenticated client have only policies that let him invoke e.g. the function for login/sign up a user. In comparison an authenticated client have policies that enables him to access more recourses.
The question now is: Because I only want my clients to get access to my Gateway APIs and to do it as secure as possible, is it necessary to create a custom authorizer which checks the validity of tokens?
Neither I did setup a cognito user pool, nor I did setup a external public provider (google, Facebook, openId, amazon, etc.). I'm working with custom developer authenticated identities. All users are saved in AWS RDS. When a user tries to login and gets correctly authenticated through his email and password a open id and a jwt token is returned to the client. This is done by invoking 'getOpenIdTokenForDeveloperIdentity'.
I found some recourses on the web where people created a custom authorizer, but they did always verify the validity of the token by a external provider (google, facebook, auth0, etc.). This member did wrote that you only need to have a external provider when you have "[...]some totally different auth logic[...]" https://stackoverflow.com/a/39407156/5181862. And I don't think this is the case here.
The clients that run the application are iOS and later Android devices, if this information is necessary.
If all the APIs have AWS_IAM authorization, that is already pretty secure. AWS_IAM requires that the client have valid AWS credentials from the same account as the API (your account).
It sounds like you are using Cognito (talking about unauthenticated client policy), in which case your authorization model is secure if implemented correctly.