此处使用REST Java API请求OAuth 2.0令牌

问题描述

我正在尝试使用Rest服务java向Here API请求令牌,以获得OAuth 2.0令牌证书。我被限制在请求级别,并且始终遇到相同的错误,但是根据文档,我没有做错任何事情。

这是REST Java中发出请求的必要代码。 我尝试了以下代码

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.httpentity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class here {

private static final String HMAC_SHA256 = "HmacSHA256";
private static final String ENC = "UTF-8";
private static Base64 base64 = new Base64();
private static String key = "MyKeyID"; // here.access.key.id from credential file
private static String secret = "MySecretKey" //here.access.key.secret
public static void main(String[] args) {


 HttpClient httpClient = new DefaultHttpClient();
 long value = (System.currentTimeMillis() / 1000);
 int unique = (int) (Math.random() * 100000000);
 
 // These params should ordered in key
    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    qparams.add(new BasicNameValuePair("grant_type","client_credentials"));
    qparams.add(new BasicNameValuePair("oauth_consumer_key","MY_KEY_ID"));
    qparams.add(new BasicNameValuePair("oauth_nonce",""
            + unique));
    qparams.add(new BasicNameValuePair("oauth_signature_method","HMAC-SHA256"));
    qparams.add(new BasicNameValuePair("oauth_timestamp",""
            + value));
    qparams.add(new BasicNameValuePair("oauth_version","1.0"));
    System.err.println("query param->>>");
    
    // creating authentication signature
    String  signature = getSignature(URLEncoder.encode(
                    "https://account.api.here.com/oauth2/token",ENC),URLEncoder.encode(URLEncodedUtils.format(qparams,ENC));
  
    
   // comibining the params
    String authHeader = "OAuth oauth_consumer_key=MY_KEY,"
           +"oauth_nonce="+unique+","
           +"oauth_signature="+signature+","
           +"oauth_signature_method=HMAC-SHA256,"
           +"oauth_timestamp="+value+","
           +"oauth_version=1.0";
   
    
    HttpPost httpPost = new HttpPost("https://account.api.here.com/oauth2/token");
    httpPost.addHeader("Content-Type","application/x-www-form-urlencoded");
    httpPost.setHeader(HttpHeaders.AUTHORIZATION,authHeader);
   
    String grant_type = "client_credentials";
    StringEntity input = new StringEntity("grant_type=" + grant_type);
    httpPost.setEntity(input);
    // output the response content.
    System.out.println("Token and Token Secrect:");
    
    HttpResponse    response = httpClient.execute(httpPost);
    httpentity entity = response.getEntity();
    
    if (entity != null) {
        
        InputStream instream = entity.getContent();
        int len;
        byte[] tmp = new byte[2048];
        try {
            while ((len = instream.read(tmp)) != -1) {
                System.out.println(new String(tmp,len,ENC));
            }
        } catch (IOException e) {
            // Todo Auto-generated catch block
            e.printstacktrace();
        }
    }


}

private static String getSignature(String url,String params) throws UnsupportedEncodingException,NoSuchAlgorithmException,InvalidKeyException {
    
    StringBuilder base = new StringBuilder();
    base.append("POST&");
    base.append(url);
    base.append("&");
    base.append(params);
    System.out.println("Stirng for oauth_signature generation:" + base);
    // yea,don't ask me why,it is needed to append a "&" to the end of
    // secret key.
    byte[] keyBytes = (secret + "&").getBytes(ENC);

    SecretKey key = new SecretKeySpec(keyBytes,HMAC_SHA256);

    Mac mac = Mac.getInstance(HMAC_SHA256);
    mac.init(key);

    // encode it,base64 it,change it to string and return.
    return new String(base64.encode(mac.doFinal(base.toString().getBytes(
            ENC))),ENC).trim();

}}

这是我不断得到的错误

{“ errorId”:“ ERROR-27b88f02-5d76-40ea-81d5-de6e70cf8464”,“ httpStatus”:401,“ errorCode”:401205,“ message”:“标头中不支持的签名方法。需要HMAC-SHA256 “,” error“:” invalid_request“,” error_description“:” errorCode:'401205'。标头中不支持的签名方法。需要HMAC-SHA256“}

根据文档https://developer.here.com/documentation/authentication/dev_guide/topics/using-aaa-javasdk-or-3rd-party-libraries.html

我根据上述api文档开发了代码,但没有得到结果。 有人知道如何解决此问题吗?

解决方法

我尝试了这段代码

 HttpClient httpClient = HttpClientBuilder.create().build();
         String headers = "grant_type=client_credentials"+"&oauth_consumer_key=mykey"+"&oauth_nonce=uniquevalue"+"&oauth_signature_method=HMAC-SHA256"+"&oauth_timestamp=timestamp"+"&oauth_version=1.0";
          String combine = "POST"+"\n&"+URLEncoder.encode("https://account.api.here.com/oauth2/token",StandardCharsets.UTF_8.toString())+"\n&"+URLEncoder.encode(headers,StandardCharsets.UTF_8.toString());
          Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
          SecretKeySpec secret_key = new SecretKeySpec(("mysecretkey &").getBytes(),"HmacSHA256");
          sha256_HMAC.init(secret_key);
          String signature = Base64.encodeBase64String(sha256_HMAC.doFinal(combine.getBytes()));
           String authHeader = "OAuth "
                   + "oauth_consumer_key=\"X1E2a0ElfkaHx7aezqN5Hg-1234\","
                   +"oauth_nonce=\"uniquevalue\","
                   +"oauth_signature=\""+signature+"\","
                   +"oauth_signature_method=\"HMAC-SHA256\","
                   +"oauth_timestamp=\"timestamp\","
                   +"oauth_version=\"1.0\"";
            HttpPost httpPost = new HttpPost("https://account.api.here.com/oauth2/token");
            httpPost.addHeader("Content-Type","application/x-www-form-urlencoded");
            httpPost.addHeader("Host","account.api.here.com");
            httpPost.setHeader(HttpHeaders.AUTHORIZATION,authHeader);
            StringEntity input = new StringEntity("grant_type=" + "client_credentials");
            httpPost.setEntity(input);
            HttpResponse    response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            

它显示了另一个错误,例如errorCode:'401202'。无效的客户端授权标头,要求签署的请求格式。请给一些建议,如何索取代币?

,

您能否尝试将代码修改为-

//创建身份验证签名

字符串签名= getSignature(URLEncoder.encode(
“ https://account.api.here.com/oauth2/token",ENC), URLEncoder.encode(URLEncodedUtils.format(qparams,ENC),ENC));

//合并参数

String authHeader =“ OAuth oauth_consumer_key = MY_KEY,” +“ oauth_nonce =” + unique +“,” +“ oauth_signature =” + URLEncoder.encode(signature,“ UTF-8”)+“,” +“ oauth_signature_method = HMAC-SHA256” +“ oauth_timestamp =” + value +“,” +“ oauth_version = 1.0”;