Что входит в Dropbox OAuth Signature? - PullRequest
       35

Что входит в Dropbox OAuth Signature?

2 голосов
/ 20 декабря 2011

Я занимаюсь разработкой приложения для API DropBox и не могу на протяжении всей жизни найти информацию о том, что подразумевается под "подписью" первого запроса токена во время аутентификации.

Кто-нибудь еще знает

1 Ответ

3 голосов
/ 20 декабря 2011

Если это OAuth, то подпись является комбинацией

  • OAuthVersion
  • OAuthNonce
  • Отметка
  • ConsumerKey
  • Метод подписи (например, HMACSHA1)
  • Любые параметры, которые вы хотите отправить
  • HTTP метод

Например, вот код, который это делает

    /// <summary>
    /// Generate the signature base that is used to produce the signature
    /// </summary>
    /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
    /// <param name="consumerKey">The consumer key</param>        
    /// <param name="token">The token, if available. If not available pass null or an empty string</param>
    /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
    /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
    /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuthBase.SignatureTypes">OAuthBase.SignatureTypes</see>.</param>
    /// <returns>The signature base</returns>
    public static string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, string signatureType, SortedList<String, String> customParameters, out string normalizedUrl, out string normalizedRequestParameters)
    {
        if (token == null)
        {
            token = string.Empty;
        }

        if (tokenSecret == null)
        {
            tokenSecret = string.Empty;
        }

        if (string.IsNullOrEmpty(consumerKey))
        {
            throw new ArgumentNullException("consumerKey");
        }

        if (string.IsNullOrEmpty(httpMethod))
        {
            throw new ArgumentNullException("httpMethod");
        }

        if (string.IsNullOrEmpty(signatureType))
        {
            throw new ArgumentNullException("signatureType");
        }

        normalizedUrl = null;
        normalizedRequestParameters = null;

        List<QueryParameter> parameters = GetQueryParameters(url.Query);
        parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion));
        parameters.Add(new QueryParameter(OAuthNonceKey, nonce));
        parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp));
        parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType));
        parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey));

        foreach (String key in customParameters.Keys)
        {
            parameters.Add(new QueryParameter(key, UrlEncode(customParameters[key])));
        }


        if (!string.IsNullOrEmpty(token))
        {
            parameters.Add(new QueryParameter(OAuthTokenKey, token));
        }

        parameters.Sort(new QueryParameterComparer());

        normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
        if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443)))
        {
            normalizedUrl += ":" + url.Port;
        }
        normalizedUrl += url.AbsolutePath;
        normalizedRequestParameters = NormalizeRequestParameters(parameters);

        StringBuilder signatureBase = new StringBuilder();
        signatureBase.AppendFormat("{0}&", httpMethod.ToUpper());
        signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl));
        signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters));

        return signatureBase.ToString();
    }

    /// <summary>
    /// Generate the signature value based on the given signature base and hash algorithm
    /// </summary>
    /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param>
    /// <param name="hash">The hash algorithm used to perform the hashing. If the hashing algorithm requires initialization or a key it should be set prior to calling this method</param>
    /// <returns>A base64 string of the hash value</returns>
    public static string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash)
    {
        return ComputeHash(hash, signatureBase);
    }

        /// <summary>
    /// Helper function to compute a hash value
    /// </summary>
    /// <param name="hashAlgorithm">The hashing algoirhtm used. If that algorithm needs some initialization, like HMAC and its derivatives, they should be initialized prior to passing it to this function</param>
    /// <param name="data">The data to hash</param>
    /// <returns>a Base64 string of the hash value</returns>
    private static string ComputeHash(HashAlgorithm hashAlgorithm, string data)
    {
        if (hashAlgorithm == null)
        {
            throw new ArgumentNullException("hashAlgorithm");
        }

        if (string.IsNullOrEmpty(data))
        {
            throw new ArgumentNullException("data");
        }

        byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(data);
        byte[] hashBytes = hashAlgorithm.ComputeHash(dataBuffer);

        return Convert.ToBase64String(hashBytes);
    }

/// <summary>
    /// Generates a signature using the specified signatureType 
    /// </summary>      
    /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
    /// <param name="consumerKey">The consumer key</param>
    /// <param name="consumerSecret">The consumer seceret</param>
    /// <param name="token">The token, if available. If not available pass null or an empty string</param>
    /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
    /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
    /// <param name="signatureType">The type of signature to use</param>
    /// <returns>A base64 string of the hash value</returns>
    public static string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, SignatureTypes signatureType, SortedList<String, String> parameters, out string normalizedUrl, out string normalizedRequestParameters)
    {
        normalizedUrl = null;
        normalizedRequestParameters = null;

        switch (signatureType)
        {
            case SignatureTypes.PLAINTEXT:
                return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret));
            case SignatureTypes.HMACSHA1:


                string signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, parameters, out normalizedUrl, out normalizedRequestParameters);

                HMACSHA1 hmacsha1 = new HMACSHA1();
                hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));

                return GenerateSignatureUsingHash(signatureBase, hmacsha1);
            case SignatureTypes.RSASHA1:
                throw new NotImplementedException();
            default:
                throw new ArgumentException("Unknown signature type", "signatureType");
        }
    }

Но проверьте http://oauth.net/core/1.0a/ для деталей.

...