If you haven’t heard of OAuth or OpenID you have most certainly used it in day to day life. Have you provided your google username/password and logged in to StackOverflow or used your WordPress.com account to post comments on someone’s blog or used third party Twitter clients whom you have given permission to use your Twitter account or used Facebook to post comments on some tech blog site? If answer to any of the above is a Yes, you have seen OAuth or OpenID in action.
This article is published from the DNC .NET Magazine – A Free High Quality Digital Magazine for .NET professionals published once every two months. Subscribe to this eMagazine for Free
What is OpenID and OAuth
At a 100K feet both are Authentication protocols that work towards a dream on the web, that is - Single Sign On. Basic premise being, instead of having to remember a different username and password for every Application we visit on the internet, we have a dedicated Authentication provider with whom we register our user name and password. Applications (aka Relying Party) redirect us to this provider for authentication and after a successful authentication, the provider passes back a token to the replying party who initiated the request. The target Application then uses the token to verify the identity of the person and provide further access to Application Features.
OAuth was initiated by Twitter when they were working on building their OpenID implementation for Twitter API. Their need was more towards controlling what features to make available based on Authentication Types offered at the Provider and those sought by the relying party.
For example when a Relying party signs up for Twitter Authentication access, they can request for a Read-Only connection (this gives them read permissions to a user’s stream), a Read/Write connection (this gives them read and write permissions on a user’s stream) and a Read/Write with Direct Messages connection (giving them maximum possible access to user’s data). Thus, when a user authenticates with Twitter over OAuth, they are told exactly what kind of access they are providing.
On the other hand, OpenID simply ensures that you are who you claim to be by verifying your username and password. It has no way of controlling feature access.
In even simpler terms, OpenID is about Authentication, OAuth is about Authentication and Authorization (for features at the Provider).
The diagram above demonstrates the Authentication process for an OAuth provider. The overall workflow is as follows:
1. Application (Relying Party) registers with OAuth provider and obtains an Application specific key (secret). This is a one-time process done offline (not shown in above image).
2. Next the Application (Relying Party) has to pass the Application key to the provider every time it intends to authenticate someone.
3. User of the Relying Party needs to be registered with the Provider (again a one-time offline process)
4. Every authentication request directs the user to the Auth Provider’s site. The user enters the Username and Password that they obtained by creating an account with the provider. The Provider verifies the account credentials, then it matches the Application Key and provides a token back to the Relying Party with which only the Authorized actions can be performed.
I have a bunch of references up on the Github page for this article feel free to go through them if you would like to understand these protocols in greater depth.
Twitter OAuth and ASP.NET
Today we will learn how to use ASP.NET’s integration of the DotNetOpenAuth library that allows you to integrate using Twitter/Facebook/Google Id and other similar providers. Most examples on the net kind of stop after the Authentication piece and don’t elaborate on how you can use it further. Today we’ll dig a little deeper and see what it takes to go beyond the default implementation provided by ASP.NET and extract further information from our OAuth provider i.e. Twitter.
Getting Started – Registering an Application with Twitter
As we saw above there are four steps, let’s get started at Step 1, registering our application with Twitter.
1. Navigate to http://dev.twitter.com/ and click on the Sign In (top right)
2. Log in using your Twitter credentials. Hover over your Account Info and Click on ‘My Applications’
This will take you to the Applications page where you can register a new Twitter Application. This is going to be the Relying Party.
3. Next click on ‘Create a new application’ and navigate to the new application page. It asks for the following details
- Provide proper Name and Description these will come up every time a new user Authenticates at your site.
- Specify a callback URL that would point to a site address. You can point it to http://127.0.0.1/
- Notice the Website is setup as localhost address. This is for testing purposes. Once you have the application going set it back to the actual website.
- Scroll down, read the Developer Rules of Road carefully and click on Yes, I agree. Fill in the captcha and click on ‘Create your Twitter Application’.
4. Twitter will navigate to a page similar to the following
Next click on the ‘Create my access token’ to generate the access token that our app will be using along with the Consumer Key and Consumer secret. Remember all three values shouldn’t be shared.
Also notice the Access Level is set to Read-only by default. For our application we need Read-only access, but if you would like to post tweets on the User’s behalf you can modify the permissions from the ‘Settings’ tab. Remember to regenerate the Access Token if you change the Access Level.
With that we are ready with Step 1. Let’s build the barebones of our Application now.
Using Registration information to Authenticate with Twitter
1. Create a new ASP.NET MVC Web Application and select the Internet Template.
2. Open the AuthConfig.cs from the App_Start folder and uncomment the code to register the Twitter Client
public static void RegisterAuth()
{
OAuthWebSecurity.RegisterTwitterClient(
consumerKey: "",
consumerSecret: "");
}
3. Put the keys in web.config and update the above code to get the values from ConfigurationSettings.
4. Update the project’s properties to run the application on the same port as specified in the URL above
5. That’s pretty much it. Run the Application and click on the Log On Link to be presented with the new Login page
As you can see we have a button to log in to Twitter. Let see what happens when we click on it.
6. On clicking twitter the application gets routed to a Twitter page
Here you will notice the following
- On the right hand side is information about your app that you provided while creating it, including the URL.
- Above the Username or email address text box is a list of things that the requesting application can do, in our case it can ‘Read Tweets from your timeline’ and ‘See who you follow’.
Note: This is why when using OAuth you have to be careful to request for only as much information as you need. If your app seems terribly nosy, the end user may choose not to allow give you permissions.
- On successful authentication you will see a brief flash of ‘redirection in progress’ message and the user will be sent back to our application again.
7. For the first time log in, we will be requested to register via the following page
8. Once you Register, you are logged in as an Authenticated user for the application
9. With this we have completed Step 2, 3 and 4 of the OAuth process and this is where most demo applications draw a line.
Hacking into the OAuth Client
Since we have a working Twitter Authentication going, let us see what it takes to use the Twitter Avatar in our application. Once authenticated we expect the entire User profile to be returned to us. This profile in the Authentication result as ExtraData. However if we break in the AccountController soon after the log in, we will see ExtraData only has a handful of values that does not include the Avatar URL.
What now? After some head-scratching I concluded that there was no other option but to create a custom OAuth client for ourselves to get the required data. Essentially the default TwitterClient class that the ASP.NET team is provided is barebones to say the least.
Overriding the default TwitterClient to build one of our own
To start off with I’ve referred to the TwitterClient class from DotNetOpenAuth’s Github repository (yay for OSS), and copied the entire implementation over into a new class called TwitterClientEx.
After copying the contents over, we will need to copy over some helper methods for formatting and escaping characters, these are mysteriously implemented as internal methods.
The code in context refers to the internal static extension class DictionaryExtensions that has some helper methods. We also bring in three helper methods LoadXDocumentFromStream, CreateUntrustedXmlReaderSettings and EscapeUriDataStringRfc3986. All these methods are implemented in the TwitterClient or OAuthClient classes but are unfortunately not reusable.
With the above in place we can register it in AuthConfig.cs using the following code.
OAuthWebSecurity.RegisterClient(new TwitterClientEx(
consumerKey: ConfigurationManager.AppSettings["consumerKey"],
consumerSecret: ConfigurationManager.AppSettings["consumerSecret"]), "Twitter", null);
//OAuthWebSecurity.RegisterTwitterClient(
// consumerKey: ConfigurationManager.AppSettings["consumerKey"],
// consumerSecret: ConfigurationManager.AppSettings["consumerSecret"]);
As we can see above, we have commented out the RegisterTwitterClient static method and instead used the generic RegisterClient method and passed in our own TwitterClientEx instance. The second parameter is simply the Label by which the Client is referred to.
However so far we have merely copied the TwitterClient so we still don’t have our Avatar URL. To load the Avatar and other User Data let’s revisit the VerifyAuthenticationCore method in TwitterClientEx.
The default code has the only the following parameters extracted from the XML Document returned by Twitter.
extraData.AddDataIfNotEmpty(document, "name");
extraData.AddDataIfNotEmpty(document, "location");
extraData.AddDataIfNotEmpty(document, "description");
extraData.AddDataIfNotEmpty(document, "url");
However, instead of the above hardcoding if we have the following Loop then we can extract the complete set of values in the ExtraData dictionary.
XDocument document = LoadXDocumentFromStream(responseStream);
foreach (var node in document.Descendants("user").Nodes<XElement>())
{
if (node.NodeType == XmlNodeType.Element)
{
extraData.AddDataIfNotEmpty(document,
((XElement)(node)).Name.LocalName);
}
}
Now that we have retrieved the data required let’s see how we can save it for ourselves.
Saving ‘ExtraData’
By default the ViewModel objects and Data Model objects are bunched together in Model\UserAccounts.cs file that has multiple class files. Even though I dislike multiple classes per file, I’ll ignore it for the moment and we’ll simply extract the UserProfile class to a new Model\Account folder.
In this folder we will add our ExtraData class. The POCO looks as follows
public class ExtraData
{
public int Id { get; set; }
public string AccessToken { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public string Description { get; set; }
public string Url { get; set; }
public UserProfile ParentUserProfile { get; set; }
public int UserProfileUserId { get; set; }
}
For brevity we will refrain from saving all the 35 possible values that can be returned in ExtraData resulting from the Authentication.
The POCO has a parent-child relationship established with the UserProfile object.
In the AccountController, the ExternalLoginCallback method is called after user returns from Twitter’s Authentication page. Here the result variable retrieves all the information returned after a successful Authentication. We populate our ExtraData POCO from the result here.
As a next step the boilerplate checks if the user exists locally and for first time access the code redirects user to a confirmation page and requests for UserId to be used in this application. This is where we can update the ExtraData poco into the database. However we need to pass all the data via the RegisterExternalLoginModel to the ExternalLoginConfirmation page. To do this we update the RegisterExternalLoginModel to carry ExtraData with it.
public class RegisterExternalLoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
public string ExternalLoginData { get; set; }
public ExtraData AuthenticationProviderData { get; set; }
}
In the View we add a set of Labels and Hidden Variables and an Image to represent the ExtraData on the View. There we have it, Authentication with Avataar.
Once we click Register, the ExtraData is saved in the Application’s database and we can retrieve and use it anytime we want.
Example Usage
Now that we have seen how to Authenticate against Twitter or other OAuth providers we can use this technique for creating a Disqus like commenting system or a StackOverflow style Forum or any ‘Socially connected’ site we want.
The default implementation that comes out of the box with ASP.NET is a little light for direct practical usage but as we saw it’s not really difficult to extend it to our benefit.
Conclusion
We saw how we can build our ASP.NET application to use Twitter for Authentication. The usage scenario discussed was only the tip of the iceberg. DotNetOpenAuth is a powerful library and hidden under the lightweight wrappers created by the ASP.NET team is a real powerhouse framework that can take care of a lot of your Social Media integration requirements.
Download the entire source code of this article (Github)
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @
sumitkm or email him at sumitkm [at] gmail