I am trying to use Cognito User Pool to authenticate with a PC application using an HTTPS call. I want to obtain the various tokens that I can then use to access the AWS resources without storing AWS secrets in the PC application.
The AWS documentation documents the InitiateAuth method and shows the AWS Endpoints, but it is not immediately apparent how to make the call over HTTPS. Most calls would require an AWS signature, but the InitiateAuth call should not, if I am just submitting Username and Password.
After some poking around, I was able to use the AWS CLI to successfully obtain tokens with this command:
aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id the_cognito_client_id --auth-parameters USERNAME=the_users_email,PASSWORD=the_users_password
Where the_cognito_client_id is an approximately 26 character long string shown as App client id under General Settings / App clients.
Note that the USER_PASSWORD_AUTH flow is not enabled by default, so you will initially get an error with this. Go to the Cognito Console for the specific User Pool and look for General Settings/App Clients, click "Show Details" for your specific app client, and check the "Enable username password based authentication (ALLOW_USER_PASSWORD_AUTH)" and save.
Once you get back tokens and you know your call is working, you can use the aws history show command to show you the details of the actual https call. The first time you call
aws history show
You will get a message
Could not locate history. Make sure cli_history is set to enabled in the ~/.aws/config file
Go to that file and add
cli_history=enabled
Then, run your initiate-auth call again with the cli. Then, when you run
aws history show
You will get back the details of how the call was made. (At this point, you might consider removing the cli_history setting so you don't log all of your calls, with all of the credentials, in the future.) You will see
to URL: https://cognito-idp.us-east-1.amazonaws.com/
which tells you the URL to use, and you will see that it is a POST. You will note that "InitiateAuth" is not anywhere in that URL. However, you will see the headers include:
"X-Amz-Target": "AWSCognitoIdentityProviderService.InitiateAuth"
and
"Content-Type": "application/x-amz-json-1.1"
You need both of those headers, including the non-standard Content-Type, to make the HTTPS call work. You can use Postman to put the call together, although Postman does not like the non-standard Content-Type, so you have to turn off the standard Content-Type and manually add these two headers to the call. At that point, Postman is able to obtain the tokens as well.
Postman also provides an export to CURL function (click the link that says "Code"), which gives you:
curl --location --request POST 'https://cognito-idp.us-east-1.amazonaws.com/' \
--header 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
--header 'Content-Type: application/x-amz-json-1.1' \
--data-raw '{
"AuthFlow": "USER_PASSWORD_AUTH",
"AuthParameters": {
"PASSWORD": "the_users_password",
"USERNAME": "the_users_email"
},
"ClientId": "the_cognito_client_id"
}'
Submitting that on the command line also gives you the tokens you need.
To refresh using the refresh token, just use InitiateAuth, but the AuthFlow is REFRESH_TOKEN_AUTH and the only member of AuthParameters is REFRESH_TOKEN (which is, of course, the RefreshToken)
Now, I just need to figure out how to do USER_SRP_AUTH using HTTPS.
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