12

We have been using Amplify and Cognito to register our users for an Angular6 application deployed to Lambda. The client wanted to transition from email to username as primary user identification. So we created a new user pool / client. I don't have visibility into the configuration settings, I was simply given new user pool, identity pool, and client id's. Then I changed the code for application signup to look like this:

  return from(Auth.signUp({
  'username': username, // was email
  'password': password, 
  attributes: { // added these
    'email': email,
    'phone_number': phone_number,
    'family_name': name,
    'birthdate': DOB,
    'custom:last_4_ssn': SSN // custom attribute
  }}));

The response I'm getting with no other changes made is: Unable to verify secret hash for client. Google claims the problem is that secretAccess is currently an unsupported configuration, but the guy who has access to these services swears to me that nowhere is secretAccess configured in our setup.

I apologize for not having access to the configuration, but is there any other possible reason to receive this error?

Arlo Guthrie
  • 1,152
  • 3
  • 12
  • 28
  • 1
    I found in aws documentation that a new user pool by default will have secret access key enabled. I believe that the person who configured this new user pool didn't realize he either needed to disable it or handle it. – Arlo Guthrie Sep 25 '18 at 13:37

2 Answers2

24

That error is probably originating from the fact that the app client you are connected to has an associated secret key. When you create a user pool app client, it generates a secret by default: enter image description here

Right now, with React-Native Amplify you have to use an app client that does not have a secret key generated. So when you create a new app client with your desired attributes, make sure the "Generate client secret" box is unchecked.

Zach
  • 472
  • 4
  • 9
  • 1
    Note: For the AWS JavaScript SDK this box should be unticked: https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js#user-content-configuration – Philip Murphy Feb 20 '19 at 02:36
1

The solution is to pass secret_hash along with the adminAuthInitiate Request. And to calculate the secret hash you can use the following method:

public static String calculateSecretHash(String userPoolClientId, String userPoolClientSecret, String userName) {
final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
        SecretKeySpec signingKey = new SecretKeySpec(
                userPoolClientSecret.getBytes(StandardCharsets.UTF_8),
                HMAC_SHA256_ALGORITHM);
        try {
            Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
            mac.init(signingKey);
            mac.update(userName.getBytes(StandardCharsets.UTF_8));
            byte[] rawHmac = mac.doFinal(userPoolClientId.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(rawHmac);
        } catch (Exception e) {
            throw new RuntimeException("Error while calculating ");
        }
    }

How to Pass Secret_Hash

Map<String, String> authParams = new HashMap<>(2);
authParams.put("USERNAME", <username>);
authParams.put("PASSWORD", <password>);
authParams.put("SECRET_HASH", calculateSecretHash(cognitoClientId, cognitoClientSecret, <username>));
AdminInitiateAuthRequest authRequest = new AdminInitiateAuthRequest()
        .withClientId(userPool.getClientId()).withUserPoolId(userPool.getUserPoolId())
        .withAuthFlow(AuthFlowType.ADMIN_NO_SRP_AUTH).withAuthParameters(authParams);
AdminInitiateAuthResult result = cognito.adminInitiateAuth(authRequest);
auth = result.getAuthenticationResult();
Vinagy
  • 133
  • 2
  • 11
Aaina Arora
  • 154
  • 1
  • 1
  • 11