Trying to setup user pool authentication for API Gateway - postman

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).

Related

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.

AWS API Gateway Authorizer using Cognito Identity Pool

The test enviornment for the API Gateway..... Cognito Authorizer.
What value is it expecting ?
I tried to use accessKeyId returned from CognitoIdentityCredentials and it did not work.
Identity Flow
'Testing the accessKeyId gives Error
I also tried _identityId and that did not work as well.
The error for both is "Unauthorized request"
I think your API endpoints are protected by AWS_IAM authorization method. you can confirm it from the Method Execution section of your API endpoint.
If you are using AWS_IAM method, the api end points excepts a signature to be generated using your aws credentials and pass it in the request under the Authorization header.
You can use postman app to test the endpoint, follow these steps
create a new request with the correct http method and the url
under Authroization tab, select AWS Signature
Enter the values for AccessKey, Secret Key
under the Advanced section, enter your region and Session Token
Postman application is very handy to test rest api endpoints. it's even handy to test the api gateway endpoints protected by AWS_IAM authorization method. The postman app generates the signatures required using your AWS credentials and include the generated signature part of http headers of the request.
Note: Also make sure your identity pool's Authenticated role has permission to invoke the api endpoint.
Reference:
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
you can download postman application if you dont have - https://www.getpostman.com/downloads/

Using Cognito federated identity with API Gateway and postman

My objective is for my user to sign-in using Cognito and get a temporary IAM role that allows them HTTP access to specific methods in API Gateway.
What I have done so far:
set up my user pool
set up my identity pool
set up IAM roles for authenticated and unauthenticated users
set up a group with an IAM role allowing access to POST to (at
present) all API gateway methods.
put my user into the group
set up my API Gateway method to use IAM authorization
I can sign-in via Cognito in my browser using a front end created via Amplify.
When I check in the browsers local storage I can see I have the following:
idToken
accessToken
refreshToken
When I have done this using a COGNITO authorizer on the API Gateway all I had to do in Postman was add a Authorization header and paste in the idToken. This gave me access to the API.
How can I test my API using Postman with IAM authorization?
I am still given the tokens, but now pasting them in to the Authorization header gives me an error message:
Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.
I have read that I need to sign requests but I am unsure how I would do this from my web browser based application.
Even if I can do that how can I test in Postman, or is this no longer possible?
Ok, the requests can still be made via Postman but they must be in Amazon's Sigv4 format.
The solution is as follows.
Get the accessKey, secretKey and sessionToken returned from the sign-in process*.
In Postman, for the request, select the Authorization tab and for type choose AWS Signature.
Enter the accessKey, secretKey and sessionToken retrieved from step 1 into the corresponding fields in Postman.
You also need to set the AWS Region e.g. eu-central-1.
Press SEND.
Postman will create the appropriate Sigv4 request to call your API. You can see the result of this in Postman's Headers tab for the request where it will have automatically created the required headers.
*I added temporary code into my React/Amplify application to do this.

How to authenticate user in AWS Custom authorizer?

I'm trying to use AWS custom authorizer in API Gateway. If I understood correctly, then I should authenticate user in custom authorizer. I don't know who sends the request. I should detect the user by token using my own services. Right?
There are multiple authorizer options available
IAM authorizer
Cognito authorizer
Custom authorizer
If you use STS issued token to grant access to your AWS resources then you can use IAM.
Similarly Cognito authorizer is to authenticate the Cognito Userpools id token.
If you have your own authentication scheme or need customize authentication mechanism, you can use Custom authorizer.
Just wanted to add my 2 cents here, here is the flow :
Once the bearer token (you can use JWT as well), is issued to the
client (i.e. mobile app/web app), the client invokes REST API created, configured and deployed through API Gateway.
The custom authorizer, which is a lambda function written in Java
(you can implement it using NodeJS, C#, Python), would need to verify if the bearer token is valid. In my case, Bearer token is hashed using the SHA-512 algorithm. So we basically match if the token
stored in DB and the token presented by the client matche.
If the token matches then, custom authorizer returns IAM policy Allow but
it token is not correct then it returns IAM policy Deny,
The API gateway reacts based on the response from custom authorizer, if the policy is allow it passthrough the call to backend else it would return HTTP code 403.
Hope it would help.

Does Cognito User Pool Authorizer in Gateway API require all requests to be signed?

The documentation for using Cognito User Pool Authorizer with Gateway API says only that I should:
Call API methods configured with a user pool authorizer, supplying the unexpired token in the Authorization header or another header of
your choosing.
This is echoed by some other texts on the web.
However, when I try using the token, I get an error message that informs about missing Credentials, Signature, Signed Headers params (and the Date header). The token I am using is most likely correct as passes the test in the authorizer's web gui.
My question has two parts:
Does that mean that using the Cognito User Pool Authorizer requires
me to sign each request? Is there some way to configure it to just
accept a valid token?
If I want to keep my HTTP calls to Amazon Gateway simple and
authorize them with just the token (so that they can easily be
performed by hand, from Python backend etc.), am I forced to write a
custom authorizer using Lambda? Or is there some better option?
Cognito User Pool authorizer does not require a signature on the request. You simply have to pass the JWT version of the OpenID Connect identity token produced by Cognito in the authorization header of each request.
result.getIdToken().getJwtToken()
This should answer both your questions.
I think you are getting confused with the Cognito Identity service, which exchanges a valid identity from a public identity provider (Facebook, Amazon, User Pools, etc) for temporary AWS Credentials. You can use the AWS credentials from the Cognito Identity service to sign requests.
If you are only using User Pools, the result of a successful authentication are an OIDC identity token and a JWT access token. API Gateway, when configured with a User Pool authorizer, uses the identity token to authenticate a request.