AnomalyInnovations / aws-api-gateway-cli-test

A simple CLI to test API Gateway endpoints with IAM authorization
MIT License
120 stars 29 forks source link

Added MFA authenitcation support with prompt for confirmation code #13

Open talyaniv opened 5 years ago

talyaniv commented 5 years ago

Also see updated package.json with latest aws-sdk version

jayair commented 5 years ago

Thanks for the PR!

Can you give me some instructions on how to test it?

talyaniv commented 5 years ago

Sure! you need to create a user pool and require MFA, see attached screenshot. SNS should be enabled as well. Once the pool is set-up, every successful user/password login attempt will emit an SMS confirmation code to the user. The CLI will halt and prompt for the code. If a correct code is entered it will complete the process. I would test all positive and negative options, e.g.:

image

jayair commented 5 years ago

Awesome! I'll give it a try this weekend.

jayair commented 5 years ago

@talyaniv I'm trying to test this. Can you tell me how to create a user that needs MFA?

Currently we use this to create a user:

aws cognito-idp sign-up \
  --region YOUR_COGNITO_REGION \
  --client-id YOUR_COGNITO_APP_CLIENT_ID \
  --username admin@example.com \
  --password Passw0rd!
talyaniv commented 5 years ago

@jayair This is the complete sign-in flow for MFA enforced user:

Sign up:

aws cognito-idp sign-up \ 
   --region YOUR_COGNITO_REGION \ 
   --client-id YOUR_COGNITO_APP_CLIENT_ID \ 
   --username user@example.com \ 
   --password PAssWOrd! \ 
   --user-attributes "[{\"Name\": \"phone_number\", \"Value\": \"+2123454567\"}]"

The expected response:

{
    "UserConfirmed": false,
    "UserSub": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "CodeDeliveryDetails": {
        "AttributeName": "phone_number",
        "Destination": "+********3456",
        "DeliveryMedium": "SMS"
    }
}

After the confirmation code 123456 received at my device I call:

aws cognito-idp confirm-sign-up \
   --region YOUR_COGNITO_REGION \
   --client-id YOUR_COGNITO_APP_CLIENT_ID \
   --username user@example.com \
   --confirmation-code 123456

No response payload should be expected on this one.

Now, when the user is confirmed, this is how the sign-in flow looks like

aws cognito-idp initiate-auth \
  --auth-flow USER_PASSWORD_AUTH \
  --client-id YOUR_COGNITO_APP_CLIENT_ID \
  --auth-parameters USERNAME="user@example.com",PASSWORD="PAssWOrd!"

The expected response:

{
    "ChallengeName": "SMS_MFA",
    "ChallengeParameters": {
        "CODE_DELIVERY_DELIVERY_MEDIUM": "SMS",
        "CODE_DELIVERY_DESTINATION": "+********4567",
        "USER_ID_FOR_SRP": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    },
    "Session": "LONG_SESSION_STRING"
}

You should be receiving the auth code at your device and complete the auth sign-in flow by confirming it:

aws cognito-idp respond-to-auth-challenge \
   --client-id YOUR_COGNITO_APP_CLIENT_ID \
   --challenge-name SMS_MFA \
   --challenge-responses USERNAME=user@example.com,SMS_MFA_CODE=345678 \
   --session "LONG_SESSION_STRING"

And now the final response looks like a standard sign-in response:

{
    "AuthenticationResult": {
        "ExpiresIn": 3600,
        "IdToken": "LONG_ID_TOKEN",
        "RefreshToken": "LONG_REFRESH_TOKEN",
        "TokenType": "Bearer",
        "AccessToken": "LONG_ACCESS_TOKEN",
        "ChallengeParameters": {}
}
talyaniv commented 5 years ago

Also see my previous reply with screenshot. Make sure you mark the MFA related checkboxes and options.

ozbillwang commented 5 years ago

one suggestion.

Could we have a new option, such as --mfa=xxxxxx as well?

jayair commented 5 years ago

@ozbillwang What would this option do?

ozbillwang commented 5 years ago

@jayair

Since this is a command line, I can run it with shell scripting with new generated MFA token every time.