/// <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)));
        }
        /// <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(initiateResponse.Session,
                                        initiateResponse.AuthenticationResult,
                                        initiateResponse.ChallengeName,
                                        initiateResponse.ChallengeParameters,
                                        new Dictionary <string, string>(initiateResponse.ResponseMetadata.Metadata)));
        }
Example #3
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);
        }
Example #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);

            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()
            {
                SessionID = verifierResponse.Session,
                ChallengeName = verifierResponse.ChallengeName,
                AuthenticationResult = verifierResponse.AuthenticationResult,
                ChallengeParameters = verifierResponse.ChallengeParameters,
                ClientMetadata = new Dictionary <string, string>(verifierResponse.ResponseMetadata.Metadata)
            });
        }
Example #5
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);

            if (verifierResponse.ChallengeName == ChallengeNameType.DEVICE_SRP_AUTH)
            {
                verifierResponse = await HandleDeviceSrpAuthResponseAsync(verifierResponse, tupleAa).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)
            });
        }
Example #6
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
    }
Example #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 virtual 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[CognitoConstants.ChlgParamDeviceKey] = Device.DeviceKey;
            }

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

            var isDeviceAuthRequest = verifierResponse.AuthenticationResult == null && (!string.IsNullOrEmpty(srpRequest.DeviceGroupKey) ||
                                                                                        !string.IsNullOrEmpty(srpRequest.DevicePass));

            #region Device-level authentication
            if (isDeviceAuthRequest)
            {
                if (string.IsNullOrEmpty(srpRequest.DeviceGroupKey) || string.IsNullOrEmpty(srpRequest.DevicePass))
                {
                    throw new ArgumentNullException("Device Group Key and Device Pass required for authentication.", "srpRequest");
                }

                #region Device SRP Auth
                var deviceAuthRequest  = CreateDeviceSrpAuthRequest(verifierResponse, tupleAa);
                var deviceAuthResponse = await Provider.RespondToAuthChallengeAsync(deviceAuthRequest).ConfigureAwait(false);

                #endregion

                #region Device Password Verifier
                var devicePasswordChallengeRequest = CreateDevicePasswordVerifierAuthRequest(deviceAuthResponse, srpRequest.DeviceGroupKey, srpRequest.DevicePass, tupleAa);
                verifierResponse = await Provider.RespondToAuthChallengeAsync(devicePasswordChallengeRequest).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)));
        }
 public void InitiateAuthAsync(InitiateAuthRequest request, AmazonServiceCallback <InitiateAuthRequest, InitiateAuthResponse> callback, AsyncOptions options = null)
 {
     throw new System.NotImplementedException();
 }
        private async Task <SignInResponse> SignIn(AuthFlowType type, SignInRequestBase request,
                                                   Dictionary <string, string> authParameters = null, CancellationToken cancellationToken = default)
        {
            Check.NotNull(request, nameof(request));

            var authRequest = new InitiateAuthRequest()
            {
                ClientId        = clientId,
                AuthFlow        = type,
                UserContextData = new UserContextDataType
                {
                    EncodedData =
                        $"IP:{request.IpAddress};ServerPath:{request.ServerPath};ServerName:{request.ServerName}"
                }
            };

            authRequest.AuthParameters.Add("USERNAME", request.UserName.ToLower());

            if (authParameters != null)
            {
                foreach (var(key, value) in authParameters)
                {
                    authRequest.AuthParameters.Add(key, value);
                }
            }

            try
            {
                var response = await base.CreateDefaultRetryAsyncPolicy().ExecuteAsync(async() =>
                                                                                       await CognitoidentityProvider.InitiateAuthAsync(authRequest, cancellationToken));

                if (response.AuthenticationResult != null)
                {
                    return new SignInResponse
                           {
                               IdToken      = response.AuthenticationResult.IdToken,
                               AccessToken  = response.AuthenticationResult.AccessToken,
                               ExpiresIn    = response.AuthenticationResult.ExpiresIn,
                               TokenType    = response.AuthenticationResult.TokenType,
                               RefreshToken = response.AuthenticationResult.RefreshToken,
                               SignInType   = "USER_PASSWORD_AUTH"
                           }
                }
                ;

                return(new SignInResponse
                {
                    Session = response.Session,
                    ChallengeName = response.ChallengeName.Value,
                    ChallengeParameters = response.ChallengeParameters
                });
            }
            catch (NotAuthorizedException)
            {
                throw new BusinessException(ErrorCode.NotAuthorized);
            }
            catch (Exception ex)
            {
                throw CatchException(ex);
            }
        }