Cognito Service Authentication returns valid JWT but subsequent JWT validations fail

Viewed 163

I have a lambda that accepts a username and password and returns a JWT. The code (seen below) basically uses cognito adminInitiateAuth() to use the username and password to get the JWT.

        let USER_POOL_CLIENT_ID = "6adc4ziG7GCzYmMwhWWVnJySbP"; 
        let USER_POOL_ID = "us-east-1_upxvqiJUP"; 
        AWS.config.update({region: 'us-east-1'});
            

        const cognito = new AWS.CognitoIdentityServiceProvider();
        let params = {
            AuthFlow: "ADMIN_NO_SRP_AUTH",
            ClientId: USER_POOL_CLIENT_ID, 
            UserPoolId: USER_POOL_ID,
            AuthParameters: {
              USERNAME: event.username,
              PASSWORD: event.password
            }
          };

        //console.log(`${JSON.stringify(params)}`);
        const jwtContainer = await cognito.adminInitiateAuth(params).promise();
        console.log(`jwtContainer = ${JSON.stringify(jwtContainer)}`);

This seems to work and, in fact, does return a valid JWT with a kid decoded by jwt.io. Whenever I attempt to use the JWT on a different endpoint that is JWT protected (as seen below) I get an error:

curl -v https://myapi.execute-api.us-east-1.amazonaws.com/reset-service-auth-password \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -X POST \
  -d '{"password": "xyz123","confirmPassword": "22221"}' \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Origin: http://localhost:8080" \
  -H 'Authorization: Bearer jwtdataxxxxxxxxxxxxxxxx'

But when I execute the above I get this error:

www-authenticate: Bearer scope="aws.cognito.signin.user.admin" error="invalid_token" error_description="unable to find an appropriate key in the JWKS. Ensure a "kid" is provided in the JWT, and that your JWKS has a supported cert available for this ID"

I checked my JWKS and the kid in the JWT is in fact in the JWKS. I am not sure what to do next or what is really wrong.

My authorizer expects the scope aws.cognito.signin.user.admin and my client does not require a secret. Please ask any clarification that you might need to help me with this issue.

1 Answers

I've had the same issue today. I hope you figured it out since then but, just in case, and for others...

I followed the same investigation steps that you did. I was convinced there was something wrong with AWS. There's not.

In my case, the token was generated against our production pool, but a development endpoint leaked in the config, and we were trying to authenticate on a wrong endpoint.

So my guess is that you got something similar: recheck your URLs, there's probably a mismatch between your pool ID and the API you request.

Related