首页 > 解决方案 > 尝试从“此处”REST API 获取令牌时客户端授权标头无效

问题描述

经过一番努力,我试图让 Bearer 令牌开始使用HERE REST API
使用 (OAuth 2.0 (JSON Web Tokens))
,我遇到了401202 错误

{"errorId":"ERROR-e0242f30-05da-4df0-9beb-b697062240ce","httpStatus":401,"errorCode":401202,"message":"无效的客户端授权标头,需要签名的请求格式。","错误":"invalid_request","error_description":"errorCode: '401202'。无效的客户端授权标头,需要签名的请求格式。"}

这是我的代码:

private void GetToken()
{
   try
    {
        var here_client_id = "b1Ibl7XXXXXXXoZtNKb";
        var here_access_key_id = "8DKjlwXXXXXXXXXerGCXPA";
        var here_access_key_secret = "tuU-bGMa1ljancfoXXXXXXXXXXXXXXXK8cMlk4o0EGUpS2fmwkAtlltFPDhYQUgytJLL-X_YNIjmdWcOabQ";
        var url = "https://account.api.here.com/oauth2/token";

        var Parameters = "grant_type=client_credentials&client_id=" + here_client_id + "&oauth_consumer_key=" + here_access_key_secret;

        var hmac = new HMACSHA256();
        var key = Convert.ToBase64String(hmac.Key);
        Guid id = Guid.NewGuid();

        // Create a request for the URL.        
        WebRequest request = WebRequest.Create(url);

        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        var cred = @"OAuth oauth_consumer_key=" + here_access_key_id;

        request.Headers.Add("Authorization", cred);
        //request.Headers.Add("oauth_consumer_key", here_access_key_id);
        request.Headers.Add("oauth_nonce", id.ToString());
        request.Headers.Add("oauth_signature_method", "HMAC-SHA256");
        request.Headers.Add("oauth_signature", key);
        request.Headers.Add("oauth_timestamp", ConvertToUnixTimestamp(DateTime.Now).ToString());
        request.Headers.Add("oauth_version", "1.0");

        byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
        request.ContentLength = byteArray.Length;

        Stream postStream = request.GetRequestStream();
        // Add the post data to the web request
        postStream.Write(byteArray, 0, byteArray.Length);
        postStream.Close();

        // Get the response.
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        // Display the status.
        Console.WriteLine(response.StatusDescription);
        // Get the stream containing content returned by the server.
        Stream dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
        // Display the content.
        MessageBox.Show(responseFromServer);
        // Cleanup the streams and the response.
        reader.Close();
        dataStream.Close();
        response.Close();
    }
    catch (WebException ex)
    {
        using (var stream = ex.Response.GetResponseStream())
        using (var reader = new StreamReader(stream))
        {
           //MessageBox.Show(reader.ReadToEnd());
            textBox1.Text = reader.ReadToEnd();
        }
    }
}

标签: c#restoauthhere-api

解决方案


这是我的第一次剪裁,很粗糙,但是。

var accessKey = "";
    var secret = "";
    var url = "https://account.api.here.com/oauth2/token";
    var nonce = GetNonce();
    var timestamp = GetTimeStamp();
    var baseString = @"grant_type=client_credentials&oauth_consumer_key=" + accessKey + "&oauth_nonce=" + nonce + "&oauth_signature_method=HMAC-SHA256&oauth_timestamp=" + timestamp + "&oauth_version=1.0";

    var workingString = new List<string>();
    foreach (var parameter in baseString.Split('&').ToList())
    {
        workingString.Add(Uri.EscapeDataString(parameter.Split('=')[0] + "=" + parameter.Split('=')[1].Trim()));
    }
    var urlEncodeParamaterString = String.Join(Uri.EscapeDataString("&"), workingString.ToArray());
    var fullBaseString = $"POST&{Uri.EscapeDataString(url)}&{urlEncodeParamaterString}";

    var signature = CreateToken(fullBaseString, (Uri.EscapeDataString(secret) + "&"));

    var authHeader = "OAuth oauth_consumer_key=\"" + accessKey + "\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"" + timestamp + "\",oauth_nonce=\"" + nonce + "\",oauth_version=\"1.0\",oauth_signature=\"" + Uri.EscapeDataString(signature) + "\"";



    using (HttpClient httpClient = new HttpClient())
    {
        httpClient.DefaultRequestHeaders.Add("Authorization", authHeader);
        var response = await httpClient.PostAsync(url, new StringContent($"grant_type={Uri.EscapeDataString("client_credentials")}",
                                                        Encoding.UTF8,
                                                        "application/x-www-form-urlencoded"));
        var responseContent = response.Content.ReadAsStringAsync();
    }

其他方法是

 private string GetNonce()
    {
        var rand = new Random();
        var nonce = rand.Next(1000000000);
        return nonce.ToString();
    }
    private string CreateToken(string message, string secret)
    {
        secret = secret ?? "";
        var encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(secret);
        byte[] messageBytes = encoding.GetBytes(message);
        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return Convert.ToBase64String(hashmessage);
        }
    }
    private string GetTimeStamp()
    {
        var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToInt64(ts.TotalSeconds).ToString();
    }

推荐阅读