You need to sign in to do that
Don't have an account?

OAuth in Winter '10
Has anybody succesfully used OAuth for obtaining a sessionId for use with the API in Winter '10?
I've been able to get so far as to generate a valid OAuth access token, but I haven't yet been able to use that access token to get an API session id and I suspect the documentation may not be accurate or complete.
A few observations I've made:
- The documentation says the url is https://login.salesforce.com/services/OAuth/type/api-version. Where type is "c" for the Partner WSDL and "u" for the enterprise WSDL. This is the reverse of the normal SOAP API, and I assume it is a mistake, but can't verify since I can't get a session id.
- The documentation says that "authorization header must have the following parameters" when referring to the request to obtain the session. I take this to mean that one must use the Authorization HTTP header and not POST parameters to obtain the session id. However, I've not had success with either.
- If I do not use the authorization header and post the oauth parameters in the body, I get a response of LOGIN_OAUTH_INVALID_DSIG, indicating a bad signature. Even though I'm using the same code to sign the request as I do for generating the request and access tokens.
- If I instead use the Authorization HTTP header I get the error LOGIN_OAUTH_METHOD_NOT_SUPPORTED indicating I must use http POST, even though I already am. Note, in this case the post body is empty.
If anybody has got this last step working it would be very helpful to know how you constructed the request. Did you use the authorization header? What were the contents of the POST? Did you do anything special when generating your signature, in particular the generation of the OAuth Signature Base String and the key used for the signature (I'm using both the consumer and token secrets per the spec).
Thanks,
George
I got this working, the documentation definitely needs to be updated and it seems salesforce is not compliant with the OAuth spec in regards to API requests.
Here's a quick summary of how I got it working:
To isolate this futher, I tried to login to the frontdoor at https://login.salesforce.com to see what would happen. It turns out it let me right in using OAuth POST parameters, not the Authorization header, and sent me back a reply with session cookies and HTML to redirect to /home/home.jsp.
Once I knew that worked, I tried the API url again. Because I was getting a bad signature error, I decided to use the same signature I used to go into the front door and it worked! This means that to compute the signature for generating a session id for the API you need to use the a server URL of "https://login.salesforce.com" and not the actual url you are posting to (e.g. "https://login.salesforce.com/services/OAuth/u/17.0" ) when constructing your OAuth Signature Base String. This is technically a violation of the OAuth spec.
I also verified that the "u" and "c" are swapped in the documentation. Use the "u" if you want the partner WSDL.
So in summary to use OAuth with the API:
1. Use HTTP Post to send your oauth parameters and not the authorization header as it states in the documentation.
2. Use "u" for partner API and "c" for enterprise API (as is normally the case), not what it states in the documentation.
3. Use "https://login.salesforce.com" as your request URL when generating your OAuth Signature Base String, do not use the actual request URL (e.g. "https://login.salesforce.com/services/OAuth/u/17.0" ).
George
All Answers
I got this working, the documentation definitely needs to be updated and it seems salesforce is not compliant with the OAuth spec in regards to API requests.
Here's a quick summary of how I got it working:
To isolate this futher, I tried to login to the frontdoor at https://login.salesforce.com to see what would happen. It turns out it let me right in using OAuth POST parameters, not the Authorization header, and sent me back a reply with session cookies and HTML to redirect to /home/home.jsp.
Once I knew that worked, I tried the API url again. Because I was getting a bad signature error, I decided to use the same signature I used to go into the front door and it worked! This means that to compute the signature for generating a session id for the API you need to use the a server URL of "https://login.salesforce.com" and not the actual url you are posting to (e.g. "https://login.salesforce.com/services/OAuth/u/17.0" ) when constructing your OAuth Signature Base String. This is technically a violation of the OAuth spec.
I also verified that the "u" and "c" are swapped in the documentation. Use the "u" if you want the partner WSDL.
So in summary to use OAuth with the API:
1. Use HTTP Post to send your oauth parameters and not the authorization header as it states in the documentation.
2. Use "u" for partner API and "c" for enterprise API (as is normally the case), not what it states in the documentation.
3. Use "https://login.salesforce.com" as your request URL when generating your OAuth Signature Base String, do not use the actual request URL (e.g. "https://login.salesforce.com/services/OAuth/u/17.0" ).
George
Gscott,
thanks for putting this together and for uncovering a couple problems with our implementation. Our goal is to comply completely with the specification.
We are fixing our login method to accept either https://login.salesforce.com or the actual URL (e.g. https://login.salesforce.com/services/OAuth/u/17.0) - the fix should be in production by Thursday 10/29. We will also correct our documentation to correct the reversal of "u" and "c".
Can you explain what you mean by #1 (use POST to pass parameters, not the Authorization header)? We don't believe this should be the case.
Thanks,
-Pete
Pete,
Great to hear this is getting fixed so quickly. I will try it out once again after the fix goes live.
In regards to #1 in my post. In the section of the documentation that discusses how to access salesforce using the consumer application and the API it states that the required parameters must be placed in the "authorization header". This is different from the documentation that describes how to obtain the request and access tokens. So I took that to mean one *must* use the authorization HTTP headers (per the OAuth spec), and not put the parameters in the POST body using application/x-www-form-urlencoded encoding.
However, when I attempted to POST to the login url using the HTTP Authorization header I always received an error saying invalid method. Note, that since there is no data to post in this case, the body of the POST is always empty (which may be the problem). I was never able to get this to work, even after making the change to compute the signature using "https://login.salesforce.com". Since posting the oauth parameters in the body did work, that is what I was recommending in my post.
It is very possible that I made a mistake in constructing my Authorization header, I didn't spend a lot of time diagnosing it further after I got the POST parameters to work with the login url. Since you can use POST parameters I would recommend changing the documentation to remove the "authorization headers" section and make it similar to the text on obtaining request and access tokens.
It would be useful if the documentation (or developer wiki) included sample HTTP headers/body for the various OAuth request types and a sample consumer key/secret. This would make it much easier for developers to get OAuth up and running.
I just added an idea which references a blog post with some ideas on how to make it easier to debug OAuth:
http://ideas.salesforce.com/article/show/10098488/Make_it_easier_to_debug_Remote_Access_Applications_OAuth
George
Hi,
I'm running into similar issues. Using the oauth ruby gem, I've managed to successfully get an access token from Salesforce. However, when I try to get a session id using that access token, I get an odd error.
# after Salesforce OAuth redirects back to my client
rt = OAuth::RequestToken.new @consumer, session[:request_token], session[:request_secret]
at = rt.get_access_token :oauth_verifier => params[:oauth_verifier]
res = at.post 'https://login.salesforce.com/'
puts res.body
# => <response><faultcode>1700</faultcode><error>Failed: Signature Invalid</error></response>
Here's a dump of the actual POST to 'https://login.salesforce.com/'
---!ruby/object:Net::HTTP::Post
body:
oauth_nonce=4vwwHOp5ixWKNrPU6qgoPHYS03agKYC5OJARO9CqQU&
oauth_timestamp=1258402353&
oauth_signature_method=HMAC-SHA1&
oauth_signature=2i93aV6j%2bl9pDSR2d5Dyk5rkbFY%3d&
oauth_token=<REDACTED>&
oauth_consumer_key=<REDACTED>&
oauth_version=1.0
header:
accept:
- "*/*"
content-type:
- application/x-www-form-urlencoded
user-agent:
- OAuth gem v0.3.6
content-length:
- 0
method: POST
path: /
request_has_body: true
response_has_body: true
Per my reading, this seems to match what's expected at: https://na7.salesforce.com/help/doc/user_ed.jsp?section=help&target=remoteaccess_authenticate.htm&loc=help&hash=access_data
Any help would be appreciated.
Thanks,
Gerad
Simon,
Thanks for getting back to me so quickly!
Good eye. The OAuth library that I am using does indeed do wacky things to the 'Content-Length' header. However, it gets ignored by the downstream http library.
Here's what actually gets written into the connection:
POST / HTTP/1.1
Accept: */*
Connection: close
Content-Type: application/x-www-form-urlencoded
User-Agent: OAuth gem v0.3.6
Content-Length: 381
Host: login.salesforce.com
oauth_nonce=WvO4joJXFVajdphR1UthYD8O2QmXtz4SWDO6f5jUE&oauth_timestamp=1258411747&oauth_signature_method=HMAC-SHA1&oauth_signature=7zbHKx%2b0EM4T8PrG7KIAILHtDUI%3d&oauth_token=<REDACTED>&oauth_consumer_key=<REDACTED>&oauth_version=1.0
So it seems the content-length being 0 in my earlier posting was a bit of a red herring. Sorry about that! Any other thoughts?
Gerad
Gerad,
Since my original post, I have done more testing of OAuth with salesforce and I get intermittent invalid signature errors even when requesting access tokens. I have verified this behavior with different OAuth client libraries, so they have some type of issue still on their back end. Because of this, I decided not to use OAuth in our applications until this issue is resolved.
I filed a case with support a few weeks ago and it has been reproduced internally and is currently with salesforce tier 3 support. I would stay clear of OAuth until they get to the bottom of this issue.
George
George,
Thanks so much. I'll take your advice. It's been quite an adventure getting OAuth to work.
Gerad
P.S. Your posts definitely helped a ton with getting as far as I did. Thanks for trailblazing.
try to remove the trailing slash to the input to your library method, i.e.
res = at.post 'https://login.salesforce.com'
that should fix the signature base string that salesforce is expecting, which hopefully will fix the generated dsig.
normalizedUrl += url.AbsolutePath;if (httpMethod.ToUpper() == "POST"){ normalizedUrl = normalizedUrl.Substring(0, normalizedUrl.LastIndexOf("/")); }
Hi,
I want to send leads to salesforce api from a different web application using php scripts. Can ny1 provide temme how i can authorize, autheticate and get the callback url, or some documentation I can refer.