AWS API Gateway token test Response Code: 401 - amazon-web-services

Thanks if anyone can help me. I am building a cognito user pool + API gateway solution in AWS. Now the configuration is done but the token is not working. Here is how I tested,
I used API endpoint
https://mydomain/login?response_type=token&client_id=5gjg8956um7bf2h5c3fuav1o46&redirect_uri=https://www.example.com
to get a token, here is the result.
https://www.example.com/#id_token=eyJraWQiOiJiTTcrSVlMUHBHVTBQK3FnTmkrMWxSeGFyNjRrb3hxYUluemptZllMTmZ3PSIsImFsZyI6IlJTMjU2In0.eyJhdF9oYXNoIjoiMmJXdHU5STVMQUJkQWFTSmM5S3ZtQSIsInN1YiI6ImYwNDk3NjgwLWJlNDEtNGNlZC1iMzQ4LWQ0NTg3M2Q5OTg2MSIsImF1ZCI6IjVnamc4OTU2dW03YmYyaDVjM2Z1YXYxbzQ2IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImV2ZW50X2lkIjoiODIyMWI3MjQtMzI5ZS00ZGJjLThjZjktZjhlMjY5NWFiNjkzIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE1OTM5MDg1MjEsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl9Qa1ROR1RPNzIiLCJjb2duaXRvOnVzZXJuYW1lIjoiZjA0OTc2ODAtYmU0MS00Y2VkLWIzNDgtZDQ1ODczZDk5ODYxIiwiZXhwIjoxNTkzOTEyMTIxLCJpYXQiOjE1OTM5MDg1MjEsImVtYWlsIjoicWlhby5saUBob2xtZXNnbGVuLmVkdS5hdSJ9.lkTA49l_EQpWnhiLnKdbBR1anA0H4psFwEEBJuWgwQ6Iwg_GVZgvl3Sf0_p8OF-_vgRvcGbg1uI7nJdcTBs5EAcLV75AKfglQT7UjWXQtv10D7lh86sLNmIuLWRcJDV-8iCNSlHeFqJnBcskEH4yTXJI03s7Ikp9ZVZiNDW-wZzt6fW3n1SEtfN57sV4xvknByJBqswwUv07vL3URGk60MLMfLex16vVijBVHOhvMwWByEOpvWFMH3jY0NrGjx9ty5U4I-Bq1OvwJlR5SGPz2OjiPMdXnGM8eA-E8AUHjY8VtFIW4Ec6d74axlw7qMIayUHL8UaNMKKHSDM_giIpMg&access_token=eyJraWQiOiIxOEpWY2hGcWowQndhNjkxdUFlWW5IVThxdWdaWVhxOW9FaGFZNUd3cGtZPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJmMDQ5NzY4MC1iZTQxLTRjZWQtYjM0OC1kNDU4NzNkOTk4NjEiLCJldmVudF9pZCI6IjgyMjFiNzI0LTMyOWUtNGRiYy04Y2Y5LWY4ZTI2OTVhYjY5MyIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoicGhvbmUgb3BlbmlkIHByb2ZpbGUgZW1haWwiLCJhdXRoX3RpbWUiOjE1OTM5MDg1MjEsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl9Qa1ROR1RPNzIiLCJleHAiOjE1OTM5MTIxMjEsImlhdCI6MTU5MzkwODUyMSwidmVyc2lvbiI6MiwianRpIjoiMjVkM2MzMTYtNDNkMS00OTY5LTg3YTQtOTkxNWE3YzE0Y2FiIiwiY2xpZW50X2lkIjoiNWdqZzg5NTZ1bTdiZjJoNWMzZnVhdjFvNDYiLCJ1c2VybmFtZSI6ImYwNDk3NjgwLWJlNDEtNGNlZC1iMzQ4LWQ0NTg3M2Q5OTg2MSJ9.J0j9jZFzEG8gjowipZdJ_O_uXUKP5Jyk5PrZvWf5yVZ4jbdoJpgom3IcxFcaDvXbTkB_NNx9soq8Prc-whpYrjQ9RxDTd3Fb6ZyDOXhRaVQAmQSnagVr0_jPhH9Bw4_AS_4jNy4t27yDufpOnEgNWQW1sy96zpuaLFHJYAQblaJCxt_qbf_KETRDCil8ap63XUbAElaCvnSRrIGCcXmVOPChUMDSHVDu4CoMm9cgRQvj-kWFKP96YEO62tFa4_gZk1CICvjFEi7VCH0tvN9JVe8baSHm2GL1jaTeoUeE0jmGPGxGc-7fDBY37JjPbnPiHDZlm3D8eGE1AhO5qI3rng&expires_in=3600&token_type=Bearer
I verified the token on https://jwt.io/ and it is decodable. However, when trying to test the token in test tool in API gateway Authorizer, I got a 401 error.
Also, I tried to post the request in Postman as well and the result is also 401, with the following result.
{
"message": "Unauthorized"
}
My take is that if I can get a token through the endpoint, the token must be correct, right? How can I troubleshoot? thanks

Now I used the "wild rydes" app to sign in for a token, and the token will pass the Authorizer test in API gateway, also Postman API call is working.
Still, the token generated by "Hosted UI" in the Cognito does not work, as in the original question.

The Cognito authorizer on your API Gateway will accept either the ID token or Access token, depending if you specified an OAUTH scope to the API Gateway method when adding the authorization.
The Authorizer test on API Gateway will only accept the ID token. So I would suggest checking that you are getting a token from the correct Cognito UserPool that matches your API Gateway Cognito authorizer and then check your API Gateway method to see if you specified an OAUTH scope. If specified a scope, this scope will need to be in the Access token sent to API Gateway. If no scope specified, send the ID token.

Related

AWS API Gateway Authorizer always rejects Authorization Token

I am trying to only let users who are authorized via Cognito make requests to my lambda backend. So I created an Authorizer on my API Gateway that should only grant access to authorized users but currently, it is rejecting every request.
Then I tried testing it but it always rejects the jwtToken I'm giving to it.
I am sure that this jwtToken is valid and the user Account status is confirmed. I don't really have more information.
Thank you for reading this
You need to include 'Bearer' in front of the TOKEN, e.g. Bearer ey...

API Gateway unauthorized when using token

I am trying to test an API Gateway endpoint, using Postman.
I'm trying to make use of the Hosted UI, and whilst I can get an access_token returned in the URL, using this in the Authorization Bearer Token, I simply get 401 Unauthorized responses.
The specific endpoint has the correct authorizer attached to it.
I even tried removing the authorizer all together, but still got the 401 response, so I'm quite confused, as that should have meant I don't need to pass any token with the request?
Turns out, despite the naming convention, access_token was the wrong token to use. I tried th id_token and that works.
Solution: Add an OAuth scope if you want to use the access token otherwise use an id token.
From the documents
With the COGNITO_USER_POOLS authorizer, if the OAuth Scopes option isn't specified, API Gateway treats the supplied token as an identity token and verifies the claimed identity against the one from the user pool. Otherwise, API Gateway treats the supplied token as an access token and verifies the access scopes that are claimed in the token against the authorization scopes declared on the method.

AWS HTTP Api Gateway lambda authorizer how to return 401 if a token is expired

We have our API behind the AWS HTTP API gateway with a custom Lambda authorizer. Our JWT token contains an expiration time and base on that we have to return 401 when it is expired to tell the client to use his refresh token to update JWT.
Lambda authorizer returns only 403 even if the token is present but it is expired. So in this case we don't have a possibility to force users for token updates it is confusing a lot. It seems like your permissions just not allow you to reach the API URL instead of telling you that your token is expired.
With REST ApiGateway it seems possible but we can't use it because it doesn't work with APL, and this is a requirement.
Is it possible to return 401 from HTTP API Gateway custom Lambda authorizer?
It is possible, but it is not possible to customise the error message.
Depending on your function use either:
callback("Unauthorized", null);
or
throw new Error('Unauthorized');
Both of these will produce a 401 response.
See https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/blob/master/blueprints/nodejs/index.js

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/

Decoding an AWS Session Token

We are using AWS Cognito Federated Identities to obtain a Session Token from the AWS Security Token Service, then leverage for securing our APIs via API Gateway. This is working well.
But within our web service, we sometimes must obtain the issuer and subject from the JWT token used to derive the Session Token. For this, we are exploring AWSSecurityTokenServiceClient.
But my question is whether it's possible to simply decode the Session Token without invoking the Security Token Service for every API call. Thoughts?
Here is an example of the response provided by AWS Security Token Service, via API Call to Cognito Federated Services:
{"IdentityId":"us-east-2:4628a310-f743-43bb-8808-6123c744c664","Credentials":{"AccessKeyId":"ASIATTD56AWGXWG2GGES","SecretKey":"0TOwO2JMgWQLd6FvVrX5m9UKsDcFfQW3goG3NQ8Z","SessionToken":"AgoJb3JpZ2luX2VjEKH//////////wEaCXVzLWVhc3QtMiJHMEUCIQDDTKUnIQtIcztLVmpTsif9b9rj5yUOiBgfPNN3z16S6gIgUAlRFD8V9bpVokR0sqrtxN/5uPtaLf4vHGPAtUokj/kqpgUIehABGgwyNDcyMjQ3MzEwMjEiDE7afe4LMcTOdqF3niqDBbwZENnBEw3XyIdGz1AEPVY51gZ0KxkC7YgoAxpZVedZZUbIeAiGy+Ez2PtTzsVhO1WPiM5DqwTqb3/iuV2XsTXGf43qpTc2WsYypFUI51scF1J+pSGT58yAayTf5wwPi9I1kFWiBcDpuyemLwI2yfZB8hIuAvdr0MW6a7GVHR93xDfsx0T7aCFqZriUQTOpc9clpkQfygdhf7mHeYdMnD/HthZCh3mllS4I86Zzjr8wIypCqrV0A2OhVVvsLddjF8WF4WS0WhNEEQHoUs/jMkDjnrcvPBIeuU/hE2x+UfECmH5vDs0QarfsHR1HiLVL+EghINNF9eG4CzpVu0FBz8meJhPEJLlQMK9MdZ7ZGgtx7ZzT/7a/azoCpriOK9KganXsMfHbwLqnR96bXEC3ebFYtL638y25KZyn7rL/z5Ise/D5KjihQOuuRoxufgUWKoi6Or0r56bSpLhq7KCd0ZUweoKKvX/9RLF2YU0h+FYV4NRxar93jzKEYX63so/gxCaWWb7gRde/qca3fEZHHh0I26/DflrvWar6HDHu3Ee7aYJB/m5n4u1ko6SRvAdwmQ/hn1ttDgvUSpVq28IyxR4Ic9cBaS81ohRInM7i6NTSGHhpd6ij0l0F1Br8Vtr5UJe96xK7aNir3sspYqrSzd6y1DO6fnZKVaFpWDnWo4/SCdSp3F9bM4Q+GNICaT9Rcvyx1nJgofuqY4gdHdxv1PoIL8KEXz72U8aZ/immlhZ5kNrc/aM5KEJ4weE04mZ4u1t3GmN5xLFd7wqOCPUvrzamiEy4GMtm+kBF5rsa+eVRp+YpN2R6CsUpCqw8EEhE3w6RMV578Ah3sO0nBwXQXNQ7nKQwxoa57AU6tAHGr89nNR/Br3UahFBK5o9mQ297nbWB5C6PqCSShsheXzkJww0OdqMwmZgIfvikqnWNZC5KrfobiSancqCXKIRbuLtWcWT6+F9Q+eJQ50Rj1ctdN18H84cfQZYNjHRQVf7iTTcgfq8oqlJtmEavs8T2rvp3a9gp1QQEwjIHdCUQJRwM8h2RYFvLd6s48/XT9sxQj8OAmq8q/gw6/fOiRPFj9yq/Pw38IusTE0MFFwgAJWgUSAo=","Expiration":"2019-09-27T18:13:42.000Z"}}
Note the SessionToken is fairly lengthy, but does not decode when pasting into https://jwt.io
Yes, JWT token can be decoded without Security Token Service for every API call.
Please copy-paste the JWT token https://jwt.io and you can see the details.
This image has a full payload of what you are looking for, session Token and JWT token. I hope this is what you are looking for.
However, please note that only JWT token will be passed in API gateway.