in src/Amazon.Extensions.CognitoAuthentication/CognitoUserAuthentication.cs [56:134]
public virtual async Task<AuthFlowResponse> StartWithSrpAuthAsync(InitiateSrpAuthRequest srpRequest, CancellationToken cancellationToken)
{
if (srpRequest == null || string.IsNullOrEmpty(srpRequest.Password))
{
throw new ArgumentNullException(nameof(srpRequest), "Password required for authentication.");
}
Tuple<BigInteger, BigInteger> tupleAa = AuthenticationHelper.CreateAaTuple();
InitiateAuthRequest initiateRequest = CreateSrpAuthRequest(tupleAa);
if (srpRequest.ClientMetadata != null)
{
initiateRequest.ClientMetadata = new Dictionary<string, string>(srpRequest.ClientMetadata);
}
initiateRequest.UserContextData = srpRequest.UserContextData;
initiateRequest.AnalyticsMetadata = srpRequest.AnalyticsMetadata;
if (srpRequest.IsCustomAuthFlow)
{
initiateRequest.AuthFlow = AuthFlowType.CUSTOM_AUTH;
initiateRequest.AuthParameters?.Add(CognitoConstants.ChlgParamChallengeName, CognitoConstants.ChlgParamSrpA);
}
InitiateAuthResponse initiateResponse = await Provider.InitiateAuthAsync(initiateRequest, cancellationToken).ConfigureAwait(false);
UpdateUsernameAndSecretHash(initiateResponse.ChallengeParameters);
RespondToAuthChallengeRequest challengeRequest =
CreateSrpPasswordVerifierAuthRequest(initiateResponse, srpRequest.Password, tupleAa);
if (srpRequest.ClientMetadata != null)
{
challengeRequest.ClientMetadata = new Dictionary<string, string>(srpRequest.ClientMetadata);
}
challengeRequest.UserContextData = srpRequest.UserContextData;
challengeRequest.AnalyticsMetadata = srpRequest.AnalyticsMetadata;
bool challengeResponsesValid = challengeRequest != null && challengeRequest.ChallengeResponses != null;
bool deviceKeyValid = Device != null && !string.IsNullOrEmpty(Device.DeviceKey);
if (challengeResponsesValid && deviceKeyValid)
{
challengeRequest.ChallengeResponses[CognitoConstants.ChlgParamDeviceKey] = Device.DeviceKey;
}
RespondToAuthChallengeResponse verifierResponse =
await Provider.RespondToAuthChallengeAsync(challengeRequest, cancellationToken).ConfigureAwait(false);
#region Device-level authentication
if (verifierResponse.ChallengeName == ChallengeNameType.DEVICE_SRP_AUTH)
{
if (string.IsNullOrEmpty(srpRequest.DeviceGroupKey) || string.IsNullOrEmpty(srpRequest.DevicePass))
{
throw new ArgumentNullException(nameof(srpRequest), $"{nameof(srpRequest.DeviceGroupKey)} and {nameof(srpRequest.DevicePass)} required for authentication with challenge {ChallengeNameType.DEVICE_SRP_AUTH}");
}
#region Device SRP Auth
var deviceAuthRequest = CreateDeviceSrpAuthRequest(verifierResponse, tupleAa);
var deviceAuthResponse = await Provider.RespondToAuthChallengeAsync(deviceAuthRequest, cancellationToken).ConfigureAwait(false);
#endregion
#region Device Password Verifier
var devicePasswordChallengeRequest = CreateDevicePasswordVerifierAuthRequest(deviceAuthResponse, srpRequest.DeviceGroupKey, srpRequest.DevicePass, tupleAa);
verifierResponse = await Provider.RespondToAuthChallengeAsync(devicePasswordChallengeRequest, cancellationToken).ConfigureAwait(false);
#endregion
}
#endregion
UpdateSessionIfAuthenticationComplete(verifierResponse.ChallengeName, verifierResponse.AuthenticationResult);
return new AuthFlowResponse(verifierResponse.Session,
verifierResponse.AuthenticationResult,
verifierResponse.ChallengeName,
verifierResponse.ChallengeParameters,
new Dictionary<string, string>(verifierResponse.ResponseMetadata.Metadata));
}