In this post, you’ll learn how to integrate OAuth 1.0a to access an external service from an app for Office.
In the course of a recent development project, I was asked to show how apps for Office can be used to simplify citing sources in a Word document. The requirements were:
· The app should connect to Zotero (a free and open-source reference management software to manage bibliographic data) on behalf of the user.
· With one click, the app should pull down the user’s stored sources and insert the citations into a Word document.
You can download the Zotero web service code sample to preview what I’m going to talk about.
Figure 1. Zotero Citation Assistant app user interface
Zotero is pretty easy to work with. Simply download the Firefox extension or stand-alone program, and you can begin storing and organizing your research sources. You can start with even a minimal amount of information—for example, the ISBN numbers of the sources you want to manage.
Although you can pull the citation directly from Zotero’s program to the clipboard or save them as a file, Zotero really shines with its ease of integrating into other applications. Zotero provides an API that can be used to connect a third-party app to their system to retrieve and process a user’s research source data. Because that data needs to be secure, Zotero uses OAuth 1.0a to authorize the app to act on behalf of the user.
What is OAuth, and how do you use it use it with apps for Office?
OAuth is a standard for web authorization. It allows a “client” (what we developers call a server, or service, that we are implementing) to access “server resources” (for example, Facebook data) for a “resource owner” (the user). It does this by having the resource owner log on to the server and grant the client authorization. The server then grants the client a token that can be used in further calls to the server’s API. For this blog post, I’m going to focus on OAuth 1.0a, since that’s the version Zotero currently uses.
Because we need to get cross-domain resources from Zotero, the web browser same-origin policy becomes an issue. Generally, JSONP (JSON with padding) would be used as a solution to get cross-domain resources; however, JSONP is not supported by many secure web services (including Zotero) due to potential security flaws (see Defining Safer JSON-P). Consequently, you’ll need a web service—I chose Windows Communication Foundation (WCF)—to place the actual calls to Zotero and return results to the user’s browser, as well as server-side logic to handle the initial authorization. We use a WCF REST service in the Zotero code sample.
I also chose to use DotNetOpenAuth and the extensions for ASP.NET, as these greatly simplify OAuth implementation. DotNetOpenAuth is an OAuth library for use in .NET applications that provides a well-known and simple way to integrate OAuth into applications. Since the new Visual Studio web application templates use DotNetOpenAuth, they are already set up for OAuth. Thus, using the library means better and easier integration with any existing ASP.NET web applications that you may have.
Using DotNetOpenAuth OAuth is a breeze
So how simple is it to get up and running with the ASP.NET extension of DotNetOpenAuth? It can be very straightforward. In this case, it’s less than 200 lines of code! There is a little bit of setup to do if you don’t have an already existing web application. The Apps for Office template gives you two projects, an app for Office project and a website. You’ll first need to convert the website to a web application. To do this, right-click the project and select Convert to web application. Once the website is converted, you can host the web service in a web app (This is the preferred way of hosting WCF services in IIS). You can then also replace the Home.html file with an .aspx file (Home.aspx in the code sample).
Now we’re ready to get coding! For the code sample, I followed conventions for OAuth 1.0 clients that already exist in the DotNetOpenAuth ASP.NET extension. The following is located in the ZoteroClient.cs code file. Simply create a class and have it inherit from DotNetOpenAuth.AspNet.Clients.OAuthClient, set the necessary information (endpoints, service provider description, etc.), and override the VerifyAuthenticationCore() method.
public class ZoteroClient : OAuthClient
private const string UserAuthorizationRequestUrl =
private const string AccessTokenRequestUrl =
private const string RequestTokenRequestUrl =
In VerifyAuthenticationCore(), you’re basically just setting the properties of AuthenticationResult based on what Zotero will have passed back at this stage of OAuth, as well as any extra data your .aspx code-behind will need (in this case the access token). That’s all there is to setting up a simple custom OAuth client!
//We don't care if this is empty or not.
string userName = "";
userName = response.ExtraData["username"];
string accessToken = response.AccessToken;
Dictionary<string, string> extraData = new Dictionary<string, string>();
return new AuthenticationResult(true, this.ProviderName,
userId, userName, extraData);
Back in your .aspx code-behind, you’ll need to set up some logic to determine whether:
· You already have a token for that user.
· This is a brand new request.
· You’ve just received results back from Zotero.
In your “new request” logic, add your instantiated custom client to OpenAuth.AuthenticationClients, and then call OpenAuth.RequestAuthentication for the custom client. Then, in your logic for when a result is returned, you’ll need to get the access token from the results, as well as the user name (Zotero requires both).
Access token storage: best practices
Section 9 of the OAuth 1.0a spec states that requests take a token and signature. This means that HTTPS is not needed. Furthermore, since the token by itself can’t accomplish anything, there are no security issues with passing the token down in a cookie for the user to store.
Zotero went a slightly different route, requiring HTTPS and not requiring signing. Since the user can revoke a token at any time, the token is permanent and can thus be persisted. This means all that is needed is the access token. For the code sample, to save time and complexity, I simply stored the token in a cookie. If that cookie gets cleared, a new token gets issued. This isn’t ideal. In addition to being insecure, this implementation can clutter the user’s Zotero token management page with numerous requests. Here is an example:
Figure 2. Zotero token management page
It would be better to encrypt the key in the cookie, but the most secure option would be to store the token in a database and associate it with a user. That would require setting up an account system so that we can tie the token to a user securely. Such an approach was out of scope for this app; but since the token is permanent and is the only piece needed to actually make calls (the Zotero user ID is used as part of the URL to get at that user’s specific research sources), secure account access to a token database would be the preferred way to handle the token.
The final countdown
Only one more step remains to make sure everything will work smoothly: making sure Word will trust Zotero’s domain. In the app for Word project, open the app manifest XML file and insert the following.
That line tells the task pane that we trust Zotero, and that redirects can be opened in the task pane and not in a new browser instance. Otherwise, Zotero will try to open in a new browser instead of in the task pane, making the app unusable.
Now that everything is in place, we can run the app, which will take us to Zotero’s login page. Once we log in, we grant the app permission to work with Zotero on our behalf by creating a new key for the app. Once the key is created, Zotero redirects back to our page, and the app will have control.
Figure 3. Zotero log in page
Figure 4. Zotero app authorization page
As you can see from this example, although it’s a bit time consuming and complex, OAuth 1.0 is not difficult to implement. By using DotNetOpenAuth, you decrease the complexity, and the app is more easily integrated with existing sites that use the library. After you get the hang of it, hooking up and getting Zotero working can take as little as a few hours.
So what’s next? Well, we still need to get to the program’s logic, how to call APIs, and how to modify and insert the returned data into the Word document. In my next post, I will go over those details and show just how easy it is to work with the Word API. I hope you found this post informative, and I look forward to writing the continuation piece. Until next time!
Today’s post was authored by Tyler Wagner. Tyler is an associate developer at 3Sharp. 3Sharp specializes in SharePoint consulting and Microsoft Office customizations, and offers a range of services from building custom business intelligence dashboards to software solutions for customized document generation—and so much more. You can find out more about 3Sharp at http://www.3Sharp.com.