I am configuring an app with various frontends (mobile and web apps) and a single API backend, powered by Lambda and accessed via AWS API Gateway.
As I'm planning to use Cognito to authenticate and authorize users, I have set up a Cognito User Pool authorizer on my API Gateway and several API methods.
With an architecture like this, it seems logical that my apps (e.g. an iOS or Vue.js app) are the Client applications from an OAuth perspective, and my API Gateway backend is a Resource Server. Based on this Auth0 forum post it seems clear that I should therefore use an ID token in my client app, and pass an Access Token to authorize my API Gateway resources.
When I hit the Cognito /oauth2/authorize
endpoint to get an access code and use that code to hit the /oauth2/token
endpoint, I get 3 tokens - an Access Token, an ID Token and a Refresh Token. So far so good, as I should have what I need.
This is where I've run into difficulties - using the test function on the API Gateway Cognito User Pool Authorizer console, I can paste in the ID token and it passes (decoding the token on-screen). But when I paste in the Access Token, I get 401 - unauthorized
.
In my Cognito setup, I have enabled Authorization Code Grant
flow only, with email
and openid
scopes (this seems to be the minimum allowed by Cognito as I get an error trying to save without at least these ticked).
Do I need to add some specific scopes to get API Gateway to authorize a request with the Access Code? If so, where are these configured?
Or am I missing something? Will API Gateway only allow an ID token to be used with a Cognito User Pool Authorizer?
Step 3: Configure Cognito Authorizer for API Gateway Go to “Resources” and select “GET” method. Select “Method Request” configuration on right pane. Select “Cognito_Authorizer” in “Authorization” drop-down. That should automatically add a new field “OAuth Scopes”.
If you're building APIs with Amazon API Gateway and you need fine-grained access control for your users, you can use Amazon Cognito. Amazon Cognito allows you to use groups to create a collection of users, which is often done to set the permissions for those users.
Answer: Choose (or create) a method on your API. Explanation: Choose Method Request.
You can use the tokens to grant your users access to your own server-side resources or to the Amazon API Gateway. Or you can exchange them for temporary AWS credentials to access other AWS services. Your app must be able to store tokens of varying sizes.
You can use an access token with the same authorizer that works for the id token, but there is some additional setup to be done in the User Pool and the APIG.
Even when this extra setup is done you cannot use the built-in authorizer test functionality with an access token, only an id token. Typical 80% solution from AWS!
To use an access token you need to set up resource servers in the User Pool under App Integration -> Resource Servers
it doesn't matter what you use but I will assume you use <site>.com
for the Identifier and you have one scope called api
.
No go to the method in APIG and enter the Method Request
for the method. Assuming this is already set up with an authorizer tested with the id token, you then add <site>.com/api
to the Settings -> OAuth Scopes
section.
Just by adding the OAuth Scope it will make sure that the token now has to be an access token and an id token is no longer accepted.
This is detailed here: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html
For those looking for an answer and are not using OAuth and are deploying using Serverless framework:
What worked for me to make APGW accept accessToken was to modify my serverless.yml file as follows:
functions:
my-function:
handler: path to source file
events:
- http:
path: my-function
method: post
cors: true
authorizer:
type: COGNITO_USER_POOLS
scopes:
- YOUR SCOPE HERE <- THIS IS THE TRICK
authorizerId:
Ref: ApiGatewayAuthorizer
The value of the scope can be found by reading the contents of your accessToken (for by pasting the token into https://jwt.io/ debugger).
Yes, API Gateway will only use idToken to Authorize.
After user enters correct credentials, Access Code is provided by Identity provider authorizing that the user entered correct credential and this access code is used by
client just to get you idToken and refreshToken from /oauth2/token
endpoint for that given user. All your further calls would only use idToken in Authorization header.
Even that access code expires after you retrieve you user tokens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With