Recently I worked on a project that involved integrating with social networking and jobs websites like Elance. These days almost all major services that allow applications to access users' data, perform authorization/authentication using OAuth1.0 or OAuth2. OAuth2 compared to OAuth1 is very easy to implement. OAuth1 involves generating nonce,timestamp,signaturebase and signing the request with any algorithm like HMAC-SHA1 and appending data to query string of URL and passing in Authorization header of HTTP. OAuth2 removed all these requirements. Following is OAuth2 process in a nutshell
Lets start by creating a class named OAuth2 that will hold variables that is common to all OAuth2 consumers.
namespace Usmani.OAuth2
{
public abstract class OAuth2
{
public string AuthorizationUrl { get; protected set; }
public string AccessTokenUrl { get; protected set; }
public string RedirectUrl { get; protected set; }
public string AuthorizationCode { get; protected set; }
public string ClientId { get; private set; }
public string ClientSecret { get; private set; }
public string AccessToken { get; protected set; }
public string RefreshToken { get; protected set; }
protected string AuthorizationCodeParameter { get; set; }
protected string ClientIdParameter { get; set; }
protected string ClientSecretParameter { get; set; }
public OAuth2(string clientId, string clientCode,string rUrl)
{
this.ClientId = clientId;
this.ClientSecret = clientCode;
this.RedirectUrl=rUrl;
}
protected string GetFullAuthorizationUrl(string queryStringToAppend)
{
return AuthorizationUrl + "?" + ClientIdParameter + "=" + ClientId + "&" + queryStringToAppend;
}
protected void SetAuthorizationCode(string queryStringPart)
{
NameValueCollection nvc = HttpUtility.ParseQueryString(queryStringPart);
this.AuthorizationCode = nvc[AuthorizationCodeParameter];
}
protected string GetAccessTokenResponse(string queryStringToAppend, string postDataToAppend)
{
string fullUrl = AccessTokenUrl + "?" + queryStringToAppend;
string postData = AuthorizationCodeParameter+"=" + HttpUtility.UrlEncode(AuthorizationCode);
postData += "&" + ClientIdParameter + "=" + HttpUtility.UrlEncode(ClientId);
postData += "&" + ClientSecretParameter + "=" + HttpUtility.UrlEncode(ClientSecret);
postData += "&" + postDataToAppend;
return HttpClient.postFormData(fullUrl,postData);
}
public abstract void GetAccessToken();
public abstract void UserRedirectedAfterAuthorization(string queryPart);
}
}
Now we will create class specific to Elance OAuth2 which will inherit from OAuth2.
namespace Usmani.OAuth2
{
public class ElanceOAuth2 : OAuth2
{
public ElanceOAuth2(string apiKey,string consumerSecret,string redUrl)
: base(apiKey,consumerSecret,redUrl)
{
this.AuthorizationUrl = "https://api.elance.com/api2/oauth/authorize";
this.AccessTokenUrl = "https://api.elance.com/api2/oauth/token";
this.RedirectUrl = "http://yourredirecturl";
this.ClientIdParameter = "client_id";
this.ClientSecretParameter = "client_secret";
this.AuthorizationCodeParameter = "code";
}
public override void GetAccessToken()
{
string response = GetAccessTokenResponse(string.Empty, "grant_type=authorization_code");
//Elance return response in Json format.I am using Newtonsoft Json library here
JToken jobj = JToken.Parse(response);
jobj = jobj.Value<JObject>("data");
AccessToken = jobj.Value<string>("access_token");
RefreshToken = jobj.Value<string>("refresh_token");
}
public override void UserRedirectedAfterAuthorization(string queryPart)
{
SetAuthorizationCode(queryPart);
}
}
}
GUI Part
We can perform following part in our GUI to allow user to login to elance and perform authorization and authentication.
ElanceOAuth2 elApi=new ElanceOAuth2("YOUR_API_KEY","CONSUMER_SECRET","REDIRECT_URL");
WebBrowser brw=new WebBrowser();
this.Controls.Add(brw);
brw.Navigated+=new WebBrowserNavigatedEventHandler(browser_Navigated);
brw.Navigate(elApi.GetFullAuthorizationUrl("scope=basicInfo&response_type=code"));
public void browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
if (e.Url.AbsoluteUri.StartsWith(el.RedirectUrl))
{
elApi.UserRedirectedAfterAuthorization(e.Url.Query);
}
}
1) Redirect user to Authorization url passing client_id and redirect_url in query parametersIn this blog post I will implement OAuth2 for Elance in a desktop C# app. Elance provide you API Key (client_id) and secret code (client_secret) when you apply for new API keys.
2) If user authenticates successfully through service provider it will redirect user to the redirect_url passed with authorization access code in query parameters.
3) After getting authorization access code you exchange this to receive access token. You make a POST HTTP request to a URL passing client_id , client_secret and authorization code.
4) After access token is received you can call API of service provider using that access token.
Lets start by creating a class named OAuth2 that will hold variables that is common to all OAuth2 consumers.
namespace Usmani.OAuth2
{
public abstract class OAuth2
{
public string AuthorizationUrl { get; protected set; }
public string AccessTokenUrl { get; protected set; }
public string RedirectUrl { get; protected set; }
public string AuthorizationCode { get; protected set; }
public string ClientId { get; private set; }
public string ClientSecret { get; private set; }
public string AccessToken { get; protected set; }
public string RefreshToken { get; protected set; }
protected string AuthorizationCodeParameter { get; set; }
protected string ClientIdParameter { get; set; }
protected string ClientSecretParameter { get; set; }
public OAuth2(string clientId, string clientCode,string rUrl)
{
this.ClientId = clientId;
this.ClientSecret = clientCode;
this.RedirectUrl=rUrl;
}
protected string GetFullAuthorizationUrl(string queryStringToAppend)
{
return AuthorizationUrl + "?" + ClientIdParameter + "=" + ClientId + "&" + queryStringToAppend;
}
protected void SetAuthorizationCode(string queryStringPart)
{
NameValueCollection nvc = HttpUtility.ParseQueryString(queryStringPart);
this.AuthorizationCode = nvc[AuthorizationCodeParameter];
}
protected string GetAccessTokenResponse(string queryStringToAppend, string postDataToAppend)
{
string fullUrl = AccessTokenUrl + "?" + queryStringToAppend;
string postData = AuthorizationCodeParameter+"=" + HttpUtility.UrlEncode(AuthorizationCode);
postData += "&" + ClientIdParameter + "=" + HttpUtility.UrlEncode(ClientId);
postData += "&" + ClientSecretParameter + "=" + HttpUtility.UrlEncode(ClientSecret);
postData += "&" + postDataToAppend;
return HttpClient.postFormData(fullUrl,postData);
}
public abstract void GetAccessToken();
public abstract void UserRedirectedAfterAuthorization(string queryPart);
}
}
Now we will create class specific to Elance OAuth2 which will inherit from OAuth2.
namespace Usmani.OAuth2
{
public class ElanceOAuth2 : OAuth2
{
public ElanceOAuth2(string apiKey,string consumerSecret,string redUrl)
: base(apiKey,consumerSecret,redUrl)
{
this.AuthorizationUrl = "https://api.elance.com/api2/oauth/authorize";
this.AccessTokenUrl = "https://api.elance.com/api2/oauth/token";
this.RedirectUrl = "http://yourredirecturl";
this.ClientIdParameter = "client_id";
this.ClientSecretParameter = "client_secret";
this.AuthorizationCodeParameter = "code";
}
public override void GetAccessToken()
{
string response = GetAccessTokenResponse(string.Empty, "grant_type=authorization_code");
//Elance return response in Json format.I am using Newtonsoft Json library here
JToken jobj = JToken.Parse(response);
jobj = jobj.Value<JObject>("data");
AccessToken = jobj.Value<string>("access_token");
RefreshToken = jobj.Value<string>("refresh_token");
}
public override void UserRedirectedAfterAuthorization(string queryPart)
{
SetAuthorizationCode(queryPart);
}
}
}
GUI Part
We can perform following part in our GUI to allow user to login to elance and perform authorization and authentication.
ElanceOAuth2 elApi=new ElanceOAuth2("YOUR_API_KEY","CONSUMER_SECRET","REDIRECT_URL");
WebBrowser brw=new WebBrowser();
this.Controls.Add(brw);
brw.Navigated+=new WebBrowserNavigatedEventHandler(browser_Navigated);
brw.Navigate(elApi.GetFullAuthorizationUrl("scope=basicInfo&response_type=code"));
public void browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
if (e.Url.AbsoluteUri.StartsWith(el.RedirectUrl))
{
elApi.UserRedirectedAfterAuthorization(e.Url.Query);
}
}
Whats up very cool blog!! Man .. Beautiful .. Superb ..
ReplyDeleteI'll bookmark yiur blog and take the feeds additionally?
I'm satisfied to find a lot of helpful info right here within the post, we'd like develop more techniques on this regard, thank
you for sharing. . . . . .