Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

Can anybody help me with the oauth 1.0 oauth_signature generation from the client secret and consumer key? I have got client secret and consumer key along with the oauth token. Just need helping hand to generate the header and oauth_signature.

I found a post on StackOverflow really helpful but complete code is not there.

Please help me to understand from my client secret and consumer key how will I encrypt and generate oauth_signature?

share|improve this question
add comment

1 Answer 1

up vote 2 down vote accepted

There is complete OAuth 1.0 code at my fork of sfdc-oauth-playground (originally by Jesper Joergensen - I fixed a couple of bugs in Jesper's code and added the 'two-legged' OAuth flow). Here is the header/oauth_signature code from OAuth.cls:

private void refreshParameters() {
    parameters.clear();
    parameters.put('oauth_consumer_key',consumerKey);
    if(token!=null) {
        parameters.put('oauth_token',token);
    }
    if(verifier!=null) {
        parameters.put('oauth_verifier',verifier);
    }
    parameters.put('oauth_signature_method','HMAC-SHA1');
    parameters.put('oauth_timestamp',timestamp);
    parameters.put('oauth_nonce',nonce);
    parameters.put('oauth_callback',callbackUrl);
}

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('&')) {
        System.debug('getUrlParams: '+s);
        List<String> kv = s.split('=');
        if(kv.size()>1) {
          // RFC 5849 section 3.4.1.3.1 and 3.4.1.3.2 specify that parameter names 
          // and values are decoded then encoded before being sorted and concatenated
          // Section 3.6 specifies that space must be encoded as %20 and not +
          String encName = EncodingUtil.urlEncode(EncodingUtil.urlDecode(kv[0], 'UTF-8'), 'UTF-8').replace('+','%20');
          String encValue = EncodingUtil.urlEncode(EncodingUtil.urlDecode(kv[1], 'UTF-8'), 'UTF-8').replace('+','%20');
          System.debug('getUrlParams:  -> '+encName+','+encValue);
          res.put(encName,encValue);
        }
    }
    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));
    }

    // 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');
}

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

    refreshParameters();

    String s = createBaseString(parameters, req);

    System.debug('Signature base string: '+s);

    Blob sig = Crypto.generateMac('HmacSHA1', Blob.valueOf(s), 
                   Blob.valueOf(consumerSecret+'&'+
                                (tokenSecret!=null ? tokenSecret : '')));
    signature = EncodingUtil.urlEncode(EncodingUtil.base64encode(sig), 'UTF-8');
    System.debug('Signature: '+signature);

    String header = 'OAuth ';
    for (String key : parameters.keySet()) {
        header = header + key + '="'+parameters.get(key)+'", ';
    }
    header = header + 'oauth_signature="'+signature+'"';
    System.debug('Authorization: '+header);
    req.setHeader('Authorization',header);
}   
share|improve this answer
    
Awesome !!!No words for this .I will try this –  Mohith Shrivastava Dec 19 '12 at 17:21
    
Cool - btw - you might want to work on your accept rate. Review some of the answers to your questions, and accept them as appropriate: salesforce.stackexchange.com/users/645/… –  metadaddy Dec 19 '12 at 17:30
    
Cool will do .Few was not happy but this one is good and will accept once i try this . –  Mohith Shrivastava Dec 19 '12 at 17:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.