Skip to content

Instantly share code, notes, and snippets.

@surjikal
Created November 19, 2013 03:18
Show Gist options
  • Save surjikal/7539745 to your computer and use it in GitHub Desktop.
Save surjikal/7539745 to your computer and use it in GitHub Desktop.
Apex 2-legged OAuth 1.0
public class OAuth {
public static HttpRequest signRequest(HttpRequest req, String consumerKey, String consumerSecret) {
String nonce = String.valueOf(Crypto.getRandomLong());
String timestamp = String.valueOf(DateTime.now().getTime() / 1000);
Map<String,String> parameters = new Map<String,String>();
parameters.put('oauth_signature_method','HMAC-SHA1');
parameters.put('oauth_consumer_key', consumerKey);
parameters.put('oauth_timestamp', timestamp);
parameters.put('oauth_nonce', nonce);
String signature = generateSignature(req, consumerSecret, parameters);
String header = generateHeader(signature, parameters);
req.setHeader('Authorization', header);
return req;
}
private static String generateHeader(String signature, Map<String,String> parameters) {
String header = 'OAuth ';
for (String key : parameters.keySet()) {
header = header + key + '="'+parameters.get(key)+'", ';
}
return header + 'oauth_signature="' + signature + '"';
}
private static String generateSignature(HttpRequest req, String consumerSecret, Map<String,String> parameters) {
String s = createBaseString(req, parameters);
Blob sig = Crypto.generateMac(
'HmacSHA1'
, Blob.valueOf(s)
, Blob.valueOf(consumerSecret + '&')
);
return EncodingUtil.urlEncode(EncodingUtil.base64encode(sig), 'UTF-8');
}
private static String createBaseString(HttpRequest req, Map<String,String> parameters) {
Map<String,String> p = parameters.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));
}
// According to OAuth spec, host string should be lowercased, but Google and LinkedIn
// both expect that case is preserved.
return req.getMethod().toUpperCase()+ '&' +
EncodingUtil.urlEncode(host, 'UTF-8') + '&' +
EncodingUtil.urlEncode(s, 'UTF-8');
}
private static 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('&')) {
System.debug('getUrlParams: '+s);
List<String> kv = s.split('=');
if(kv.size()>1) {
System.debug('getUrlParams: -> '+kv[0]+','+kv[1]);
res.put(kv[0],kv[1]);
}
}
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment