aws / aws-aspnet-cognito-identity-provider

ASP.NET Core Identity Provider for Amazon Cognito
https://aws.amazon.com/developer/language/net/
Apache License 2.0
213 stars 89 forks source link

Implementing MFA suppression via remembered devices, getting 'Invalid device key given.' exception #206

Closed yenhanshih closed 2 years ago

yenhanshih commented 2 years ago

The Question

I am currently trying to implement MFA suppression via remembered devices in Cognito. I am trying to implement this workflow as documented here (https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pool-remembered-devices/) but seem to have ran into an exception when calling ConfirmDeviceAsync().

Amazon.CognitoIdentityProvider.Model.InvalidParameterException: 'Invalid device key given.'

var respondToAuthChallengeRequest = new RespondToAuthChallengeRequest
{
    ChallengeName = ChallengeNameType.SMS_MFA,
    ChallengeResponses = new Dictionary<string, string>
    {
        {
            "SMS_MFA_CODE", mfaCodeSubmission.Code
        },
        {
        "USERNAME", mfaCodeSubmission.Username
        }
    },
    ClientId = _amazonCognitoConfiguration.Value.ClientId,
    Session = mfaCodeSubmission.SessionId
};
var respondToAuthChallengeResponse = await _amazonCognitoIdentityProvider.RespondToAuthChallengeAsync(respondToAuthChallengeRequest, cancellationToken);

user.Device = new CognitoDevice(new DeviceType { DeviceKey = respondToAuthChallengeResponse.AuthenticationResult.NewDeviceMetadata.DeviceKey }, user);
var deviceSecretVerifierConfigType = user.GenerateDeviceVerifier(respondToAuthChallengeResponse.AuthenticationResult.NewDeviceMetadata.DeviceGroupKey, mfaCodeSubmission.Code, user.Username);
var confirm = new ConfirmDeviceRequest
{
    AccessToken = respondToAuthChallengeResponse.AuthenticationResult.AccessToken,
    DeviceKey = respondToAuthChallengeResponse.AuthenticationResult.NewDeviceMetadata.DeviceKey,
    DeviceSecretVerifierConfig = new DeviceSecretVerifierConfigType
    {
        PasswordVerifier = deviceSecretVerifierConfigType.PasswordVerifier,
        Salt = deviceSecretVerifierConfigType.Salt
    }
};
var response = await _amazonCognitoIdentityProvider.ConfirmDeviceAsync(confirm, cancellationToken);

It is also important to mention that ConfirmDeviceAsync() seems to work if we are doing SRP Auth WITHOUT SMS_MFA challenge. It doesn't seem like I am missing anything, any help is appreciated.

Environment

We also use aws-sdk-net-extensions-cognito 2.2.2 to call GenerateDeviceVerifier to create the PasswordVerifier and Salt.


This is a :question: general question

ashishdhingra commented 2 years ago

Hi @yenhanshih,

Good afternoon.

Thanks for posting guidance question. Although I'm not sure, this might be related to https://github.com/aws/aws-sdk-net-extensions-cognito/issues/10.

Thanks, Ashish

yenhanshih commented 2 years ago

@ashishdhingra it does look relevant, however according to the use case you provided a link to, it is for StartWithSrpAuthAsync() then calling ConfirmDeviceAsync(), which as mentioned, seems to work for me. However, the issue occurs for me when we are calling RespondToAuthChallengeAsync() then calling ConfirmDeviceAsync().

Thanks

ashishdhingra commented 2 years ago

@ashishdhingra it does look relevant, however according to the use case you provided a link to, it is for StartWithSrpAuthAsync() then calling ConfirmDeviceAsync(), which as mentioned, seems to work for me. However, the issue occurs for me when we are calling RespondToAuthChallengeAsync() then calling ConfirmDeviceAsync().

Thanks

@yenhanshih Not sure if this would help, there is a similar question posted on StackOverflow for Boto3 https://stackoverflow.com/questions/59062064/aws-cognito-boto3-error-on-confirm-device-invalid-device-key-given. Please give it a try. We can change this issue to bug for investigation, if required.

yenhanshih commented 2 years ago

@ashishdhingra looks like that was it. Instead of passing in the email address, it actually needed the Cognito Id, which was a GUID associated to the User. I am able to call ConfirmDeviceAsync() from the SMS_MFA challange now.

ashishdhingra commented 2 years ago

@ashishdhingra looks like that was it. Instead of passing in the email address, it actually needed the Cognito Id, which was a GUID associated to the User. I am able to call ConfirmDeviceAsync() from the SMS_MFA challange now.

@yenhanshih Glad that it worked out for you. Closing this issue for now.

github-actions[bot] commented 2 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.