Java 未经授权

Java 未经授权,java,oauth,withings,Java,Oauth,Withings,我在从Withings API获取用户数据访问令牌时遇到问题(API文档的步骤3): 服务返回“无效签名”错误 以下是我的方法: private static String getSignature(String url, String params, String authSecret) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException { StringBuilder

我在从Withings API获取用户数据访问令牌时遇到问题(API文档的步骤3):

服务返回“无效签名”错误

以下是我的方法:

private static String getSignature(String url, String params, String authSecret) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
    StringBuilder base = new StringBuilder();
    base.append("GET&");
    base.append(url);
    base.append("&");
    base.append(params);

    byte[] keyBytes;
    if (authSecret != null) {
        keyBytes = (secret + "&" + authSecret + "&").getBytes(ENC);
    } else {
        keyBytes = (secret + "&").getBytes(ENC);
    }

    SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);

    Mac mac = Mac.getInstance(HMAC_SHA1);
    mac.init(key);
    Base64 base64 = new Base64();
    return new String(base64.encode(mac.doFinal(base.toString().getBytes(ENC))), ENC).trim();
}
public static AuthResponse getAccessToken(AuthRequest request) {
    try {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String url = "https://oauth.withings.com/account/access_token";
        URIBuilder builder = new URIBuilder(url);
        List<NameValuePair> valuePairs = new ArrayList<>();

        valuePairs.add(new BasicNameValuePair("oauth_consumer_key", key));
        valuePairs.add(new BasicNameValuePair("oauth_nonce", "" + (int) (Math.random() * 100000000)));
        valuePairs.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
        valuePairs.add(new BasicNameValuePair("oauth_timestamp", "" + (System.currentTimeMillis() / 1000)));
        valuePairs.add(new BasicNameValuePair("oauth_token", request.getOauthToken()));
        valuePairs.add(new BasicNameValuePair("oauth_version", "1.0"));
        valuePairs.add(new BasicNameValuePair("userid", request.getUserId()));

        String signature = getSignature(URLEncoder.encode(url, ENC), URLEncoder.encode(URLEncodedUtils.format(valuePairs, ENC), ENC), request.getOauthTokenSecret());

        valuePairs.add(new BasicNameValuePair("oauth_signature", signature));

        builder.addParameters(valuePairs);

        URI uri = builder.build();

        HttpGet httpget = new HttpGet(uri);

        HttpResponse response = httpclient.execute(httpget);
        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

        StringBuilder sb = new StringBuilder();
        String result;

        while ((result = reader.readLine()) != null) {
            sb.append(result);
        }

        return null;
    } catch (Exception e) {
        throw new RuntimeException("*Error during getAccessToken request");
    }
}
private static String getSignature(字符串url、字符串参数、字符串authSecret)引发UnsupportedEncodingException、NoSuchAlgorithmException、InvalidKeyException{
StringBuilder base=新的StringBuilder();
base.append(“GET&”);
base.append(url);
基数。追加(“&”);
base.append(params);
字节[]键字节;
如果(authSecret!=null){
keyBytes=(secret+“&”+authSecret+“&”).getBytes(ENC);
}否则{
keyBytes=(secret+“&”).getBytes(ENC);
}
SecretKey key=newsecretkeyspec(keyBytes,HMAC_SHA1);
Mac Mac=Mac.getInstance(HMAC_SHA1);
mac.init(密钥);
Base64 Base64=新的Base64();
返回新字符串(base64.encode(mac.doFinal(base.toString().getBytes(ENC))),ENC.trim();
}
公共静态AuthResponse getAccessToken(AuthRequest请求){
试一试{
CloseableHttpClient httpclient=HttpClients.createDefault();
字符串url=”https://oauth.withings.com/account/access_token";
URIBuilder=新的URIBuilder(url);
List valuePairs=new ArrayList();
添加(新的BasicNameValuePair(“oauth_consumer_key”,key));
add(新的BasicNameValuePair(“oauth_nonce)”,“”+(int)(Math.random()*100000000));
添加(新的BasicNameValuePair(“oauth_签名_方法”、“HMAC-SHA1”);
添加(新的BasicNameValuePair(“oauth_timestamp”,“System.currentTimeMillis()/1000”);
add(新的BasicNameValuePair(“oauth_令牌”,request.getOauthToken());
添加(新的BasicNameValuePair(“oauth_版本”、“1.0”);
添加(新的BasicNameValuePair(“userid”,request.getUserId());
String signature=getSignature(URLEncoder.encode(url,ENC),URLEncoder.encode(URLEncodedUtils.format(valuePairs,ENC),ENC),request.getOauthTokenSecret());
添加(新的BasicNameValuePair(“oauth_签名”,signature));
builder.addParameters(valuePairs);
URI=builder.build();
HttpGet HttpGet=新的HttpGet(uri);
HttpResponse response=httpclient.execute(httpget);
BufferedReader=new BufferedReader(new InputStreamReader(response.getEntity().getContent());
StringBuilder sb=新的StringBuilder();
字符串结果;
而((result=reader.readLine())!=null){
某人追加(结果);
}
返回null;
}捕获(例外e){
抛出新的RuntimeException(“*getAccessToken请求期间出错”);
}
}
我还尝试在没有“authSecret”参数的情况下生成签名(如withings规范),尝试更改顺序并按字母顺序放置“oauth_签名”参数,但没有成功 有人能帮我吗?
PS:在Api文档的前两个步骤中,我使用此签名生成器成功地获得了oauth_令牌、oauth_令牌、userid。

为了使步骤3正常工作,您必须从行中删除第二个“&”:

keyBytes = (secret + "&" + authSecret + "&").getBytes(ENC);
因此,它变成:

keyBytes = (secret + "&" + authSecret).getBytes(ENC);

您能尝试一下,而不是实现自己的OAuth解决方案吗?他们甚至为您的站点提供了一个可供复制和使用的应用程序。@user3707125 ThanX很多,授权工作正常。我成功地从Withings“游乐场”获取了数据,并获得了访问权限和秘密令牌。但是这个oauth实现有两个问题:在版本2.0的maven central中它不可用,当我尝试获取数据(身体测量)时,比如在示例中,我得到了状态为2554(错误操作或错误Web服务)的空响应身体。我做错了什么<代码>OAuthRequest request=新的OAuthRequest(动词.GET)https://wbsapi.withings.net/measure?action=getmeas“、服务);signRequest(accessToken,request);Response=request.send();返回response.getBody()我修复了将“.signatureType(signatureType.QueryString)”添加到OAuthService中的问题。