You need to sign in to do that
Don't have an account?
Nayana Pawar 5
down votefavorite
Please help me.
I have a salesforce requirement that necessitates a callout from Apex to an external web service that receives signed OAuth responses.
I am getting oAuth_token successfully. But after that when I am trying to get data using that oAuth_token I am getting error 'signature_invalid'.
Check getAccData method from code as below.
global class OAuthToken
{
private OAuthService__c service;
private String token;
private String tokenSecret;
private Boolean isAccess = false;
private String verifier;
private String nonce;
private String timestamp;
private String signature;
private String consumerKey;
private String consumerSecret;
private Map<String,String> parameters = new Map<String,String>();
public String message { get; set; }
public String callbackUrl {get; set; }
public void setConsumerKey(String value) { consumerKey = value; }
public void setConsumerSecret(String value) { consumerSecret = value; }
public String newAuthorization(String serviceName)
{
service = [SELECT request_token_url__c, access_token_url__c, consumer_key__c,consumer_secret__c, authorization_url__c,
(select token__c, secret__c, isAccess__c FROM tokens__r WHERE owner__c=:UserInfo.getUserId() )
FROM OAuthService__c WHERE name = :serviceName];
if(service==null)
{
System.debug('Couldn\'t find Oauth Service '+serviceName);
message = 'Service '+serviceName+' was not found in the local configuration';
return null;
}
if(callbackUrl==null)
{
if(ApexPages.currentPage()==null || ApexPages.currentPage().getHeaders().get('Host')==null) {
message = 'No callback page was set and it couldn\'t be generated from Apex context';
System.debug(message);
return null;
}
callbackUrl = EncodingUtil.urlEncode('https://'+ApexPages.currentPage().getHeaders().get('Host')+
Page.CompleteAuth.getUrl(),'UTF-8');
}
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint('https://www.gliffy.com/api/1.0/accounts/5023581/users/nileshbhd5@gmail.com/oauth_token.xml?action=create&description=createuser');//service.request_token_url__c
req.setTimeout(12000);
System.debug('Request body set to: '+req.getBody());
consumerKey = service.consumer_key__c;
consumerSecret = service.consumer_secret__c;
sign(req);
HttpResponse res = null;
res = h.send(req);
String XMLString = res.getBody();
parseXML(XMLString);
System.debug('Response from request token request: ('+res.getStatusCode()+')'+res.getBody());
if(res.getStatusCode()>299) {
message = 'Failed getting a request token. HTTP Code = '+res.getStatusCode()+
'. Message: '+res.getStatus()+'. Response Body: '+res.getBody();
return null;
}
String resParams = serviceName == 'test1234' ?'oauth_token=token&oauth_token_secret=token_secret' : res.getBody();
Map<String,String> rp = getUrlParams(resParams);
OAuth_Token__c t = new OAuth_Token__c();
t.owner__c = UserInfo.getUserId();
t.OAuth_Service__c = service.id;
t.token__c = token;
t.secret__c = tokenSecret;
t.isAccess__c = false;
delete service.tokens__r;
insert t;
System.debug('Got request token: '+t.token__c+'('+rp.get('oauth_token')+')');
if(service.authorization_url__c.contains('?')) {
string getAccountURL = 'https://www.gliffy.com/api/1.0/accounts/5023581/users.xml?action=get'+'&oauth_token='+token;
return getAccountURL;
} else {
return service.authorization_url__c+'?oauth_token='+EncodingUtil.urlDecode(t.token__c,'UTF-8')+'&oauth_consumer_key='+service.consumer_key__c;
}
}
public String getAccData(String authUrlName)
{
service = [SELECT request_token_url__c, access_token_url__c, consumer_key__c,consumer_secret__c, authorization_url__c,
(select token__c, secret__c, isAccess__c FROM tokens__r WHERE owner__c=:UserInfo.getUserId() )
FROM OAuthService__c WHERE name = :'Gliffy'];
if(service==null)
{
System.debug('Couldn\'t find Oauth Service '+'Gliffy');
message = 'Service '+'Gliffy'+' was not found in the local configuration';
return null;
}
if(callbackUrl==null)
{
if(ApexPages.currentPage()==null || ApexPages.currentPage().getHeaders().get('Host')==null) {
message = 'No callback page was set and it couldn\'t be generated from Apex context';
System.debug(message);
return null;
}
callbackUrl = EncodingUtil.urlEncode('https://'+ApexPages.currentPage().getHeaders().get('Host')+
Page.CompleteAuth.getUrl(),'UTF-8');
}
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint(authUrlName);
req.setTimeout(12000);
consumerKey = service.consumer_key__c;
consumerSecret = service.consumer_secret__c;
sign(req);
HttpResponse res = null;
res = h.send(req);
String XMLString = res.getBody();
system.debug('Accountdata String:'+XMLString );
return XMLString;
}
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);
}
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');
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);
}
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');
}
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) {
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;
}
}
Using OAuth 1.0 encoded requests for external web service calls Error: signature_invalid
down votefavorite
Please help me.
I have a salesforce requirement that necessitates a callout from Apex to an external web service that receives signed OAuth responses.
I am getting oAuth_token successfully. But after that when I am trying to get data using that oAuth_token I am getting error 'signature_invalid'.
Check getAccData method from code as below.
global class OAuthToken
{
private OAuthService__c service;
private String token;
private String tokenSecret;
private Boolean isAccess = false;
private String verifier;
private String nonce;
private String timestamp;
private String signature;
private String consumerKey;
private String consumerSecret;
private Map<String,String> parameters = new Map<String,String>();
public String message { get; set; }
public String callbackUrl {get; set; }
public void setConsumerKey(String value) { consumerKey = value; }
public void setConsumerSecret(String value) { consumerSecret = value; }
public String newAuthorization(String serviceName)
{
service = [SELECT request_token_url__c, access_token_url__c, consumer_key__c,consumer_secret__c, authorization_url__c,
(select token__c, secret__c, isAccess__c FROM tokens__r WHERE owner__c=:UserInfo.getUserId() )
FROM OAuthService__c WHERE name = :serviceName];
if(service==null)
{
System.debug('Couldn\'t find Oauth Service '+serviceName);
message = 'Service '+serviceName+' was not found in the local configuration';
return null;
}
if(callbackUrl==null)
{
if(ApexPages.currentPage()==null || ApexPages.currentPage().getHeaders().get('Host')==null) {
message = 'No callback page was set and it couldn\'t be generated from Apex context';
System.debug(message);
return null;
}
callbackUrl = EncodingUtil.urlEncode('https://'+ApexPages.currentPage().getHeaders().get('Host')+
Page.CompleteAuth.getUrl(),'UTF-8');
}
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint('https://www.gliffy.com/api/1.0/accounts/5023581/users/nileshbhd5@gmail.com/oauth_token.xml?action=create&description=createuser');//service.request_token_url__c
req.setTimeout(12000);
System.debug('Request body set to: '+req.getBody());
consumerKey = service.consumer_key__c;
consumerSecret = service.consumer_secret__c;
sign(req);
HttpResponse res = null;
res = h.send(req);
String XMLString = res.getBody();
parseXML(XMLString);
System.debug('Response from request token request: ('+res.getStatusCode()+')'+res.getBody());
if(res.getStatusCode()>299) {
message = 'Failed getting a request token. HTTP Code = '+res.getStatusCode()+
'. Message: '+res.getStatus()+'. Response Body: '+res.getBody();
return null;
}
String resParams = serviceName == 'test1234' ?'oauth_token=token&oauth_token_secret=token_secret' : res.getBody();
Map<String,String> rp = getUrlParams(resParams);
OAuth_Token__c t = new OAuth_Token__c();
t.owner__c = UserInfo.getUserId();
t.OAuth_Service__c = service.id;
t.token__c = token;
t.secret__c = tokenSecret;
t.isAccess__c = false;
delete service.tokens__r;
insert t;
System.debug('Got request token: '+t.token__c+'('+rp.get('oauth_token')+')');
if(service.authorization_url__c.contains('?')) {
string getAccountURL = 'https://www.gliffy.com/api/1.0/accounts/5023581/users.xml?action=get'+'&oauth_token='+token;
return getAccountURL;
} else {
return service.authorization_url__c+'?oauth_token='+EncodingUtil.urlDecode(t.token__c,'UTF-8')+'&oauth_consumer_key='+service.consumer_key__c;
}
}
public String getAccData(String authUrlName)
{
service = [SELECT request_token_url__c, access_token_url__c, consumer_key__c,consumer_secret__c, authorization_url__c,
(select token__c, secret__c, isAccess__c FROM tokens__r WHERE owner__c=:UserInfo.getUserId() )
FROM OAuthService__c WHERE name = :'Gliffy'];
if(service==null)
{
System.debug('Couldn\'t find Oauth Service '+'Gliffy');
message = 'Service '+'Gliffy'+' was not found in the local configuration';
return null;
}
if(callbackUrl==null)
{
if(ApexPages.currentPage()==null || ApexPages.currentPage().getHeaders().get('Host')==null) {
message = 'No callback page was set and it couldn\'t be generated from Apex context';
System.debug(message);
return null;
}
callbackUrl = EncodingUtil.urlEncode('https://'+ApexPages.currentPage().getHeaders().get('Host')+
Page.CompleteAuth.getUrl(),'UTF-8');
}
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint(authUrlName);
req.setTimeout(12000);
consumerKey = service.consumer_key__c;
consumerSecret = service.consumer_secret__c;
sign(req);
HttpResponse res = null;
res = h.send(req);
String XMLString = res.getBody();
system.debug('Accountdata String:'+XMLString );
return XMLString;
}
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);
}
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');
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);
}
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');
}
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) {
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;
}
}