Oauth 2.0 生成的OAuth标头给出错误OAuth\u problem=签名\u无效

Oauth 2.0 生成的OAuth标头给出错误OAuth\u problem=签名\u无效,oauth-2.0,oauth,Oauth 2.0,Oauth,我正在尝试使用“OAuth 1.0”执行一个非常简单的HTTP-POST请求,使用4个凭证(使用者密钥、使用者机密、访问令牌、令牌机密)向名为liveperson的外部数据提供者发出请求 我在Java中尝试了几种方法和库来生成OAuth授权头,但我一直得到“OAuth_problem=signature_invalid” 附加的是Java类OauthHeaderGenerator,它生成OAuth授权令牌。我将在CURL命令中替换它 TOKEN_GENERATED_FROM_JAVA_CODE

我正在尝试使用“OAuth 1.0”执行一个非常简单的HTTP-POST请求,使用4个凭证(使用者密钥、使用者机密、访问令牌、令牌机密)向名为liveperson的外部数据提供者发出请求

我在Java中尝试了几种方法和库来生成OAuth授权头,但我一直得到“OAuth_problem=signature_invalid”

附加的是Java类OauthHeaderGenerator,它生成OAuth授权令牌。我将在CURL命令中替换它

TOKEN_GENERATED_FROM_JAVA_CODE --> 
OAuth oauth_consumer_key="***************",oauth_token="="***************",",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1605311654",oauth_nonce="****************",oauth_version="1.0",oauth_signature="5S*****DR3Ast3%2B%2FVY%3D" 



curl -v --request POST 'https://XXXXXXX.liveperson.net/messaging_history/api/account/XXXXXXX/conversations/search?limit=100&offset=0&v=2' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: TOKEN_GENERATED_FROM_JAVA_CODE' \
--data-raw '{"start":{"from":1601474572016,"to":1604066572019}, "contentToRetrieve":["campaign","messageRecords","agentParticipants"]}'

我无法调试这一点,因为签名生成的哪一部分导致了问题。感谢您的帮助。谢谢

Java代码

OauthHeaderGenerator generator = new OauthHeaderGenerator(
                "****************",
                "****************",
                "****************",
                "****************");
        Map<String, String> requestParams = new HashMap<>();
        String header = generator.generateHeader("POST", "https://va.msghist.liveperson.net/messaging_history/api/account/****************/conversations/search?limit=100&offset=0&v=2", requestParams);
        System.out.println("**************");
        System.out.println(header);
        System.out.println("**************");

--------

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class OauthHeaderGenerator {

    private String consumerKey;
    private String consumerSecret;
    private String signatureMethod;
    private String token;
    private String tokenSecret;
    private String version;

    public OauthHeaderGenerator(String consumerKey, String consumerSecret, String token, String tokenSecret) {
        this.consumerKey = consumerKey;
        this.consumerSecret = consumerSecret;
        this.token = token;
        this.tokenSecret = tokenSecret;
        this.signatureMethod = "HMAC-SHA1";
        this.version = "1.0";
    }

    private static final String oauth_consumer_key = "oauth_consumer_key";
    private static final String oauth_token = "oauth_token";
    private static final String oauth_signature_method = "oauth_signature_method";
    private static final String oauth_timestamp = "oauth_timestamp";
    private static final String oauth_nonce = "oauth_nonce";
    private static final String oauth_version = "oauth_version";
    private static final String oauth_signature = "oauth_signature";
    private static final String HMAC_SHA1 = "HmacSHA1";


    public String generateHeader(String httpMethod, String url, Map<String, String> requestParams) {
        StringBuilder base = new StringBuilder();
        String nonce = getNonce();
        String timestamp = getTimestamp();
        String baseSignatureString = generateSignatureBaseString(httpMethod, url, requestParams, nonce, timestamp);
        String signature = encryptUsingHmacSHA1(baseSignatureString);
        base.append("OAuth ");
        append(base, oauth_consumer_key, consumerKey);
        append(base, oauth_token, token);
        append(base, oauth_signature_method, signatureMethod);
        append(base, oauth_timestamp, timestamp);
        append(base, oauth_nonce, nonce);
        append(base, oauth_version, version);
        append(base, oauth_signature, signature);
        base.deleteCharAt(base.length() - 1);
        //System.out.println("header : " + base.toString());
        return base.toString();
    }


    private String generateSignatureBaseString(String httpMethod, String url, Map<String, String> requestParams, String nonce, String timestamp) {
        Map<String, String> params = new HashMap<>();
        requestParams.entrySet().forEach(entry -> {
            put(params, entry.getKey(), entry.getValue());
        });
        put(params, oauth_consumer_key, consumerKey);
        put(params, oauth_nonce, nonce);
        put(params, oauth_signature_method, signatureMethod);
        put(params, oauth_timestamp, timestamp);
        put(params, oauth_token, token);
        put(params, oauth_version, version);
        Map<String, String> sortedParams = params.entrySet().stream().sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        StringBuilder base = new StringBuilder();
        sortedParams.entrySet().forEach(entry -> {
            base.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        });
        base.deleteCharAt(base.length() - 1);
        String baseString = httpMethod.toUpperCase() + "&" + encode(url) + "&" + encode(base.toString());
        return baseString;
    }

    private String encryptUsingHmacSHA1(String input) {
        String secret = new StringBuilder().append(encode(consumerSecret)).append("&").append(encode(tokenSecret)).toString();
        byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
        SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);
        Mac mac;
        try {
            mac = Mac.getInstance(HMAC_SHA1);
            mac.init(key);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
            return null;
        }
        byte[] signatureBytes = mac.doFinal(input.getBytes(StandardCharsets.UTF_8));
        return new String(Base64.getEncoder().encode(signatureBytes));
    }


    private String encode(String value) {
        String encoded = "";
        try {
            encoded = URLEncoder.encode(value, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String sb = "";
        char focus;
        for (int i = 0; i < encoded.length(); i++) {
            focus = encoded.charAt(i);
            if (focus == '*') {
                sb += "%2A";
            } else if (focus == '+') {
                sb += "%20";
            } else if (focus == '%' && i + 1 < encoded.length() && encoded.charAt(i + 1) == '7' && encoded.charAt(i + 2) == 'E') {
                sb += '~';
                i += 2;
            } else {
                sb += focus;
            }
        }
        return sb.toString();
    }

    private void put(Map<String, String> map, String key, String value) {
        map.put(encode(key), encode(value));
    }

    private void append(StringBuilder builder, String key, String value) {
        builder.append(encode(key)).append("=\"").append(encode(value)).append("\",");
    }

    private String getNonce() {
        int leftLimit = 48; // numeral '0'
        int rightLimit = 122; // letter 'z'
        int targetStringLength = 10;
        Random random = new Random();

        String generatedString = random.ints(leftLimit, rightLimit + 1).filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)).limit(targetStringLength)
                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
        return generatedString;

    }

    private String getTimestamp() {
        return Math.round((new Date()).getTime() / 1000.0) + "";
    }

}

OauthHeaderGenerator生成器=新的OauthHeaderGenerator(
"****************",
"****************",
"****************",
"****************");
Map requestParams=new HashMap();
字符串头=generator.generateHeader(“POST”https://va.msghist.liveperson.net/messaging_history/api/account/****************/对话/搜索?限制=100,偏移量=0,v=2”,请求参数);
System.out.println(“****************”);
系统输出打印项次(表头);
System.out.println(“****************”);
--------
导入java.net.urlcoder;
导入java.nio.charset.StandardCharset;
导入java.security.InvalidKeyException;
导入java.security.NoSuchAlgorithmException;
导入java.util.Base64;
导入java.util.Date;
导入java.util.HashMap;
导入java.util.LinkedHashMap;
导入java.util.Map;
导入java.util.Random;
导入java.util.stream.collector;
导入javax.crypto.Mac;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.SecretKeySpec;
公共类OauthHeaderGenerator{
私人消费市场;
私有字符串ConsumerCret;
私有字符串签名方法;
私有字符串令牌;
私密字符串标记;
私有字符串版本;
公共OauthHeaderGenerator(字符串consumerKey、字符串ConsumerCret、字符串令牌、字符串令牌机密){
this.consumerKey=consumerKey;
this.consumerSecret=consumerSecret;
this.token=token;
this.tokenSecret=tokenSecret;
this.signatureMethod=“HMAC-SHA1”;
this.version=“1.0”;
}
私有静态最终字符串oauth\u consumer\u key=“oauth\u consumer\u key”;
私有静态最终字符串oauth_token=“oauth_token”;
私有静态最终字符串oauth\u signature\u method=“oauth\u signature\u method”;
私有静态最终字符串oauth_timestamp=“oauth_timestamp”;
私有静态最终字符串oauth\u nonce=“oauth\u nonce”;
私有静态最终字符串oauth_version=“oauth_version”;
私有静态最终字符串oauth_签名=“oauth_签名”;
私有静态最终字符串HMAC_SHA1=“HmacSHA1”;
公共字符串生成器标头(字符串httpMethod、字符串url、映射请求参数){
StringBuilder base=新的StringBuilder();
字符串nonce=getNonce();
字符串timestamp=getTimestamp();
String baseSignatureString=generateSignatureBaseString(httpMethod、url、requestParams、nonce、timestamp);
字符串签名=加密使用HMACSHA1(baseSignatureString);
base.append(“OAuth”);
追加(基本、oauth\u消费者密钥、消费者密钥);
附加(基本、oauth_令牌、令牌);
append(base、oauth\u signature\u方法、signatureMethod);
追加(基本、oauth_时间戳、时间戳);
附加(base、oauth\u nonce、nonce);
追加(基本、oauth_版本、版本);
附加(基本、oauth_签名、签名);
base.deleteCharAt(base.length()-1);
//System.out.println(“标题:+base.toString());
返回base.toString();
}
私有字符串generateSignatureBaseString(字符串httpMethod、字符串url、映射请求参数、字符串nonce、字符串时间戳){
Map params=新的HashMap();
requestParams.entrySet().forEach(条目->{
put(params,entry.getKey(),entry.getValue());
});
put(参数、oauth_消费者_密钥、消费者密钥);
put(参数、当前值、当前值);
put(参数、oauth\u签名方法、签名方法);
put(参数、oauth_时间戳、时间戳);
put(参数、oauth_令牌、令牌);
put(参数,oauth_版本,版本);
Map-sortedParams=params.entrySet().stream().sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(oldValue,newValue)->oldValue,LinkedHashMap::new));
StringBuilder base=新的StringBuilder();
sortedParams.entrySet().forEach(条目->{
base.append(entry.getKey()).append(“=”).append(entry.getValue()).append(“&”);
});
base.deleteCharAt(base.length()-1);
String baseString=httpMethod.toUpperCase()+“&”+encode(url)+“&”+encode(base.toString());
返回基串;
}
私有字符串加密使用HMACSHA1(字符串输入){
String secret=new StringBuilder().append(encode(consumerSecret)).append(“&”).append(encode(tokenSecret)).toString();
byte[]keyBytes=secret.getBytes(StandardCharsets.UTF_8);
SecretKey key=newsecretkeyspec(keyBytes,HMAC_SHA1);
Mac-Mac;
试一试{
mac=mac.getInstance(HMAC_SHA1);
mac.init(密钥);
}捕获(NoSuchAlgorithmException | InvalidKeyException e){
e、 printStackTrace();
返回null;
}
byte[]signatureBytes=mac.doFinal(input.getBytes(StandardCharsets.UTF_8));
返回新字符串(Base64.getEncoder().encode(signatureBytes));
}
私有字符串编码(字符串值){
字符串编码=”;
试一试{
encoded=urlcoder.encode(值为“UTF-8”);
}捕获(例外e){
e、 printStackTrace();
}
串某人“”;
焦焦;
对于(int i=0;i<已编码)。