我正在使用Play框架为Instagram实时API开发消费者。但是仍然不能正确地执行x中心签名验证。那么,我们如何使用Java和Play框架来执行Instagram x中心签名验证呢?
以下是我的当前代码:
SubscriptionUtil
内部,我使用以下代码执行验证:
公共静态VerificationResult(encodedResult.equals(xHubSignature),verifySubscriptionPostSignature(String clientSecret,String rawJsonData,String xHubSignature) { SecretKeySpec keySpec;keySpec =新SecretKeySpec(clientSecret.getBytes("UTF-8"),HMAC_SHA1);mac;Mac = Mac.getInstance(HMAC_SHA1);mac.init(keySpec);byte[]结果;return =keySpec(“UTF-8”);String en21=(结果);返回新;}我创建了一个独立的Python脚本,它复制instagram-python实现,它们为相同的clientSecret
和jsonString
生成相同的结果。也许我应该提供原始二进制数据而不是字符串。
如果我们需要一个用于JSON请求的原始二进制数据,那么我需要创建自定义BodyParser来将JSON请求解析为原始二进制data5
参考文献:
1-4 (所以不允许我发布超过2个链接,所以我把所有的参考在这里。链接包含Ruby、Python和PHP中的签名验证)
6我的独立python脚本:#!/usr/bin/env python
import sys
import hmac
import hashlib
hc_client_secret = "myclientsecret"
hc_raw_response = "[{\"subscription_id\":\"1\",\"object\":\"user\",\"object_id\":\"1234\",\"changed_aspect\":\"media\",\"time\":1297286541},{\"subscription_id\":\"2\",\"object\":\"tag\",\"object_id\":\"nofilter\",\"changed_aspect\":\"media\",\"time\":1297286541}]"
client_secret = hc_client_secret
raw_response = hc_raw_response
if len(sys.argv) != 3:
print 'Usage verify_signature <client_secret> <raw_response>.\nSince the inputs are invalid, use the hardcoded value instead!'
else:
client_secret = sys.argv[1]
raw_response = sys.argv[2]
print "client_secret = " + client_secret
print "raw_response = " + raw_response
digest = hmac.new(client_secret.encode('utf-8'), msg=raw_response.encode('utf-8'), digestmod=hashlib.sha1).hexdigest()
print digest
发布于 2013-12-24 14:00:36
最后,我设法找到了解决办法。对于Play框架中的Controller,我们需要使用BodyParser.Raw
,这样我们就可以将有效负载请求提取为原始数据,即字节数组。
以下是Play Framework中控制器的代码:
@BodyParser.Of(BodyParser.Raw.class)
public static Result receiveRawInstaData(){
Map<String, String[]> headers = request().headers();
RawBuffer jsonRaw = request().body().asRaw();
if(jsonRaw == null){
logger.warn("jsonRaw is null. Something is wrong with the payload");
return badRequest("Expecting serializable raw data");
}
String[] xHubSignature = headers.get(InstaSubscriptionUtils.HTTP_HEADER_X_HUB_SIGNATURE);
if(xHubSignature == null){
logger.error("Invalid POST. It does not contain {} in its header", InstaSubscriptionUtils.HTTP_HEADER_X_HUB_SIGNATURE);
return badRequest("You are not Instagram!\n");
}
String json;
byte[] jsonRawBytes;
jsonRawBytes = jsonRaw.asBytes();
json = new String(jsonRawBytes, StandardCharsets.UTF_8);
try {
String clientSecret = InstaSubscriptionUtils.getClientSecret(1);
VerificationResult verificationResult = SubscriptionUtil.verifySubscriptionPostRequestSignature
(clientSecret,jsonRawBytes, xHubSignature[0]);
if(verificationResult.isSuccess()){
logger.debug("Signature matches!. Received signature: {}, calculated signature: {}", xHubSignature[0], verificationResult.getCalculatedSignature());
}else{
logger.error("Signature doesn't match. Received signature: {}, calculated signature: {}", xHubSignature[0], verificationResult.getCalculatedSignature());
return badRequest("Signature does not match!\n");
}
} catch (InstagramException e) {
logger.error("Instagram exception.", e);
return internalServerError("Internal server error. We will attend to this problem ASAP!");
}
logger.debug("Received xHubSignature: {}", xHubSignature[0]);
logger.info("Sucessfully received json data: {}", json);
return ok("OK!");
}
以及方法verifySubscriptionPostRequestSignature
在SubscriptionUtil
中的代码
public static VerificationResult verifySubscriptionPostRequestSignature(String clientSecret, byte[] rawJsonData, String xHubSignature) throws InstagramException{
SecretKeySpec keySpec;
keySpec = new SecretKeySpec(clientSecret.getBytes(StandardCharsets.UTF_8), HMAC_SHA1);
Mac mac;
try {
mac = Mac.getInstance(HMAC_SHA1);
mac.init(keySpec);
byte[] result = mac.doFinal(rawJsonData);
String encodedResult = Hex.encodeHexString(result);
return new VerificationResult(encodedResult.equals(xHubSignature), encodedResult);
} catch (NoSuchAlgorithmException e) {
throw new InstagramException("Invalid algorithm name!", e);
} catch (InvalidKeyException e){
throw new InstagramException("Invalid key: " + clientSecret, e);
}
}
我在jInstagram中实现了这个解决方案,下面是指向源代码的链接:SubscriptionUtil
https://stackoverflow.com/questions/20658813
复制相似问题