Esempio n. 1
0
        /// <summary>
        /// Uses the properties of the RespondToCustomChallengeRequest object to respond to the current
        /// custom authentication challenge using an asynchronous call
        /// </summary>
        /// <param name="customRequest">RespondToCustomChallengeRequest object containing the necessary parameters to
        /// respond to the current custom authentication challenge</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public void RespondToCustomAuthAsync(RespondToCustomChallengeRequest customRequest, AsyncCallback <AuthFlowResponse> callback = null)
        {
            RespondToAuthChallengeRequest request = new RespondToAuthChallengeRequest()
            {
                ChallengeName      = ChallengeNameType.CUSTOM_CHALLENGE,
                ClientId           = ClientID,
                ChallengeResponses = new Dictionary <string, string>(customRequest.ChallengeParameters),
                Session            = customRequest.SessionID
            };

            Provider.RespondToAuthChallengeAsync(request, r =>
            {
                if (r.Exception != null)
                {
                    callback?.Invoke(new AsyncResult <AuthFlowResponse>(null, r.Exception));
                    return;
                }

                RespondToAuthChallengeResponse authResponse = r.Response;
                UpdateSessionIfAuthenticationComplete(authResponse.ChallengeName, authResponse.AuthenticationResult);

                callback?.Invoke(new AsyncResult <AuthFlowResponse>(new AuthFlowResponse()
                {
                    SessionID            = authResponse.Session,
                    ChallengeName        = authResponse.ChallengeName,
                    AuthenticationResult = authResponse.AuthenticationResult,
                    ChallengeParameters  = authResponse.ChallengeParameters,
                    ClientMetadata       = new Dictionary <string, string>(authResponse.ResponseMetadata.Metadata)
                }, null));
            });
        }
        /// <summary>
        /// Uses the properties of the RespondToSmsMfaRequest object to respond to the current MFA
        /// authentication challenge using an asynchronous call
        /// </summary>
        /// <param name="smsMfaRequest">RespondToSmsMfaRequest object containing the necessary parameters to
        /// respond to the current SMS MFA authentication challenge</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public async Task <AuthFlowResponse> RespondToSmsMfaAuthAsync(RespondToSmsMfaRequest smsMfaRequest)
        {
            RespondToAuthChallengeRequest challengeRequest = new RespondToAuthChallengeRequest
            {
                ChallengeResponses = new Dictionary <string, string>
                {
                    { CognitoConstants.ChlgParamSmsMfaCode, smsMfaRequest.MfaCode },
                    { CognitoConstants.ChlgParamUsername, Username }
                },
                Session       = smsMfaRequest.SessionID,
                ClientId      = ClientID,
                ChallengeName = ChallengeNameType.SMS_MFA
            };

            if (!string.IsNullOrEmpty(SecretHash))
            {
                challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamSecretHash, SecretHash);
            }

            RespondToAuthChallengeResponse challengeResponse =
                await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false);

            UpdateSessionIfAuthenticationComplete(challengeResponse.ChallengeName, challengeResponse.AuthenticationResult);

            return(new AuthFlowResponse(challengeResponse.Session,
                                        challengeResponse.AuthenticationResult,
                                        challengeResponse.ChallengeName,
                                        challengeResponse.ChallengeParameters,
                                        new Dictionary <string, string>(challengeResponse.ResponseMetadata.Metadata)));
        }
Esempio n. 3
0
        /// <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>
        /// Uses the properties of the RespondToNewPasswordRequiredRequest object to respond to the current new
        /// password required authentication challenge using an asynchronous call
        /// </summary>
        /// <param name="newPasswordRequest">RespondToNewPasswordRequiredRequest object containing the necessary
        /// parameters to respond to the current SMS MFA authentication challenge</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public async Task <AuthFlowResponse> RespondToNewPasswordRequiredAsync(RespondToNewPasswordRequiredRequest newPasswordRequest)
        {
            RespondToAuthChallengeRequest challengeRequest = new RespondToAuthChallengeRequest
            {
                ChallengeResponses = new Dictionary <string, string>
                {
                    { CognitoConstants.ChlgParamNewPassword, newPasswordRequest.NewPassword },
                    { CognitoConstants.ChlgParamUsername, Username }
                },
                Session       = newPasswordRequest.SessionID,
                ClientId      = ClientID,
                ChallengeName = ChallengeNameType.NEW_PASSWORD_REQUIRED
            };

            if (!string.IsNullOrEmpty(SecretHash))
            {
                challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamSecretHash, SecretHash);
            }

            RespondToAuthChallengeResponse challengeResponse =
                await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false);

            UpdateSessionIfAuthenticationComplete(challengeResponse.ChallengeName, challengeResponse.AuthenticationResult);

            return(new AuthFlowResponse(challengeResponse.Session,
                                        challengeResponse.AuthenticationResult,
                                        challengeResponse.ChallengeName,
                                        challengeResponse.ChallengeParameters,
                                        new Dictionary <string, string>(challengeResponse.ResponseMetadata.Metadata)));
        }
Esempio n. 5
0
        public AuthenticationResult ChallengePassword(ResetPasswordQueryParams resetPasswordQueryParams)
        {
            RespondToAuthChallengeRequest authChallengeRequest = new RespondToAuthChallengeRequest
            {
                ChallengeName      = ChallengeNameType.NEW_PASSWORD_REQUIRED,
                ChallengeResponses = new Dictionary <string, string>
                {
                    { "NEW_PASSWORD", resetPasswordQueryParams.Password },
                    { "USERNAME", resetPasswordQueryParams.Email }
                },
                ClientId = _connectionInfo.ClientId,
                Session  = resetPasswordQueryParams.Session
            };
            var authResult = new AuthenticationResult();

            try
            {
                var authResp = _provider.RespondToAuthChallengeAsync(authChallengeRequest).Result;
                authResult.AccessToken  = authResp.AuthenticationResult.AccessToken;
                authResult.IdToken      = authResp.AuthenticationResult.IdToken;
                authResult.RefreshToken = authResp.AuthenticationResult.RefreshToken;
                authResult.TokenType    = authResp.AuthenticationResult.TokenType;
                authResult.ExpiresIn    = authResp.AuthenticationResult.ExpiresIn;
                authResult.Success      = true;
            }
            catch (Exception e)
            {
                LoggingHandler.LogError(e.Message);
                LoggingHandler.LogError(e.StackTrace);
                throw;
            }
            return(authResult);
        }
Esempio n. 6
0
        private async Task <RespondToAuthChallengeResponse> VerifyChallenge(string username, string session, string accountId)
        {
            var provider = new AmazonCognitoIdentityProviderClient(RegionEndpoint.USEast2);

            try
            {
                var challengeRequest = new RespondToAuthChallengeRequest
                {
                    Session            = session,
                    ChallengeName      = "CUSTOM_CHALLENGE",
                    ClientId           = CLIENTAPP_ID,
                    ChallengeResponses = new Dictionary <string, string>()
                    {
                        { "ANSWER", accountId },
                        { "USERNAME", username }
                    }
                };

                return(await provider.RespondToAuthChallengeAsync(challengeRequest));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            return(null);
        }
Esempio n. 7
0
        /// <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>
        /// Internal method which responds to the PASSWORD_VERIFIER challenge in SRP authentication
        /// </summary>
        /// <param name="challenge">Response from the InitiateAuth challenge</param>
        /// <param name="password">Password for the CognitoUser, needed for authentication</param>
        /// <param name="tupleAa">Tuple of BigIntegers containing the A,a pair for the SRP protocol flow</param>
        /// <returns>Returns the RespondToAuthChallengeRequest for an SRP authentication flow</returns>
        private RespondToAuthChallengeRequest CreateSrpPasswordVerifierAuthRequest(InitiateAuthResponse challenge,
                                                                                   string password,
                                                                                   Tuple <BigInteger, BigInteger> tupleAa)
        {
            string     username    = challenge.ChallengeParameters[CognitoConstants.ChlgParamUsername];
            string     poolName    = PoolName;
            string     secretBlock = challenge.ChallengeParameters[CognitoConstants.ChlgParamSecretBlock];
            string     salt        = challenge.ChallengeParameters[CognitoConstants.ChlgParamSalt];
            BigInteger srpb        = BigIntegerExtensions.FromUnsignedLittleEndianHex(challenge.ChallengeParameters[CognitoConstants.ChlgParamSrpB]);

            if ((srpb.TrueMod(AuthenticationHelper.N)).Equals(BigInteger.Zero))
            {
                throw new ArgumentException("SRP error, B mod N cannot be zero.", "challenge");
            }

            DateTime timestamp = DateTime.UtcNow;
            string   timeStr   = timestamp.ToString("ddd MMM d HH:mm:ss \"UTC\" yyyy", CultureInfo.InvariantCulture);

            byte[] claim = AuthenticationHelper.AuthenticateUser(username, password, poolName, tupleAa, salt,
                                                                 challenge.ChallengeParameters[CognitoConstants.ChlgParamSrpB], secretBlock, timeStr);
            string claimBase64 = Convert.ToBase64String(claim);

            Dictionary <string, string> srpAuthResponses = new Dictionary <string, string>(StringComparer.Ordinal)
            {
                { CognitoConstants.ChlgParamPassSecretBlock, secretBlock },
                { CognitoConstants.ChlgParamPassSignature, claimBase64 },
                { CognitoConstants.ChlgParamUsername, username },
                { CognitoConstants.ChlgParamTimestamp, timeStr },
            };

            if (!string.IsNullOrEmpty(ClientSecret))
            {
                SecretHash = CognitoAuthHelper.GetUserPoolSecretHash(Username, ClientID, ClientSecret);
                srpAuthResponses.Add(CognitoConstants.ChlgParamSecretHash, SecretHash);
            }

            if (Device != null && !string.IsNullOrEmpty(Device.DeviceKey))
            {
                srpAuthResponses.Add(CognitoConstants.ChlgParamDeviceKey, Device.DeviceKey);
            }

            RespondToAuthChallengeRequest authChallengeRequest = new RespondToAuthChallengeRequest()
            {
                ChallengeName      = challenge.ChallengeName,
                ClientId           = ClientID,
                Session            = challenge.Session,
                ChallengeResponses = srpAuthResponses
            };

            return(authChallengeRequest);
        }
Esempio n. 9
0
        public async Task <AuthFlowResponse> RespondToSoftwareMfaAuthAsync(RespondToSoftwareMfaRequest softwareMfaRequest)
        {
            RespondToAuthChallengeRequest challengeRequest = new RespondToAuthChallengeRequest
            {
                ChallengeResponses = new Dictionary <string, string>
                {
                    { CognitoConstants.ChlgParamSoftwareMfaCode, softwareMfaRequest.MfaCode },
                    { CognitoConstants.ChlgParamUsername, Username },
                },
                Session       = softwareMfaRequest.SessionID,
                ClientId      = ClientID,
                ChallengeName = "SOFTWARE_TOKEN_MFA"
            };

            if (Device != null && !string.IsNullOrEmpty(Device.DeviceKey))
            {
                challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamDeviceKey, Device.DeviceKey);
            }

            if (!string.IsNullOrEmpty(SecretHash))
            {
                challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamSecretHash, SecretHash);
            }

            RespondToAuthChallengeResponse challengeResponse =
                await Provider.RespondToAuthChallengeAsync(challengeRequest).ConfigureAwait(false);

            if (challengeResponse.ChallengeName == ChallengeNameType.DEVICE_SRP_AUTH)
            {
                challengeResponse = await HandleDeviceSrpAuthResponseAsync(challengeResponse).ConfigureAwait(false);
            }
            UpdateSessionIfAuthenticationComplete(challengeResponse.ChallengeName, challengeResponse.AuthenticationResult);

            return(new AuthFlowResponse
            {
                SessionID = challengeResponse.Session,
                ChallengeName = challengeResponse.ChallengeName,
                AuthenticationResult = challengeResponse.AuthenticationResult,
                ChallengeParameters = challengeResponse.ChallengeParameters,
                ClientMetadata = new Dictionary <string, string>(challengeResponse.ResponseMetadata.Metadata)
            });
        }
        /// <summary>
        /// Uses the properties of the RespondToCustomChallengeRequest object to respond to the current
        /// custom authentication challenge using an asynchronous call
        /// </summary>
        /// <param name="customRequest">RespondToCustomChallengeRequest object containing the necessary parameters to
        /// respond to the current custom authentication challenge</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public async Task <AuthFlowResponse> RespondToCustomAuthAsync(RespondToCustomChallengeRequest customRequest)
        {
            RespondToAuthChallengeRequest request = new RespondToAuthChallengeRequest()
            {
                ChallengeName      = ChallengeNameType.CUSTOM_CHALLENGE,
                ClientId           = ClientID,
                ChallengeResponses = new Dictionary <string, string>(customRequest.ChallengeParameters),
                Session            = customRequest.SessionID
            };

            RespondToAuthChallengeResponse authResponse =
                await Provider.RespondToAuthChallengeAsync(request).ConfigureAwait(false);

            UpdateSessionIfAuthenticationComplete(authResponse.ChallengeName, authResponse.AuthenticationResult);

            return(new AuthFlowResponse(authResponse.Session,
                                        authResponse.AuthenticationResult,
                                        authResponse.ChallengeName,
                                        authResponse.ChallengeParameters,
                                        new Dictionary <string, string>(authResponse.ResponseMetadata.Metadata)));
        }
Esempio n. 11
0
        private async Task <AuthFlowResponse> RespondToTwoFactorSoftwareTokenChallengeAsync(TUser user, string code, string authWorkflowSessionId, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                /* Amazon Cognito Authentication Extension Library doesn't currently support responding to challenges for Software Token as the MFA (only SMS or Custom)
                 * // So we need to hook in to some methods via reflection
                 * // https://github.com/aws/aws-sdk-net-extensions-cognito  */

                var challengeRequest = new RespondToAuthChallengeRequest
                {
                    ChallengeResponses = new Dictionary <string, string>
                    {
                        { "SOFTWARE_TOKEN_MFA_CODE", code },
                        { "USERNAME", user.Username }
                    },
                    Session       = authWorkflowSessionId,
                    ClientId      = user.ClientID,
                    ChallengeName = ChallengeNameType.SOFTWARE_TOKEN_MFA
                };

                var secretHash = user.GetSecretHash();

                if (!string.IsNullOrEmpty(secretHash))
                {
                    challengeRequest.ChallengeResponses.Add("SECRET_HASH", secretHash);
                }

                var challengeResponse = await _cognitoClient.RespondToAuthChallengeAsync(challengeRequest, cancellationToken).ConfigureAwait(false);

                user.UpdateSessionIfAuthenticationComplete(challengeResponse.ChallengeName, challengeResponse.AuthenticationResult);

                return(new AuthFlowResponse(challengeResponse.Session, challengeResponse.AuthenticationResult, challengeResponse.ChallengeName, challengeResponse.ChallengeParameters, new Dictionary <string, string>(challengeResponse.ResponseMetadata.Metadata)));
            }
            catch (AmazonCognitoIdentityProviderException e)
            {
                throw new CognitoServiceException("Failed to respond to Cognito two factor software token challenge.", e);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Uses the properties of the RespondToNewPasswordRequiredRequest object to respond to the current new
        /// password required authentication challenge using an asynchronous call
        /// </summary>
        /// <param name="newPasswordRequest">RespondToNewPasswordRequiredRequest object containing the necessary
        /// parameters to respond to the current SMS MFA authentication challenge</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public void RespondToNewPasswordRequiredAsync(RespondToNewPasswordRequiredRequest newPasswordRequest, AsyncCallback <AuthFlowResponse> callback = null)
        {
            RespondToAuthChallengeRequest challengeRequest = new RespondToAuthChallengeRequest
            {
                ChallengeResponses = new Dictionary <string, string>
                {
                    { CognitoConstants.ChlgParamNewPassword, newPasswordRequest.NewPassword },
                    { CognitoConstants.ChlgParamUsername, Username }
                },
                Session       = newPasswordRequest.SessionID,
                ClientId      = ClientID,
                ChallengeName = ChallengeNameType.NEW_PASSWORD_REQUIRED
            };

            if (!string.IsNullOrEmpty(SecretHash))
            {
                challengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamSecretHash, SecretHash);
            }

            Provider.RespondToAuthChallengeAsync(challengeRequest, r =>
            {
                if (r.Exception != null)
                {
                    callback?.Invoke(new AsyncResult <AuthFlowResponse>(null, r.Exception));
                    return;
                }

                RespondToAuthChallengeResponse challengeResponse = r.Response;
                UpdateSessionIfAuthenticationComplete(challengeResponse.ChallengeName, challengeResponse.AuthenticationResult);

                callback?.Invoke(new AsyncResult <AuthFlowResponse>(new AuthFlowResponse()
                {
                    SessionID            = challengeResponse.Session,
                    ChallengeName        = challengeResponse.ChallengeName,
                    AuthenticationResult = challengeResponse.AuthenticationResult,
                    ChallengeParameters  = challengeResponse.ChallengeParameters,
                    ClientMetadata       = new Dictionary <string, string>(challengeResponse.ResponseMetadata.Metadata)
                }, null));
            });
        }
Esempio n. 13
0
        /// <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));
        }
Esempio n. 14
0
        /// <summary>
        /// Internal method which responds to the DEVICE_SRP_AUTH challenge in SRP authentication
        /// </summary>
        /// <param name="challenge">The response from the PASSWORD_VERIFIER challenge</param>
        /// <param name="tupleAa">Tuple of BigIntegers containing the A,a pair for the SRP protocol flow</param>
        /// <returns></returns>
        private RespondToAuthChallengeRequest CreateDeviceSrpAuthRequest(RespondToAuthChallengeResponse challenge, Tuple <BigInteger, BigInteger> tupleAa)
        {
            RespondToAuthChallengeRequest authChallengeRequest = new RespondToAuthChallengeRequest()
            {
                ChallengeName      = "DEVICE_SRP_AUTH",
                ClientId           = ClientID,
                Session            = challenge.Session,
                ChallengeResponses = new Dictionary <string, string>
                {
                    { CognitoConstants.ChlgParamUsername, Username },
                    { CognitoConstants.ChlgParamDeviceKey, Device.DeviceKey },
                    { CognitoConstants.ChlgParamSrpA, tupleAa.Item1.ToString("X") },
                }
            };

            if (!string.IsNullOrEmpty(ClientSecret))
            {
                SecretHash = CognitoAuthHelper.GetUserPoolSecretHash(Username, ClientID, ClientSecret);
                authChallengeRequest.ChallengeResponses.Add(CognitoConstants.ChlgParamSecretHash, SecretHash);
            }
            return(authChallengeRequest);
        }
        /// <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)));
        }
 public void RespondToAuthChallengeAsync(RespondToAuthChallengeRequest request, AmazonServiceCallback <RespondToAuthChallengeRequest, RespondToAuthChallengeResponse> callback, AsyncOptions options = null)
 {
     throw new System.NotImplementedException();
 }
Esempio n. 17
0
    /// <summary>
    /// Try to sign in with email and password
    /// </summary>
    public void TrySignInRequest(string username, string password,
                                 Action OnFailureF = null, Action <string> OnSuccessF = null)
    {
        //Get the SRP variables A and a
        var TupleAa = AuthenticationHelper.CreateAaTuple();

        InitiateAuthRequest authRequest = new InitiateAuthRequest()
        {
            ClientId       = AppClientID,
            AuthFlow       = AuthFlowType.USER_SRP_AUTH,
            AuthParameters = new Dictionary <string, string>()
            {
                { "USERNAME", username },
                { "SRP_A", TupleAa.Item1.ToString(16) }
            }
        };

        //
        // This is a nested request / response / request. First we send the
        // InitiateAuthRequest, with some crypto things. AWS sends back
        // some of its own crypto things, in the authResponse object (this is the "challenge").
        // We combine that with the actual password, using math, and send it back (the "challenge response").
        // If AWS is happy with our answer, then it is convinced we know the password,
        // and it sends us some tokens!
        CognitoIDPClient.InitiateAuthAsync(authRequest, (authResponse) => {
            if (authResponse.Exception != null)
            {
                Debug.Log("[TrySignInRequest] exception : " + authResponse.Exception.ToString());
                if (OnFailureF != null)
                {
                    OnFailureF();
                }
                return;
            }

            //The timestamp format returned to AWS _needs_ to be in US Culture
            DateTime timestamp    = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now);
            CultureInfo usCulture = new CultureInfo("en-US");
            String timeStr        = timestamp.ToString("ddd MMM d HH:mm:ss \"UTC\" yyyy", usCulture);

            //Do the hard work to generate the claim we return to AWS
            var challegeParams = authResponse.Response.ChallengeParameters;
            byte[] claim       = AuthenticationHelper.authenticateUser(
                challegeParams["USERNAME"],
                password, UserPoolName, TupleAa,
                challegeParams["SALT"], challegeParams["SRP_B"],
                challegeParams["SECRET_BLOCK"], timeStr);

            String claimBase64 = System.Convert.ToBase64String(claim);

            // construct the second request
            RespondToAuthChallengeRequest respondRequest = new RespondToAuthChallengeRequest()
            {
                ChallengeName      = authResponse.Response.ChallengeName,
                ClientId           = AppClientID,
                ChallengeResponses = new Dictionary <string, string>()
                {
                    { "PASSWORD_CLAIM_SECRET_BLOCK", challegeParams["SECRET_BLOCK"] },
                    { "PASSWORD_CLAIM_SIGNATURE", claimBase64 },
                    { "USERNAME", username },
                    { "TIMESTAMP", timeStr }
                }
            };

            // send the second request
            CognitoIDPClient.RespondToAuthChallengeAsync(respondRequest, (finalResponse) => {
                if (finalResponse.Exception != null)
                {
                    // Note: if you have the wrong username/password, you will get an exception.
                    // It's up to you to differentiate that from other errors / etc.
                    Debug.Log("[TrySignInRequest] exception : " + finalResponse.Exception.ToString());
                    if (OnFailureF != null)
                    {
                        OnFailureF();
                    }
                    return;
                }

                // Ok, if we got here, we logged in, and here are some tokens
                AuthenticationResultType authResult = finalResponse.Response.AuthenticationResult;
                string idToken      = authResult.IdToken;
                string accessToken  = authResult.AccessToken;
                string refreshToken = authResult.RefreshToken;

                Debug.Log("[TrySignInRequest] success!");
                if (OnSuccessF != null)
                {
                    OnSuccessF(idToken);
                }
            });
        });   // end of CognitoIDPClient.InitiateAuthAsync
    }