领英API中OAuth认证的问题

4

我为我的客户开发LinkedIn库,目前在授权部分遇到了些问题。我使用了RIACorge的OAuth库,并重写了所有内容,以便利用CF9中基于脚本的CFC和MXUnit测试。当我尝试使用HMAC-SHA1算法创建OAuth签名时,似乎总是无法与LinkedIn所需的匹配。这是我签署请求的方法:

  public void function signRequest(any req){
    var params = Arguments.req.getAllParameters();
    var secret = "#Variables.encoder.parameterEncodedFormat(getConsumer().getConsumerSecret())#&#Variables.encoder.parameterEncodedFormat(Arguments.req.getOAuthSecret())#";
    var base = '';

    params = Variables.encoder.encodedParameter(params, true, true);
    secret = JavaCast('string', secret).getBytes();

    local.mac = createObject('java', 'javax.crypto.Mac').getInstance('HmacSHA1');
    local.key = createObject('java', 'javax.crypto.spec.SecretKeySpec').init(secret, local.mac.getAlgorithm());

    base = reReplaceNoCase(Arguments.req.getRequestUrl(), 'http[s]?://', '/');
    params = listSort(params, 'text', 'asc', '&');
    base = JavaCast('string', "#base#&#params#").getBytes();

    local.mac.init(local.key);
    local.mac.update(base);

    Arguments.req.addParameter('oauth_signature', toBase64(mac.doFinal()), true);
  }

我认为问题出在加密的密钥上。我将基本字符串与LinkedIn的OAuth测试工具进行了比较,发现完全匹配,因此用于加密的密钥必须是问题所在。我还没有OAuth令牌密钥,因此我的密钥类似于fdsa43fdsa3j&。这是否正确,或者结尾处的“&”应该以编码格式呈现,还是其他什么?

正确方法

  public void function signRequest(any req){
    var params = Arguments.req.getAllParameters();
    var secret = "#Variables.encoder.parameterEncodedFormat(getConsumer().getConsumerSecret())#&#Variables.encoder.parameterEncodedFormat(Arguments.req.getOAuthSecret())#";
    var base = '';

    params = Variables.encoder.encodedParameter(params, true, true);
    secret = toBinary(toBase64(secret));

    local.mac = createObject('java', 'javax.crypto.Mac').getInstance('HmacSHA1');
    local.key = createObject('java', 'javax.crypto.spec.SecretKeySpec').init(secret, local.mac.getAlgorithm());

    base = "#Arguments.req.getMethod()#&";
    base = base & Variables.encoder.parameterEncodedFormat(Arguments.req.getRequestUrl());
    params = listSort(params, 'text', 'asc', '&');
    base = "#base#&#Variables.encoder.parameterEncodedFormat(params)#";

    local.mac.init(local.key);
    local.mac.update(JavaCast('string', base).getBytes());
    //writeDump(toString(toBase64(mac.doFinal()))); abort;
    Arguments.req.addParameter('oauth_signature', toString(toBase64(mac.doFinal())), true);
  }
1个回答

1

Ben Nadel提供了一个示例,用于使用OAuth连接到Twilio。您的签名代码与他的主要区别在于,他在设置SecretKeySpec时使用了一些编码。

以下是他文章中相关的片段:

<cfset secretKeySpec = createObject(
    "java",
    "javax.crypto.spec.SecretKeySpec"
  ).init(
    toBinary( toBase64( twilioAuthKey ) ),
    "HmacSHA1"
  )
/>

谢谢Pat,我可以告诉这将会给我答案,因为当我打开Ben Nadel的页面时,我的照片出现了 ;) - Dave Long
感谢您的帮助。虽然不是100%正确的答案,但它让我朝着正确的方向前进了。我已经发布了正确的方法,希望能帮助其他人。 - Dave Long
@DaveLong:你应该将其作为单独的答案发布并接受,而不是修改你的问题。这将作为未来读者的路标。或者,编辑Patrick的答案以匹配你使用的解决方案,以便他可以保留“接受”信用。 - ale

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接