2

I'm using boto3 for connect Amazon Cognito. I'm trying to use sign_up method; however, there is a parameter called SecretHash which I cannot understand how it is generated.

The original documentation about SecretHash:

SecretHash (string) -- A keyed-hash message authentication code (HMAC) calculated using the secret key of a user pool client and username plus the client ID in the message.

I'm getting error below, if I don't put SecretHash parameter.

botocore.exceptions.ClientError: An error occurred (NotAuthorizedException) when calling the SignUp operation: Unable to verify secret hash for client xxx

cagatayodabasi
  • 762
  • 11
  • 34

4 Answers4

10

Don't know if this helps, but if you're using the JavaScript SDK, in the Setup part 1, it states:

Create an app for your user pool. Note that the generate client secret box must be unchecked because the JavaScript SDK doesn't support apps that have a client secret.

I created another app without generating a client secret key and it worked.

user1432403
  • 1,533
  • 4
  • 16
  • 21
3

I just got off support with AWS regarding this question. Here is what i was told:

AWS REP: let me start from the begnining

AWS REP: the secretHash is not 100% stable

AWS REP: in order to call the function

AWS REP: the secretHash has to be ommited

AWS REP: so, you need to call it without secretHash

AWS REP: but.....

AWS REP: if you have configured your app with secret/security setting

AWS REP: cognito will not be happy if there is no secret hash

AWS REP: so you need to use a different app key

AWS REP: that was confiured without that setting

The rep was not sure about the algorithm that should be used and has opened a case to get the documentation updated.

Ian Laird
  • 442
  • 3
  • 9
3

The following works for me :

import hmac
import hashlib
import base64 

def signup( username, password, email, phone):
  msg=username + CLIENTID
  dig = hmac.new(str(CLIENTSECRET).encode('utf-8'), 
  msg=str(msg).encode('utf-8'), digestmod=hashlib.sha256).digest()
  d2 = base64.b64encode(dig).decode()
  dig = d2
  resp = pool.sign_up(
    ClientId=CLIENTID,
    SecretHash=str(dig),
    Username=username,
    Password=password,
    UserAttributes=[
            { 'Name': 'email', 'Value': email},
            { 'Name': 'phone_number', 'Value': phone}
    ])

This was after trying all permutations of inputs to the secret and message parts. The CLIENTID is from AWS User Pools 'App clients' -> 'App client id'. The CLIENTSECRET is from AWS User Pools 'App client' -> 'App client secret'.

Hope this helps

LazyBrush
  • 440
  • 4
  • 13
2

This example shows how you could generate HMAC with SHA256 hash algorithm in python using the hmac libraries. Calculating a SHA hash with a string + secret key in python

In this case the secret for HMAC will be your 'client secret'. And the message will be utf8 bytes of (username+clientId).

You only need to provide secretHash if your client has been generated with the secret otherwise secret hash can be committed in the call.

Also I would recommended you tot explore Cognito UserPools with our client side SDKs :javascript, android or IOS. As the SDKs handle the generation of secret hash for you.

Community
  • 1
  • 1
patanjal
  • 645
  • 4
  • 4
  • when I try to omit it by not sending this parameter, I'm getting the same error. – cagatayodabasi Apr 30 '16 at 15:52
  • You need to generate a new app client which does not require a secret by unchecking the "Generate client secret" box. Then you can omit this parameter for the new client. – Vinay Kushwaha May 17 '16 at 18:28