Wednesday, December 5, 2012

LinkedIn REST URL (Step 3 - Obtain Access Token)

Hello again,

My last post was Step 2 for obtaining authorization http://dailyprogrammingtalk.blogspot.com/2012/11/linkedin-rest-url-step-2-obtain.html

We will go through the final step of OAuth, that is obtaining an access token, so we can make API calls.
Using the new OAuth token and verfier we obtained from Step 2, make a POST request to:

https://api.linkedin.com/uas/oauth/requestToken

You might notice that the path of the URL is the same as the one we used in Step 1. There's no typo. Don't worry :)

To make the POST request, you can still use the same code in Step 1, but you need to pass in the OAuth token, verifier, and token secret from Step 2:

OAuthBase oauth = new OAuthBase();
string linkedinUrl = "https://api.linkedin.com/uas/oauth/requestToken"
string url = String.Empty;
string urlParameters = String.Empty;
string timeStamp = oauth.GenerateTimeStamp();
string nonce = oauth.GenerateNonce();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(linkedinUrl);
request.Method = "POST";
string signature = oauth.GenerateSignature(new Uri(linkedinUrl), consumerKey, consumerSecret, step2Tokenstep2TokenSecret, "POST", timeStamp, nonce, out url, out urlParameters);

But then, for the OAuth library I am using, the GenerateSignature method does not accept verifier in the arguments. In case you are curious which OAuth library I use, it's from http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs
So, I need to make modifications to the GenerateSignatureBase method to accept verifier in the arguments and add the verifier to the list of QueryParameter like below:

public string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, string httpMethod, string timeStamp, string verifierstring nonce, string signatureType, out string normalizedUrl, out string normalizedRequestParameters)
{
  ...
  List<QueryParameter> parameters = GetQueryParameters(url.Query);
  ...

  if (!String.IsNullOrEmpty(verifier))
  {
    parameters.Add(new QueryParameter("oauth_verifier", verifier));
  }
  ...
}

After making the changes above, add the extra "verifier" argument to the GenerateSignature methods that make a call to the GenerateSignatureBase method.
After that, you can pass in the verifier value:

string signature = oauth.GenerateSignature(new Uri(linkedinUrl), consumerKey, consumerSecret, step2Tokenstep2TokenSecret, "POST", timeStamp, step2Verifier, nonce, out url, out urlParameters);

Next is your authorization header needs to contain the OAuth token and verifier from Step 2:

StringBuilder header = new StringBuilder("OAuth ");
header.AppendFormat("oauth_consumer_key=\"{0}\"", consumerKey);
header.AppendFormat(", oauth_signature_method=\"{0}\"""HMAC-SHA1");
header.AppendFormat(", oauth_signature=\"{0}\"", MsSecurity.Encoder.UrlEncode(signature));
header.AppendFormat(", oauth_nonce=\"{0}\"", nonce);
header.AppendFormat(", oauth_timestamp=\"{0}\"", timeStamp);
header.AppendFormat(", oauth_version=\"{0}\"""1.0");
header.AppendFormat(", oauth_token=\"{0}\"", step2Token);
header.AppendFormat(", oauth_verifier=\"{0}\"", step2Verifier);

Make the POST request and you will receive the access token and token secret in the response:
oauth_token=efgh&oauth_token_secret=def456

From now on, you can forget about everything you stored from Step 1 and 2. The values of oauth_token and oauth_token_secret from Step 3 are the only ones you need to save because you use them in every API call you make.

Parse them out:

string step3Token = Regex.Match(token, @"oauth_token=([^&]+)").Groups[1].Value,
string step3TokenSecret = Regex.Match(token, @"oauth_token_secret=([^&]+)").Groups[1].Value

Now, to test if your oauth_token and oauth_token secret values work, make a GET request to:

http://api.linkedin.com/v1/people

For the signature and authorization header, do the following:

string signature = oauth.GenerateSignature(new Uri(linkedinUrl), consumerKey, consumerSecret, step3Tokenstep3TokenSecret, "POST", timeStamp, nonce, out url, out urlParameters);

StringBuilder header = new StringBuilder("OAuth ");
header.AppendFormat("oauth_consumer_key=\"{0}\"", consumerKey);
header.AppendFormat(", oauth_signature_method=\"{0}\"""HMAC-SHA1");
header.AppendFormat(", oauth_signature=\"{0}\"", MsSecurity.Encoder.UrlEncode(signature));
header.AppendFormat(", oauth_nonce=\"{0}\"", nonce);
header.AppendFormat(", oauth_timestamp=\"{0}\"", timeStamp);
header.AppendFormat(", oauth_version=\"{0}\"""1.0");
header.AppendFormat(", oauth_token=\"{0}\"", step3Token);

Notice that the verifier is no longer needed.
So, after making the GET request, you will see a response similar to:

<?xml version= "1.0" encoding="UTF-8" standalone="yes"?>
<person>
  <first-name>Kirsten</first-name>  
  <last-name>Jones</last-name>
  <headline>Developer Advocate at LinkedIn</headline>
  <site-standard-profile-request>    
    <url>http://www.linkedin.com/profile?viewProfile=&amp;key=3639896&amp;authToken=JdAa&amp;authType=name&amp;trk=api*a119686*s128146*</url>
  </site-standard-profile-request>
</person>

That's all there is to it for OAuth authentication.
Please feel free to leave comments.

No comments:

Post a Comment