【问题标题】:Invalid Client Authorization header when trying to get token from "Here" REST API尝试从“此处”REST API 获取令牌时客户端授权标头无效
【发布时间】:2020-07-12 06:53:56
【问题描述】:

我正在尝试获取 Bearer 令牌以开始使用 HERE REST API
使用(OAuth 2.0(JSON Web 令牌))
经过一番挣扎,我被401202 error卡住了:

{"errorId":"ERROR-e0242f30-05da-4df0-9beb-b697062240ce","httpStatus":401,"errorCode":401202,"message":"无效 客户端授权标头,期望签名请求 格式。","error":"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# rest oauth here-api


【解决方案1】:

最后我在没有 web JSON WEB TOKENS 的情况下做到了。
根据API documentation 的说法,该调用仅使用 API KEY 进行。

public static string ConvertAddressToCoordinate(string address)
{
    try
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        var apikey = "xxxxxxxxxxxxxxxxxxxxx_xxxxxxxxx";
        var url = "https://geocoder.ls.hereapi.com/6.2/geocode.json?apiKey=";
        var fullurl = url + apikey + "&searchtext=" + address;
        // Create a request for the URL.        
        WebRequest request = WebRequest.Create(fullurl);
        request.Method = "GET";
        request.ContentType = "application/json";
        // 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.
        return responseFromServer;
    }
    catch (WebException ex)
    {
        return "ERROR " + ex.Message;
    }
    catch (Exception ex)
    {
        return "ERROR " + ex.Message;
    }
}

【讨论】:

    【解决方案2】:

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

    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();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 2016-09-09
      相关资源
      最近更新 更多