/// <summary> /// Initiates the asynchronous SRP authentication flow /// </summary> /// <param name="srpRequest">InitiateSrpAuthRequest object containing the necessary parameters to /// create an InitiateAuthAsync API call for SRP authentication</param> /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge, /// if one exists</returns> public async Task <AuthFlowResponse> StartWithSrpAuthAsync(InitiateSrpAuthRequest srpRequest) { if (srpRequest == null || string.IsNullOrEmpty(srpRequest.Password)) { throw new ArgumentNullException("Password required for authentication.", "srpRequest"); } Tuple <BigInteger, BigInteger> tupleAa = AuthenticationHelper.CreateAaTuple(); InitiateAuthRequest initiateRequest = CreateSrpAuthRequest(tupleAa); InitiateAuthResponse initiateResponse = await Provider.InitiateAuthAsync(initiateRequest).ConfigureAwait(false); UpdateUsernameAndSecretHash(initiateResponse.ChallengeParameters); RespondToAuthChallengeRequest challengeRequest = CreateSrpPasswordVerifierAuthRequest(initiateResponse, srpRequest.Password, tupleAa); RespondToAuthChallengeResponse verifierResponse = await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false); UpdateSessionIfAuthenticationComplete(verifierResponse.ChallengeName, verifierResponse.AuthenticationResult); return(new AuthFlowResponse() { SessionID = verifierResponse.Session, ChallengeName = verifierResponse.ChallengeName, AuthenticationResult = verifierResponse.AuthenticationResult, ChallengeParameters = verifierResponse.ChallengeParameters, ClientMetadata = new Dictionary <string, string>(verifierResponse.ResponseMetadata.Metadata) }); }
/// <summary> /// Initiates the asynchronous SRP authentication flow /// </summary> /// <param name="srpRequest">InitiateSrpAuthRequest object containing the necessary parameters to /// create an InitiateAuthAsync API call for SRP authentication</param> /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge, /// if one exists</returns> public void StartWithSrpAuthAsync(InitiateSrpAuthRequest srpRequest, AsyncCallback <AuthFlowResponse> callback = null) { if (srpRequest == null || string.IsNullOrEmpty(srpRequest.Password)) { throw new ArgumentNullException("Password required for authentication.", "srpRequest"); } Tuple <BigInteger, BigInteger> tupleAa = AuthenticationHelper.CreateAaTuple(); InitiateAuthRequest initiateRequest = CreateSrpAuthRequest(tupleAa); Provider.InitiateAuthAsync(initiateRequest, initResult => { if (initResult.Exception != null) { callback?.Invoke(new AsyncResult <AuthFlowResponse>(null, initResult.Exception)); return; } UpdateUsernameAndSecretHash(initResult.Response.ChallengeParameters); RespondToAuthChallengeRequest challengeRequest = CreateSrpPasswordVerifierAuthRequest(initResult.Response, srpRequest.Password, tupleAa); bool challengeResponsesValid = challengeRequest != null && challengeRequest.ChallengeResponses != null; bool deviceKeyValid = Device != null && !string.IsNullOrEmpty(Device.DeviceKey); if (challengeResponsesValid && deviceKeyValid) { challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamDeviceKey, Device.DeviceKey); } Provider.RespondToAuthChallengeAsync(challengeRequest, respondResult => { if (respondResult.Exception != null) { callback?.Invoke(new AsyncResult <AuthFlowResponse>(null, respondResult.Exception)); return; } RespondToAuthChallengeResponse verifierResponse = respondResult.Response; UpdateSessionIfAuthenticationComplete(verifierResponse.ChallengeName, verifierResponse.AuthenticationResult); callback?.Invoke(new AsyncResult <AuthFlowResponse>(new AuthFlowResponse() { SessionID = verifierResponse.Session, ChallengeName = verifierResponse.ChallengeName, AuthenticationResult = verifierResponse.AuthenticationResult, ChallengeParameters = verifierResponse.ChallengeParameters, ClientMetadata = new Dictionary <string, string>(verifierResponse.ResponseMetadata.Metadata) }, null)); }); }); }
/// <summary> /// Respond to auth challange with name DEVICE_SRP_AUTH. /// </summary> /// <param name="currentResponse">Current auth response from AWS</param> /// <param name="AaTuple">Use for generate to current auth challange. If null - create new one.</param> /// <returns></returns> private async Task <RespondToAuthChallengeResponse> HandleDeviceSrpAuthResponseAsync( RespondToAuthChallengeResponse currentResponse, Tuple <BigInteger, BigInteger> AaTuple = null) { if (currentResponse == null) { throw new ArgumentNullException(nameof(currentResponse)); } if (AaTuple == null) { AaTuple = AuthenticationHelper.CreateAaTuple(); } var challengeRequest = new RespondToAuthChallengeRequest { ClientId = ClientID, Session = currentResponse.Session, ChallengeName = ChallengeNameType.DEVICE_SRP_AUTH, ChallengeResponses = new Dictionary <string, string> { { CognitoConstants.ChlgParamUsername, Username }, { CognitoConstants.ChlgParamSrpA, AaTuple.Item1.ToString("X") }, { CognitoConstants.ChlgParamDeviceKey, Device.DeviceKey }, { CognitoConstants.ChlgParamSecretHash, SecretHash } } }; currentResponse = await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false); if (currentResponse.ChallengeName == ChallengeNameType.DEVICE_PASSWORD_VERIFIER) { challengeRequest = CreateDeviceSrpAuthRequest(currentResponse, AaTuple); } else { throw new Exception($"Unsupported challenge {currentResponse.ChallengeName}"); } return(await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false)); }
/// <summary> /// Initiates the asynchronous SRP authentication flow /// </summary> /// <param name="srpRequest">InitiateSrpAuthRequest object containing the necessary parameters to /// create an InitiateAuthAsync API call for SRP authentication</param> /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge, /// if one exists</returns> public async Task <AuthFlowResponse> StartWithSrpAuthAsync(InitiateSrpAuthRequest srpRequest) { if (srpRequest == null || string.IsNullOrEmpty(srpRequest.Password)) { throw new ArgumentNullException("Password required for authentication.", "srpRequest"); } Tuple <BigInteger, BigInteger> tupleAa = AuthenticationHelper.CreateAaTuple(); InitiateAuthRequest initiateRequest = CreateSrpAuthRequest(tupleAa); InitiateAuthResponse initiateResponse = await Provider.InitiateAuthAsync(initiateRequest).ConfigureAwait(false); UpdateUsernameAndSecretHash(initiateResponse.ChallengeParameters); RespondToAuthChallengeRequest challengeRequest = CreateSrpPasswordVerifierAuthRequest(initiateResponse, srpRequest.Password, tupleAa); bool challengeResponsesValid = challengeRequest != null && challengeRequest.ChallengeResponses != null; bool deviceKeyValid = Device != null && !string.IsNullOrEmpty(Device.DeviceKey); if (challengeResponsesValid && deviceKeyValid) { challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamDeviceKey, Device.DeviceKey); } RespondToAuthChallengeResponse verifierResponse = await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false); UpdateSessionIfAuthenticationComplete(verifierResponse.ChallengeName, verifierResponse.AuthenticationResult); return(new AuthFlowResponse(verifierResponse.Session, verifierResponse.AuthenticationResult, verifierResponse.ChallengeName, verifierResponse.ChallengeParameters, new Dictionary <string, string>(verifierResponse.ResponseMetadata.Metadata))); }