2012-07-13 57 views
1

我们需要对使用OAuth 1.0的服务进行一些标注,并要求使用HMAC-SHA1对每个请求进行签名。SalesForce中Crypto.generateMac()的问题APEX

该服务没有任何APEX客户端API。因此,我们必须手动完成。

不幸的是,

EncodingUtil.base64Encode(Crypto.generateMac('hmacSHA1', Blob.valueOf(data), Blob.valueOf(key))); 

返回从我们期待一个不同的字符串。我们已经将相同输入的输出与其他语言的库进行了比较。产量不同。

+0

你可以举个例子说明它的不同之处吗,它只是base64 vs十六进制编码? – superfell 2012-07-13 15:28:44

+0

如果你提供了一个你所看到的例子,它肯定会有所帮助:一个输入和两个不同的输出。我一直在通过Apex使用HmacSHA256签名,但没有问题。 – jkraybill 2012-07-14 07:10:13

回答

2

我没有问题呼吁OAuth 1.0。下面是一些示例的Apex签署您的要求:

编辑:添加额外的代码

private Map<String,String> getUrlParams(String value) 
{ 
    Map<String,String> res = new Map<String,String>(); 
    if(value==null || value=='') 
    { 
     return res; 
    } 
    for(String s : value.split('&')) 
    { 
     List<String> kv = s.split('='); 
     if(kv.size()>1) 
     { 
      res.put(kv[0],kv[1]); 
     } 
    } 
    return res; 
} 

private String createBaseString(Map<String,String> oauthParams, HttpRequest req) 
{ 
    Map<String,String> p = oauthParams.clone(); 
    if(req.getMethod().equalsIgnoreCase('post') && req.getBody()!=null && req.getHeader('Content-Type')=='application/x-www-form-urlencoded') 
     p.putAll(getUrlParams(req.getBody())); 
    String host = req.getEndpoint(); 
    Integer n = host.indexOf('?'); 
    if(n > -1) 
    { 
     p.putAll(getUrlParams(host.substring(n+1))); 
     host = host.substring(0,n); 
    } 
    List<String> keys = new List<String>(); 
    keys.addAll(p.keySet()); 
    keys.sort(); 
    String s = keys.get(0)+'='+p.get(keys.get(0)); 
    for(Integer i=1; i<keys.size(); i++) 
     s = s + '&' + keys.get(i) + '=' + p.get(keys.get(i)); 

    return req.getMethod().toUpperCase() + '&' + EncodingUtil.urlEncode(host, 'UTF-8') + '&' + EncodingUtil.urlEncode(s, 'UTF-8'); 
} 

public void sign(HttpRequest req) 
{ 
    nonce = String.valueOf(Crypto.getRandomLong()); 
    timestamp = String.valueOf(DateTime.now().getTime()/1000); 

    refreshParameters(); 

    String s = createBaseString(parameters, req); 
    Blob sig = Crypto.generateMac('HmacSHA1', Blob.valueOf(s), 
     Blob.valueOf(consumerSecret+'&'+ (tokenSecret!=null ? tokenSecret : ''))); 

    signature = EncodingUtil.urlEncode(EncodingUtil.base64encode(sig), 'UTF-8'); 

    String header = 'OAuth '; 
    for (String key : parameters.keySet()) 
    { 
     header = header + key + '="'+parameters.get(key)+'", '; 
    } 
    header = header + 'oauth_signature="'+signature+'"'; 
    req.setHeader('Authorization',header); 
} 

这可能是深远的,但有可能是一个大小写的问题?注意我打电话'HmacSHA1'不是'hmacSHA1'

+0

嗨@adam,这很好,我试图用这个generatemac加密,我们如何使用我们自己的自定义私钥解密这个?你可以请张贴一个示例代码吗? – Sathya 2012-10-13 18:46:06

+0

亚当可以请你把整个代码 – 2012-12-19 08:44:28

+0

现在发布附加代码。 – Adam 2012-12-19 17:28:20