Beispiel #1
0
        /// <summary>
        /// Computes the hash of the StringToSign using the secret key.
        /// </summary>
        /// <param name="stringToSign">The StringToSign that will be hashed with the secret key.</param>
        /// <param name="authMethod">The authorization/hash method to be used.</param>
        /// <returns>The hash of the string to sign.</returns>
        public string ComputeHash(
            string stringToSign,
            AuthenticationMethod authMethod)
        {
            CheckArgument.NotNullOrEmpty(stringToSign, "stringToSign");

            byte[] secretKeyBytes    = Convert.FromBase64String(this.credential.SecretKey);
            byte[] stringToSignBytes = Encoding.UTF8.GetBytes(stringToSign);

            HMAC hasher = null;

            switch (authMethod)
            {
            case AuthenticationMethod.HmacSha1:
                hasher = new HMACSHA1(secretKeyBytes);
                break;

            case AuthenticationMethod.HmacSha256:
                hasher = new HMACSHA256(secretKeyBytes);
                break;

            default:
                throw new NotSupportedException("Only HMAC SHA1 and SHA256 authentication is currently supported");
            }

            return(Convert.ToBase64String(hasher.ComputeHash(stringToSignBytes)));
        }
Beispiel #2
0
        /// <summary>
        /// Constructs the "StringToSign" as defined in the TeleSign REST API. This is the string that is hashed
        /// and that hash is used to authenticate the user. Then the authorization string is created
        /// by from the customer id and the StringToSign hashed with the secret key.
        /// </summary>
        /// <param name="resourceName">The name of the resource - ie. the relative part of the URL.</param>
        /// <param name="method">The http method - POST, DELETE, GET, PUT.</param>
        /// <param name="timestamp">The timestamp to use.</param>
        /// <param name="nonce">The nonce (used for preventing replay attacks).</param>
        /// <param name="contentType">The mime type content type.</param>
        /// <param name="encodedBody">The body of a POST request.</param>
        /// <param name="authMethod">The authentication method to use.</param>
        /// <returns>The string that will be signed for authentication.</returns>
        public string ConstructStringToSign(
            string resourceName,
            string method,
            DateTime timestamp,
            string nonce,
            string contentType,
            string encodedBody,
            AuthenticationMethod authMethod)
        {
            CheckArgument.NotNullOrEmpty(resourceName, "resourceName");
            CheckArgument.NotNullOrEmpty(method, "method");
            CheckArgument.NotNull(nonce, "nonce");
            CheckArgument.NotNull(contentType, "contentType");
            CheckArgument.NotNull(encodedBody, "encodedBody");

            string authMethodString = this.MapAuthenticationMethodToHeaderString(authMethod);

            return(string.Format(
                       CultureInfo.InvariantCulture,
                       "{0}\n{1}\n\nx-ts-auth-method:{2}\nx-ts-date:{3}\nx-ts-nonce:{4}\n{5}{6}",
                       method,
                       contentType,
                       authMethodString,
                       timestamp.ToString("r"),
                       nonce,
                       encodedBody.Length == 0 ? string.Empty : encodedBody + "\n",
                       resourceName));
        }
        /// <summary>
        /// Cleans up phone number strings by removing any non-digit characters from
        /// them. Will throw an exception if the resulting cleaned up string has
        /// no characters.
        /// </summary>
        /// <param name="phoneNumber">The input phone number.</param>
        /// <returns>The input phone number with all non-digit characters removed.</returns>
        public string CleanupPhoneNumber(string phoneNumber)
        {
            CheckArgument.NotNullOrEmpty(phoneNumber, "phoneNumber");

            StringBuilder builder = new StringBuilder(
                phoneNumber.Length,
                phoneNumber.Length);

            // Remove non-digit characters from the phone number.
            foreach (char c in phoneNumber)
            {
                if (Char.IsDigit(c))
                {
                    builder.Append(c);
                }
            }

            // Reject empty strings.
            if (builder.Length == 0)
            {
                string message = string.Format(
                    CultureInfo.InvariantCulture,
                    "Phone Number '{0}' contains no digits",
                    phoneNumber);

                throw new ArgumentException(
                          message,
                          "phoneNumber");
            }

            return(builder.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the TeleSignCredential class.
        /// </summary>
        /// <param name="customerId">The customer id.</param>
        /// <param name="secretKey">The customers secret key.</param>
        public TeleSignCredential(
            Guid customerId,
            string secretKey)
        {
            CheckArgument.NotNullOrEmpty(secretKey, "secretKey");

            this.CustomerId = customerId;
            this.SecretKey  = secretKey;
        }
Beispiel #5
0
        /// <summary>
        /// Constructs the authorization by combining the customer id
        /// from the credential with the stringToSign hashed with
        /// the secret key.
        /// </summary>
        /// <param name="stringToSign">
        /// The stringToSign that is used for authentication.
        /// </param>
        /// <param name="authMethod">The method used for authentication.</param>
        /// <returns>The authorization string.</returns>
        public string ConstructAuthorizationString(
            string stringToSign,
            AuthenticationMethod authMethod)
        {
            CheckArgument.NotNullOrEmpty(stringToSign, "stringToSign");

            return(string.Format(
                       CultureInfo.InvariantCulture,
                       "TSA {0}:{1}",
                       this.credential.CustomerId,
                       this.ComputeHash(stringToSign, authMethod)));
        }
Beispiel #6
0
        /// <summary>
        /// Validates that the array is not null and of at least a certain length.
        /// If the array is null an ArgumentNullException is throw per the NotNull
        /// method - if the array is shorter than the required length an
        /// ArgumentException is thrown. Otherwise does nothing.
        /// </summary>
        /// <param name="value">The array to check.</param>
        /// <param name="minimumLength">The minimum length the array should be.</param>
        /// <param name="parameterName">The name of the parameter. Used to populate the exception.</param>
        public static void ArrayLengthAtLeast(
            Array value,
            int minimumLength,
            string parameterName)
        {
            CheckArgument.NotNull(value, parameterName);

            if (value.Length < minimumLength)
            {
                string message = string.Format(
                    CultureInfo.InvariantCulture,
                    "Array '{0}' has length '{1}' but must be at least '{2}'",
                    parameterName,
                    value.Length,
                    minimumLength);

                throw new ArgumentException(
                          message,
                          FormatParameterName(parameterName));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Constructs the "StringToSign" as defined in the TeleSign REST API. This is the string that is hashed
        /// and that hash is used to authenticate the user. Then the authorization string is created
        /// by from the customer id and the StringToSign hashed with the secret key.
        /// </summary>
        /// <param name="resourceName">The name of the resource - ie. the relative part of the URL.</param>
        /// <param name="method">The http method - POST, DELETE, GET, PUT.</param>
        /// <param name="contentType">The mime type content type.</param>
        /// <param name="encodedBody">The body of a POST request.</param>
        /// <returns>The string that will be signed for authentication.</returns>
        public string ConstructStringToSign(
            string resourceName,
            string method,
            string contentType,
            string encodedBody)
        {
            CheckArgument.NotNullOrEmpty(resourceName, "resourceName");
            CheckArgument.NotNullOrEmpty(method, "method");
            CheckArgument.NotNull(contentType, "contentType");
            CheckArgument.NotNull(encodedBody, "encodedBody");

            DateTime timestamp = DateTime.UtcNow;
            string   nonce     = Guid.NewGuid().ToString();

            return(this.ConstructStringToSign(
                       resourceName,
                       method,
                       timestamp,
                       nonce,
                       contentType,
                       encodedBody,
                       AuthenticationMethod.HmacSha1));
        }
Beispiel #8
0
        /// <summary>
        /// Initializes a new instance of the TeleSignAuthentication class with
        /// a credential.
        /// </summary>
        /// <param name="credential">
        /// The TeleSign credentials for authenticating with the TeleSign services.
        /// </param>
        public TeleSignAuthentication(TeleSignCredential credential)
        {
            CheckArgument.NotNull(credential, "credential");

            this.credential = credential;
        }
        /// <summary>
        /// Constructs a .NET WebRequest object for the request (using for Mobile).
        /// </summary>
        /// <param name="resourceName">The name of the resource - ie. the relative part of the URL.</param>
        /// <param name="method">The http method - POST, DELETE, GET, PUT.</param>
        /// <param name="fields">The fields that are the arguments to the request.</param>
        /// <param name="authMethod">The method of authentication to use.</param>
        /// <returns>A WebRequest object.</returns>
        protected WebRequest ConstructWebMobileRequest(
            string resourceName,
            string method,
            Dictionary <string, string> fields = null,
            AuthenticationMethod authMethod    = AuthenticationMethod.HmacSha1)
        {
            CheckArgument.NotNullOrEmpty(resourceName, "resourceName");
            CheckArgument.NotNullOrEmpty(method, "method");

            DateTime timeStamp = DateTime.UtcNow;
            string   nonce     = Guid.NewGuid().ToString();

            // When the Uri is constructed. If it is a GET request the fields
            // are put into the Uri's query string eg ?foo=bar. When the
            // method is POST the fields are not used in constructing the Uri,
            // but below they are placed in the encoded body.
            Uri fullUri = this.ConstructResourceMobileUri(
                resourceName,
                method,
                fields);

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(fullUri);

            request.Method = method;

            string contentType = string.Empty;
            string encodedBody = string.Empty;

            if (method == "POST")
            {
                contentType = "application/x-www-form-urlencoded";
                encodedBody = TeleSignService.ConstructQueryString(fields);
            }

            string authorizationString = this.authentication.ConstructAuthorizationString(
                resourceName,
                method,
                timeStamp,
                nonce,
                contentType,
                encodedBody,
                authMethod);

            request.Headers.Add("Authorization", authorizationString);
            request.Headers.Add("x-ts-auth-method", this.authentication.MapAuthenticationMethodToHeaderString(authMethod));
            request.Headers.Add("x-ts-date", timeStamp.ToString("r"));
            request.Headers.Add("x-ts-nonce", nonce);

            if (method == "POST")
            {
                byte[] body = Encoding.UTF8.GetBytes(encodedBody);

                request.Accept        = "application/json";
                request.ContentType   = contentType;
                request.ContentLength = body.Length;
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(body, 0, body.Length);
                }
            }

            return(request);
        }
Beispiel #10
0
 /// <summary>
 /// Checks if the provided object is null. If it is an ArgumentNullException
 /// is throw otherwise it does nothing. This is just a way to simplify/shorten
 /// parameter checkin.
 /// </summary>
 /// <param name="value">The value to check for null.</param>
 /// <param name="parameterName">
 /// The name of the parameter. This is used to populate the exception.
 /// </param>
 public static void NotNullOrEmpty(string value, string parameterName)
 {
     CheckArgument.NotNull(value, parameterName);
     CheckArgument.NotEmpty(value, parameterName);
 }