示例#1
0
        /// <summary>
        /// Initiates the asynchronous refresh token authentication flow
        /// </summary>
        /// <param name="refreshTokenRequest">InitiateRefreshTokenAuthRequest object containing the necessary
        /// parameters to initiate the refresh token authentication flow</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public void StartWithRefreshTokenAuthAsync(InitiateRefreshTokenAuthRequest refreshTokenRequest, AsyncCallback <AuthFlowResponse> callback = null)
        {
            InitiateAuthRequest initiateAuthRequest = CreateRefreshTokenAuthRequest(refreshTokenRequest.AuthFlowType);

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

                InitiateAuthResponse initiateResponse = r.Response;
                UpdateSessionIfAuthenticationComplete(initiateResponse.ChallengeName, initiateResponse.AuthenticationResult);

                callback?.Invoke(new AsyncResult <AuthFlowResponse>(new AuthFlowResponse()
                {
                    SessionID            = initiateResponse.Session,
                    ChallengeName        = initiateResponse.ChallengeName,
                    AuthenticationResult = initiateResponse.AuthenticationResult,
                    ChallengeParameters  = initiateResponse.ChallengeParameters,
                    ClientMetadata       = new Dictionary <string, string>(initiateResponse.ResponseMetadata.Metadata)
                }, null));
            });
        }
示例#2
0
        /// <summary>
        /// Initiates the asynchronous custom authentication flow
        /// </summary>
        /// <param name="customRequest">InitiateCustomAuthRequest object containing the necessary parameters to
        /// create an InitiateAuthAsync API call for custom authentication</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public void StartWithCustomAuthAsync(InitiateCustomAuthRequest customRequest, AsyncCallback <AuthFlowResponse> callback = null)
        {
            InitiateAuthRequest authRequest = new InitiateAuthRequest()
            {
                AuthFlow       = AuthFlowType.CUSTOM_AUTH,
                AuthParameters = new Dictionary <string, string>(customRequest.AuthParameters),
                ClientId       = ClientID,
                ClientMetadata = new Dictionary <string, string>(customRequest.ClientMetadata)
            };

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

                InitiateAuthResponse initiateResponse = r.Response;
                UpdateUsernameAndSecretHash(initiateResponse.ChallengeParameters);

                UpdateSessionIfAuthenticationComplete(initiateResponse.ChallengeName, initiateResponse.AuthenticationResult);

                callback?.Invoke(new AsyncResult <AuthFlowResponse>(new AuthFlowResponse()
                {
                    SessionID            = initiateResponse.Session,
                    ChallengeName        = initiateResponse.ChallengeName,
                    AuthenticationResult = initiateResponse.AuthenticationResult,
                    ChallengeParameters  = initiateResponse.ChallengeParameters,
                    ClientMetadata       = new Dictionary <string, string>(initiateResponse.ResponseMetadata.Metadata)
                }, null));
            });
        }
示例#3
0
        /// <summary>
        /// Initiates the asynchronous custom authentication flow
        /// </summary>
        /// <param name="customRequest">InitiateCustomAuthRequest object containing the necessary parameters to
        /// create an InitiateAuthAsync API call for custom 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> StartWithCustomAuthAsync(InitiateCustomAuthRequest customRequest)
        {
            InitiateAuthRequest authRequest = new InitiateAuthRequest()
            {
                AuthFlow       = AuthFlowType.CUSTOM_AUTH,
                AuthParameters = new Dictionary <string, string>(customRequest.AuthParameters),
                ClientId       = ClientID,
                ClientMetadata = new Dictionary <string, string>(customRequest.ClientMetadata)
            };

            InitiateAuthResponse initiateResponse = await Provider.InitiateAuthAsync(authRequest).ConfigureAwait(false);

            UpdateUsernameAndSecretHash(initiateResponse.ChallengeParameters);

            UpdateSessionIfAuthenticationComplete(initiateResponse.ChallengeName, initiateResponse.AuthenticationResult);

            return(new AuthFlowResponse()
            {
                SessionID = initiateResponse.Session,
                ChallengeName = initiateResponse.ChallengeName,
                AuthenticationResult = initiateResponse.AuthenticationResult,
                ChallengeParameters = initiateResponse.ChallengeParameters,
                ClientMetadata = new Dictionary <string, string>(initiateResponse.ResponseMetadata.Metadata)
            });
        }
示例#4
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>
        /// 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);
        }
        /// <summary>
        /// Initiates the asynchronous refresh token authentication flow
        /// </summary>
        /// <param name="refreshTokenRequest">InitiateRefreshTokenAuthRequest object containing the necessary
        /// parameters to initiate the refresh token authentication flow</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public async Task <AuthFlowResponse> StartWithRefreshTokenAuthAsync(InitiateRefreshTokenAuthRequest refreshTokenRequest)
        {
            InitiateAuthRequest initiateAuthRequest = CreateRefreshTokenAuthRequest(refreshTokenRequest.AuthFlowType);

            InitiateAuthResponse initiateResponse =
                await Provider.InitiateAuthAsync(initiateAuthRequest).ConfigureAwait(false);

            UpdateSessionIfAuthenticationComplete(initiateResponse.ChallengeName, initiateResponse.AuthenticationResult);

            return(new AuthFlowResponse(initiateResponse.Session,
                                        initiateResponse.AuthenticationResult,
                                        initiateResponse.ChallengeName,
                                        initiateResponse.ChallengeParameters,
                                        new Dictionary <string, string>(initiateResponse.ResponseMetadata.Metadata)));
        }
示例#7
0
        public AuthenticationResult LoginUser(LoginUserQueryParam loginUserQueryParam)
        {
            InitiateAuthRequest iaRequest = new InitiateAuthRequest
            {
                ClientId = _connectionInfo.ClientId,
                AuthFlow = AuthFlowType.USER_PASSWORD_AUTH
            };

            iaRequest.AuthParameters.Add("USERNAME", loginUserQueryParam.Email);
            iaRequest.AuthParameters.Add("PASSWORD", loginUserQueryParam.Password);
            InitiateAuthResponse authResp = new InitiateAuthResponse();
            var authResult = new AuthenticationResult();

            try
            {
                authResp = _provider.InitiateAuthAsync(iaRequest).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 (AggregateException e)
            {
                e.Handle((x) =>
                {
                    if (x is UserNotConfirmedException)  // This we know how to handle.
                    {
                        LoggingHandler.LogInfo("User not confirmed.");
                        authResult.Success         = false;
                        authResult.ResponseMessage = "User not confirmed";
                        return(true);
                    }
                    if (x is NotAuthorizedException)  // This we know how to handle.
                    {
                        LoggingHandler.LogInfo("Invalid credentials provided.");
                        authResult.Success         = false;
                        authResult.ResponseMessage = "Invalid credentials provided.";
                        return(true);
                    }
                    return(false); // Let anything else stop the application.
                });
            }
            return(authResult);
        }
示例#8
0
        /// <summary>
        /// Initiates the asynchronous refresh token authentication flow
        /// </summary>
        /// <param name="refreshTokenRequest">InitiateRefreshTokenAuthRequest object containing the necessary
        /// parameters to initiate the refresh token authentication flow</param>
        /// <returns>Returns the AuthFlowResponse object that can be used to respond to the next challenge,
        /// if one exists</returns>
        public virtual async Task <AuthFlowResponse> StartWithRefreshTokenAuthAsync(InitiateRefreshTokenAuthRequest refreshTokenRequest)
        {
            InitiateAuthRequest initiateAuthRequest = CreateRefreshTokenAuthRequest(refreshTokenRequest.AuthFlowType);

            InitiateAuthResponse initiateResponse =
                await Provider.InitiateAuthAsync(initiateAuthRequest).ConfigureAwait(false);

            // Service does not return the refresh token. Hence, set it to the old refresh token that was used.
            if (string.IsNullOrEmpty(initiateResponse.ChallengeName) && string.IsNullOrEmpty(initiateResponse.AuthenticationResult.RefreshToken))
            {
                initiateResponse.AuthenticationResult.RefreshToken = initiateAuthRequest.AuthParameters[CognitoConstants.ChlgParamRefreshToken];
            }

            UpdateSessionIfAuthenticationComplete(initiateResponse.ChallengeName, initiateResponse.AuthenticationResult);

            return(new AuthFlowResponse(initiateResponse.Session,
                                        initiateResponse.AuthenticationResult,
                                        initiateResponse.ChallengeName,
                                        initiateResponse.ChallengeParameters,
                                        new Dictionary <string, string>(initiateResponse.ResponseMetadata.Metadata)));
        }
示例#9
0
        public async Task <LoginResponse> LoginAsync(string username, string password)
        {
            LoginResponse       loginResponse;
            InitiateAuthRequest auth = new InitiateAuthRequest()
            {
                ClientId = CLIENT_ID,
                AuthFlow = AuthFlowType.USER_PASSWORD_AUTH,
            };

            auth.AuthParameters.Add("USERNAME", username);
            auth.AuthParameters.Add("PASSWORD", password);
            InitiateAuthResponse response = await _loginClient.InitiateAuthAsync(auth);

            if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
            {
                JwtSecurityTokenHandler handler   = new JwtSecurityTokenHandler();
                JwtSecurityToken        jsonToken = handler.ReadToken(response.AuthenticationResult.IdToken) as JwtSecurityToken;
                loginResponse = new LoginResponse()
                {
                    Email         = jsonToken.Claims.Single(c => c.Type == "email").Value,
                    EmailVerified = bool.Parse(jsonToken.Claims.Single(c => c.Type == "email_verified").Value),
                    FamilyName    = jsonToken.Claims.Single(c => c.Type == "family_name").Value,
                    GivenName     = jsonToken.Claims.Single(c => c.Type == "given_name").Value,
                    HomeStudioId  = jsonToken.Claims.Single(c => c.Type == "custom:home_studio_id").Value,
                    IsMigration   = bool.Parse(jsonToken.Claims.Single(c => c.Type == "custom:isMigration").Value),
                    Locale        = jsonToken.Claims.Single(c => c.Type == "locale").Value,
                    MemberId      = jsonToken.Claims.Single(c => c.Type == "cognito:username").Value,
                    JwtToken      = response.AuthenticationResult.IdToken,
                    Expiration    = jsonToken.ValidTo,
                    IssuedOn      = jsonToken.ValidFrom,
                };
            }
            else
            {
                loginResponse = null;
            }

            return(loginResponse);
        }
示例#10
0
        /// <summary>
        /// Unmarshaller the response from the service to the response class.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context)
        {
            InitiateAuthResponse response = new InitiateAuthResponse();

            context.Read();
            int targetDepth = context.CurrentDepth;

            while (context.ReadAtDepth(targetDepth))
            {
                if (context.TestExpression("AuthenticationResult", targetDepth))
                {
                    var unmarshaller = AuthenticationResultTypeUnmarshaller.Instance;
                    response.AuthenticationResult = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("ChallengeName", targetDepth))
                {
                    var unmarshaller = StringUnmarshaller.Instance;
                    response.ChallengeName = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("ChallengeParameters", targetDepth))
                {
                    var unmarshaller = new DictionaryUnmarshaller <string, string, StringUnmarshaller, StringUnmarshaller>(StringUnmarshaller.Instance, StringUnmarshaller.Instance);
                    response.ChallengeParameters = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("Session", targetDepth))
                {
                    var unmarshaller = StringUnmarshaller.Instance;
                    response.Session = unmarshaller.Unmarshall(context);
                    continue;
                }
            }

            return(response);
        }
        /// <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)));
        }