Amazon Cognito "RespondToAuthChallenge" - returns a NotAuthorizedException, Incorrect username or password

3.3k Views Asked by At

In cognito user pools I have two different groups: Admin & User. I want to allow admin users to create cognito user, so I created new user with AdminCreateUser method of CognitoIdentityServiceProvider. Ref Link - https://docs.aws.amazon.com/cognito/latest/developerguide/how-to-create-user-accounts.html

Now I want to authorize the user in userpool. I am following this link - https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html - Client-Side Authentication Flow. But “RespondToAuthChallenge” - returns a NotAuthorizedException, Incorrect username or password.

import * as AWS from 'aws-sdk'
import { SRPClient, calculateSignature, getNowString } from 'amazon-user-pool-srp-client'


const userPoolId = 'XXX'
const ClientId = 'XXX'

const verifyUser = () => {
    AWS.config.region = 'us-west-2'
    const srp = new SRPClient(userPoolId)
    const SRP_A = srp.calculateA()
    var params = {
      AuthFlow: 'USER_SRP_AUTH',
      ClientId,
      AuthParameters: {
        USERNAME: formState.email,
        SRP_A,
      },
    }
    let cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider()
    cognitoidentityserviceprovider.initiateAuth(params, function (err, data) {
      if (err) {
        const error = err.message ? err.message : err
        console.log(error)
      }
      else {
        console.log(data) // --> data.session is undefined
        if (data.ChallengeParameters && data.ChallengeName) {
          const passwordAuthenticationKey =
            srp.getPasswordAuthenticationKey(
              data.ChallengeParameters.USER_ID_FOR_SRP,
              formState.password,
              data.ChallengeParameters.SRP_B,
              data.ChallengeParameters.SALT
            )
          const dateNow = getNowString()
          const signatureString = calculateSignature(
            passwordAuthenticationKey,
            userPoolId,
            data.ChallengeParameters.USER_ID_FOR_SRP,
            data.ChallengeParameters.SECRET_BLOCK, dateNow
          )

          var params = {
            ChallengeName: data.ChallengeName,
            ClientId,
            ChallengeResponses: {
              // PASSWORD_VERIFIER
              PASSWORD_CLAIM_SIGNATURE: signatureString,
              PASSWORD_CLAIM_SECRET_BLOCK: data.ChallengeParameters.SECRET_BLOCK,
              TIMESTAMP: dateNow,
              USERNAME: data.ChallengeParameters.USER_ID_FOR_SRP,
            },
            Session: data.Session, // undefined
          };
          cognitoidentityserviceprovider.respondToAuthChallenge(params, function (err, data) {
            if (err) {
              const error = err.message ? err.message : err
              console.log(error) // Incorrect username or password
            }
            else {
              console.log(data)
            }
          })
        }
      }
    })
  }

I created diff users, but no luck. User gets registered but respondToAuthChallenge throws error. InitiateAuth response returns challengeName and challengeParameters but session is not provided.

I found this statement which I am not able to comprehend - "When the next operation of RespondToAuthChallenge proof of password runs, Amazon Cognito returns a generic NotAuthorizedException error indicating either user name or password was incorrect." in https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-managing-errors.html

Kindly let me know if you have any solution/idea, thanks!!

1

There are 1 best solutions below

1
On

Firstly, the Session field is not a required field based on the RespondToAuthChallenge documentation so you might not even need to pass it for PASSWORD_VERIFIER challenge if its not provided.

secondly, Can you include the complete error message and the responses you are getting from both the initiateAuth and the respondToAuthChallenge operations so I can take a look?

Also bear in mind that the session field in the response from initiateAuth operation is "Session" with uppercase "S" (here is the doc for initiateAuth operation) so instead of data.session you have to fetch the session value with data.Session instead.