34

I am trying to use aws api gateway authorizer with cognito user pool. It is working fine when i test using aws api gateway console.

But when i try enabling the authorization in the api it says "message": "Unauthorized". Please check below screenshot

API Gateway Console Screenshot - This works fine enter image description here

Postman Screen shot - Not working enter image description here

Can someone help please.

FYI I have followed the instructions as mentioned here http://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html

Manivannan Guru
  • 463
  • 1
  • 4
  • 10
  • 1
    Is it just `username` rather than `cognito:username`? I haven't used that exact method, but I'm not sure that part is right. – Art Ianuzzi Sep 23 '17 at 13:15
  • 1
    cognito:username is the response i get for successful authorization. Even I get same type of issue for custom authorize also. For sure am doing something silly but cannot figure it out. If someone can help that would be great.. – Manivannan Guru Sep 25 '17 at 03:56
  • I'm sorry, I mistook that for your code. Postman is saying there are 12 headers in the response. Can you post those? – Art Ianuzzi Sep 25 '17 at 11:40
  • Also, you should try sending the request using the code in the AWS SDK as well as the Cognito SDK, because there are request headers that you may be missing in the Postman request. Finally, look at the headers in the request (from inspect/network in the browser) and make sure your AWS policy matches those headers exactly or you'll have CORS issues. See: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/cors.html - especially step 4 – Art Ianuzzi Sep 25 '17 at 12:06
  • Sorry for the delay, due to project urgency as of now I have I have created a lambda function and pointed it to custom authorizer. I have decoded the jwt (access token from cognito) in the lambda as per below link. This works pretty well for now. https://aws.amazon.com/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway/ Will check your reply and let know the results – Manivannan Guru Sep 26 '17 at 12:45

10 Answers10

51

In my case, authorization code should be id_token. I made a mistake for using access_token instead

Long Nguyen
  • 9,898
  • 5
  • 53
  • 52
  • 2
    Same problem for me, and same solution. Thanks! – Craig Walker Jul 10 '19 at 05:31
  • 2
    Thanks, took me 2 days too. – Yunwei.W Jul 28 '19 at 14:46
  • 3
    Glad I found this as soon as I got the issue. Weird that access_token is not the one. – Hoon Jun 12 '20 at 04:51
  • 4
    honestly this is completely baffling tbh. What the heck is the point of the access_token then? oauth scopes are not even apart of the id_token so unless it's fetching the access_token again i dont get it – Byrd Jul 10 '20 at 13:50
  • this was the solution for me too. Byrd ses the answer by Harsh Manvar further down – jsaddwater Dec 02 '20 at 10:59
  • You made my day ! Thanks. Why is it not access_token ??? – Salem Sep 17 '21 at 08:57
  • 1
    Here's the link that explains how access and id tokens differ: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html Main difference I notice is access_tokens allow us to get user groups of users. – Kerem Sep 19 '21 at 00:54
  • Isn't using an id_token for authorization a bad practice? From the [auth0 docs](https://auth0.com/docs/secure/tokens/id-tokens): *ID Tokens should never be used to obtain direct access to APIs or to make authorization decisions.* – binford Jun 27 '23 at 13:35
17

The below steps fixes the problem for me. In short, there seems to be a bug in AWS API Gateway. You can fix it by re-deploy the API:

  1. Change the Request Validator from NONE to Validate Body
  2. Actions -> Deploy the API -> choose the stage you want to deploy it to.
  3. Change the Request Validator from Validate Body to NONE
  4. Redo step 2.

enter image description here

C.Lee
  • 10,451
  • 9
  • 31
  • 46
8

I tried Mathias' solution out and it didn't work at first. Oddly, I can back to it hours later and tried again, and this time made some other changes to my API gateway before deploying the API. This time it worked, even though the other changes that I made were superficial.

Also, as is so often the case, the AWS docs are wrong, stating that you should use method.response.header.Authorization. This is really only valid for Lambdas using custom auth. You should indeed use just Authorization here when you are using the new Cognito User Pool Authorizer.

  1. Use Authorization not method.response.header.Authorization
  2. Make a superficial change to your resource in API Gateway
  3. Deploy your API and wait a second

-- edit --

I was just converting my stack to Cloudformation and found out that if you are using Cloudformation to deploy the Authorizer, you do in fact need to specify the full method.response.header.Authorization for the token source. In fact, a stack deploy will fail if you don't use that format. However, once deployed, if you look at the Authorizer in the console, it will have dropped the method.response.header part.

Miles
  • 1,682
  • 1
  • 13
  • 22
4

If you are not checking scope at OAuth Scopes in method execution block of API gateway it will only take id-token.

Once you will have set OAuth scope restriction on request it will start taking access token automatically.

Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102
  • 1
    This was my issue, as soon as I added the cognito resource server custom scope in the api gateway method request it worked first time accepting the access token (after api re-deployed). Testing the authorizer never worked for me though. – ste Nov 30 '22 at 18:28
3

I had the same issue like you and realized that I entered a wrong Token Source.

Enter in <your API> -> Authorizers -> Token Source the name of the HTTP header where the API gateway has to look for the token. (in your case Authorization)

Save it and don't forget to deploy before you test it out.

enter image description here

Mathias
  • 1,819
  • 4
  • 22
  • 34
  • 1
    FYI I have given Authorization as token source and also deployed the API, still facing same issue. – Manivannan Guru Oct 03 '17 at 03:51
  • How did you do that pixelization? That's a really cool effect I want to know how to use that for my presentations – MeestorHok Feb 18 '19 at 22:59
  • 2
    If i remember right i copied it to microsoft paint, selected the area, made the area really small and then again back to original size. – Mathias Feb 19 '19 at 06:08
3

I had the same issues, the solution was just to redeploy the project.

sigmaxf
  • 7,998
  • 15
  • 65
  • 125
  • 1
    Yes, this incredibly solved the issue. I by mistake deployed a wrong authorizer and when I changed it, it was still bugged, I delete the entire stack and re-deployed and it worked. – Matteo Feb 10 '20 at 02:46
  • 1
    you are the best. after trying everything, this simply solved the problem. – Arootin Aghazaryan Dec 01 '20 at 15:05
3

Try below 3 steps (do not forget to deploy API) and try to send a request with POST man

  1. Cache

enter image description here

  1. Settings of Method Request

enter image description here

  1. Deploy API

enter image description here

Patrick
  • 5,526
  • 14
  • 64
  • 101
ShanmugaKS
  • 31
  • 3
3

Credit to Srce Cde channel on YouTube, https://www.youtube.com/watch?v=f8rbpHf9SiA, adding 'openid' as OAuth scope on the endpoint settings makes access_token usable.

AddingOpenidScope

Bear in mind this will make id_token unusable. For those looking for the difference between id_token and access_token, here's the link: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html

Kerem
  • 1,494
  • 2
  • 16
  • 27
2

In my case, I thought that I needed to prepend the ID token in the authorization header with 'Bearer', after having looked at example documentation coming from Amplify. Removing 'Bearer' resolved my issue (and indeed the check for the token shape.) Also, check your CORS configuration!

QWERTYUIOP
  • 46
  • 1
  • 1
    This, plus using `id_token` rather than `access_token`, as expressed [here](https://stackoverflow.com/a/51107194/5134722), worked for me. – Colm Bhandal Jul 06 '22 at 16:18
1

Changing the Token Source in the Authorizer to something other than Authorization (eg: authorization) then deploying the API and giving that in Postman's headers worked for me. No matter what we call the header, it will be translated and used by API gateway I guess.

MSahi
  • 11
  • 2