Exemple #1
0
        /// <summary>
        ///     calculate the signature of the sastoken
        /// </summary>
        public static string CalcSignature(this ISasTokenParameters token, string sharedSecret, bool useNonce, HashType hashType, IEnumerable <string> additionalKeys)
        {
            // to be safe, the sharedsecret should contain at least 20 characters.
            // this also limits the number of erroneous switch of the key name and shared secret
            var keyPolicyCheck = ValidateSigningKeyPolicies(sharedSecret);

            if (!keyPolicyCheck.Success)
            {
                throw new ArgumentOutOfRangeException(nameof(sharedSecret), keyPolicyCheck.TokenResponseCode.ToString());
            }

            var stringToSign = WebUtility.UrlEncode(token.SharedResource) + "\n";

            if (additionalKeys != null)
            {
                foreach (var key in additionalKeys)
                {
                    var kvp = token.AdditionalValues.FirstOrDefault(q => q.Key == key);
                    if (kvp.Key == null)
                    {
                        throw new ArgumentException($"Value is missing : {key}");
                    }
                    stringToSign += $"{kvp.Key}={WebUtility.UrlEncode(kvp.Value)}\n";
                }
            }
            if (useNonce)
            {
                stringToSign += $"{WebUtility.UrlEncode(token.Nonce)}\n";
            }
            stringToSign += token.Expiry;
            return(CalculateHash(sharedSecret, hashType, stringToSign));
        }
Exemple #2
0
        /// <summary>
        ///     returns a string representation of this token for use in a URL
        /// </summary>
        public static string ToQueryString(this ISasTokenParameters token)
        {
            var components = new List <string>();

            if (!string.IsNullOrEmpty(token.SharedResource))
            {
                components.Add($"sr={WebUtility.UrlEncode(token.SharedResource)}");
            }
            if (!string.IsNullOrEmpty(token.Signature))
            {
                components.Add($"sig={WebUtility.UrlEncode(token.Signature)}");
            }
            if (token.Expiry > 0)
            {
                components.Add($"se={token.Expiry}");
            }
            if (!string.IsNullOrEmpty(token.Nonce))
            {
                components.Add($"nonce={WebUtility.UrlEncode(token.Nonce)}");
            }
            if (!string.IsNullOrEmpty(token.SigningKeyName))
            {
                components.Add($"skn={WebUtility.UrlEncode(token.SigningKeyName)}");
            }
            if (token.AdditionalValues != null)
            {
                foreach (var kvp in token.AdditionalValues)
                {
                    components.Add($"{kvp.Key}={WebUtility.UrlEncode(kvp.Value)}");
                }
            }
            return(string.Join("&", components));
        }
        public ISasTokenValidationResult Validate(ISasTokenParameters token, bool ignoreTimeOut)
        {
            if (!policies.ContainsKey(token.SigningKeyName))
            {
                return(new SasTokenValidationResult(false, token.SharedResource, TokenResponseCode.PolicyFailed));
            }
            var p = policies[token.SigningKeyName];

            return(ExecuteValidation(token, p.Key, p.UseNonce, p.HashType, p.AdditionalKeys, ignoreTimeOut));
        }
Exemple #4
0
 /// <summary>
 ///     calculate the signature of the sastoken
 /// </summary>
 public static string CalcSignature(this ISasTokenParameters token, string sharedSecret, bool useNonce, HashType hashType)
 {
     return(CalcSignature(token, sharedSecret, useNonce, hashType, null));
 }
        /// <summary>
        /// Validate a token using the provided secret and hashtype
        /// </summary>
        /// <param name="token">Token to be validated</param>
        /// <param name="sharedSecret">The passphrase used to create the token's signature</param>
        /// <param name="useNonce">If true, the nonce is checked against previous validations, preventing resends</param>
        /// <param name="hashType">The hashing type used to generate the signature</param>
        /// <param name="additionalKeys">If true, the signature expects additional keys from the token</param>
        /// <param name="ignoreTimeOut">if true, ignore the timestamp when validating.</param>
        /// <returns></returns>
        private ISasTokenValidationResult ExecuteValidation(
            ISasTokenParameters token,
            string sharedSecret,
            bool useNonce,
            HashType hashType,
            IEnumerable <string> additionalKeys,
            bool ignoreTimeOut)
        {
            if (string.IsNullOrEmpty(sharedSecret))
            {
                return new SasTokenValidationResult
                       {
                           Success           = false,
                           TokenResponseCode = TokenResponseCode.InvalidSigningKey
                       }
            }
            ;

            var epochCurrent = DateTime.UtcNow - new DateTime(1970, 1, 1);
            var expiryTest   = (int)epochCurrent.TotalSeconds;

            if (!ignoreTimeOut && token.Expiry < expiryTest)
            {
                return new SasTokenValidationResult
                       {
                           TokenResponseCode = TokenResponseCode.TokenExpired,
                           Success           = false
                       }
            }
            ;
            if (useNonce && _memoryCache != null)
            {
                if (string.IsNullOrEmpty(token.Nonce))
                {
                    return new SasTokenValidationResult
                           {
                               TokenResponseCode = TokenResponseCode.NonceIsRequired,
                               Success           = false
                           }
                }
                ;

                if (TryGetValueFromcache(token.Nonce))
                {
                    return new SasTokenValidationResult
                           {
                               TokenResponseCode = TokenResponseCode.ResendNotAllowed,
                               Success           = false
                           }
                }
                ;

                SetInCache(token.Nonce);
            }

            var validateSignature = token.CalcSignature(sharedSecret, useNonce, hashType, additionalKeys);

            if (token.Signature != validateSignature)
            {
                return new SasTokenValidationResult
                       {
                           TokenResponseCode = TokenResponseCode.TokenTampered,
                           Success           = false
                       }
            }
            ;
            return(new SasTokenValidationResult
            {
                TokenResponseCode = TokenResponseCode.TokenAccepted,
                Resource = token.SharedResource,
                Success = true
            });
        }
 public ISasTokenValidationResult Validate(ISasTokenParameters token)
 {
     return(Validate(token, false));
 }