AWS Cognito UserPool Authentication on HTTP Request - amazon-web-services

I'm building an API using the serverless framework. I'm trying to authenticate requests coming in through API Gateway by leveraging Cognito (UserPools), and giving each of my users their own authorization token for each API call they make.
Trying to test it with postman I'm not able to make a call and pass authorization. I've tried setting Authorization in the header with the App Client Secret, but I'm just getting "Unauthorized" back. Is there something I'm missing?

You should be using the token rather than the App Client Secret. How are you retrieving the token?

For user sign in authorization, you must be sure you uncheck the option to generate client secret when you are creating a new Client Application inside UserPool.
In your API Gateway you create an authorizer making a reference to you before created UserPool. Inform "authorization" for the header.
Using a AWS third party SDK service (or just their API), signin with a valid user. You will get 2 types of tokens after the login, make sure you keep the right one. I advise you to check the token through the API Gateway authorizer testing option. Note: This step is the most important, as you are isolating the token you get and the authorization service. This way you can track the source of your problem.

Related

AWS API Gateway Authorizer does not authorize non-default Cognito User Pool App client tokens

I have created a new app client in Cognito, the tokens from the default app client are marked as valid by the API Gateway but not the token from the new App Client.
The API Gateway responds with HTTP 401 - UnAuthorized.
This should work because both the app clients have full permissions to the underlying users stored in Cognito.
I couldn't find any relevant documents explaining this discrepancy.
So, I was linking my AWS User pool to Amazon Alexa Smart Home Skill using this blog https://aws.amazon.com/blogs/compute/amazon-cognito-for-alexa-skills-user-management/.
On successfully linking the skill, Alexa would only send the accessToken in the subsequent API's.
The AWS API Gateway authorizers only check for the ID token and will deem the request invalid if it is given an AccessToken.
Thus, the requests were failing. It has nothing to do with default or non-default app clients.
Using a Cognito custom authorizer seems the best option, will disable API Gateway authorization.

Using Authorizers in API Gateway and Cognito User Pools

I've managed to setup a third party google login by integrating it with Cognito user pools. On successful sign-on, I am able to access an id_token as a query parameter in the redirect url.
I'm trying to sign REST calls to API gateway using this id_token. I have an authorizer configured on that particular API using Cognito user pools. When I try to test this on the Authorizer UI by setting the Authorization(header) field to this id_token which I received as a query parameter, I keep getting an Unauthorized request error.
Also, I have configured an IAM policy for my user according to this doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-user-pool-authorizer-permissions.html
Can someone help me with what I'm doing wrong?
Thanks
Turns out you have to pass the access_token that Cognito returns as part of the authorization header. You can try if your access token works by testing it in the UI offered by the Authorizor interface of API Gateway.

How do I authorize CognitoIdentityCredentials for my API?

I have a Serverless backend that implements AWS_IAM authorizer using the serverless framework.
My client is a React application. I am using AWS Cognito to authenticate users and AWS Federated Identities to retrieve temporary credentials for the user.
The user is assuming an IAM Role that has APIGatewayInvokeFullAccess policy attached. I then sign my request using aws4 and make my request using Axios.
To my understanding, I am doing everything right. But, I am still receiving a 403 error on my client request. I even logged the tokens that are being retrieved to the console and used those tokens in postman. When I use postman, the error message says "The security token included in the request is invalid". I have read every doc and tried every possible solution, but I am still unable to debug this error. Any help at all would be incredible.
I am following this guide for the application flow.

Trying to setup user pool authentication for API Gateway

I'm trying to setup security on an API using Cognito user pools. I'm getting back 401 Unauthorized.
The API and User Pools are existing, and I've been using the user pool to log into an application. I'm now trying to secure the API calls.
I created an authorizer on the API,
Then I added the authorizer to one GET method in the API
Then finally I tried to test the API in Postman. I'm using the AWS Signature authorization.
Calling the method returns 401. The method functioned before with no security, and turning off the authorizer makes it work again (without security).
Any ideas what step I'm missing?
The AWS Signature authorization is different than a Custom Authorizer.
The AWS Signature authorization (Postman) requests an AWS AccessKey and SecretKey to authenticate requests. This corresponds to IAM Authentication in API Gateway. The AccessKey and SecretKey are received through IAM.
A Custom Authorizer takes a JWT called #id_token that is issued by your specified Cognito User Pool. To test the validity of the token, go to your custom authorizer and click test, and then copy and paste the token into the text area.
The way to perform the Custom Authorizer authentication is this:
obtain an #id_token from the your user pool by following AWS Configuration
Configure API gateway with a Cognito custom Authorizer with your user pool as the source (Seems that you have done correctly)
Use OAuth 2.0 as Authorization in postman, with your #id_token as the Access Token, Or add the header: Authorization with the value Bearer and the #id_token
Drop a comment if you want me to add the AWS Signature Auth Flow.
For authorization using Postman when using Cognito user pools, chose No Auth. Then add a header Authorization (the value in token source field of your authorizer) and copy the id_token into that header value. I did not have to add anything else besides that to make it work (i.e. no bearer).

AWS API Gateway authentication error IncompleteSignatureException using JWT with Auth0

Where I'm At
I'm currently working through setting up Auth0 delegated authentication for AWS API Gateway. I've followed the documentation and tutorials below with the exception that I have an app in place rather than their example apps:
https://auth0.com/docs/quickstart/spa/angular2/aws
https://auth0.com/blog/2015/11/10/introducing-angular2-jwt-a-library-for-angular2-authentication/
https://auth0.com/docs/client-platforms/angular2
https://auth0.com/docs/integrations/aws-api-gateway/part-2
What is Working
Auth0 sign on from my Angular2 app is working correctly and I'm getting a token.
Auth0's AuthHttp component is attaching the bearer token to the Authenticate header when I call the AWS API Gateway.
What is Not Working
Status 403 response from AWS API Gateway indicating a Cloudfront IncompleteSignatureException; "Authentication header missing equal-sign".
The authentication header is
Authentication: Bearer edJ0e...[I've truncated for brevity]
Could AWS be expecting a different type of authentication which uses key value pairs? How to I tell AWS API Gateway that it should be looking for a JWT?
I'm guessing you have AWS_IAM authentication enabled for your API Gateway endpoint. You need to disable that if you aren't planning to use it. If you plan to use AWS_IAM authentication in addition to JWT then you will have to send the JWT token using a different field.
From part 5 of the Auth0 tutorial you linked:
The final step is to pass the JWT to the method from the browser
client. The standard method is with an Authorization header as a
bearer token, and you can use this method if you turn off IAM
authorization and rely solely upon the OpenID token for authorization
(you will also need to map the Authorization header into the event
data passed to the AWS Lambda function). If you are using IAM, then
the AWS API Gateway uses the Authorization header to contain the
signature of the message, and you will break the authentication by
inserting the JWT into this header. You could either add a custom
header for the JWT, or put it into the body of the message. If you
choose to use a custom header, you'll also need to do some mapping for
the Integration Request of the POST method
Based on the error message, it sounds like you've configured your API for AWS_IAM authentication. This requires your request be signed with AWS Signature Version 4.
In order to execute API Gateway functions you will need to do 1 of 3 things:
Get AWS credentials via IAM/STS as noted in the auth0 example and use those to sign your request.
As noted in Mark B's answer, follow the instructions in step 5 of the tutorial from auth0 and disable AWS_IAM auth and do the validation inside your Lambda.
Switch to use a custom authorizer to validate the JWT directly at the API Gateway layer. This would require you to take the code Auth0 provides to validate the token then build your own authorizer result.
(Posted on behalf of the question author).
Update
Both Mark B and Bob Kinney are correct. What I did (and you may have as well) is jump around in the various Auth0 links I posted at the top of this question and attempt to use their angular2-jwt library (with the AuthHttp component) to adapt the tutorial to Angular2 while following along with their 5-part example of setting up Auth0 with AWS API Gateway. The AuthHttp component will automatically put the JWT Bearer token in the "Authentication" HTTP header which is incompatible with an AWS API Gateway call secured by IAM authorization. As these gents showed me, this is explained in part 5 of the tutorial. If you only made it to part 4 and it's not working hopefully this answers your question as it did mine.
Update 2
The Auth0 Angular2 tutorial has been updated to reflect Angular2 rc 1. https://auth0.com/blog/2015/05/14/creating-your-first-real-world-angular-2-app-from-authentication-to-calling-an-api-and-everything-in-between/