Managing Tokens in SharePoint 2013 Single-Page Provider-Hosted Apps

by Scot Hillier on Jul 11, 2014

Share this:
Print

Article Details

Date Revised:
Sep 13, 2014


Single-page apps (SPA) are gaining popularity throughout the SharePoint development community because they provide an outstanding end-user experience and are supported by mature frameworks such as Angular. The outstanding end-user experience comes from the fact that the SPA never executes a postback to the server, which makes the app feel almost like a desktop application. Additionally, SPA frameworks are essential for success, because they accelerate the development process and provide consistent development patterns. However, SPAs require developers to interact with services that require token-based authorization schemes. Initially, SPA development seems to run counter to properly managing bearer tokens, but a properly-designed app makes it possible to create single-page applications that utilize token-based authorization.

 

Understanding SPA Security Challenges

Because a SPA has just one page, it must rely heavily on JavaScript since it will generally not execute a postback to the server. That doesn’t mean, however, that server-side code is off limits in a SPA. Most SPA designs utilize calls to Representational State Transfer (REST) services as a means to perform server-side processing without leaving the single page. In SharePoint 2013 app designs, REST calls may be made to either SharePoint resources or custom services. For the SPA developer this can be a challenging situation because each service may demand different forms of user authentication and app authorization.

When you make REST calls to SharePoint resources, the security requirements are determined by the app hosting model, which can be either SharePoint-hosted app (SHA) or provider-hosted app (PHA). The SHA model utilizes internal security, which does not require the use of any authorization tokens. When a REST call from a SHA targets a SharePoint REST API endpoint in the app domain, security just works; developers do not need to do any special programming. The PHA model, on the other hand, utilizes external security, which requires the use of authorization tokens. These tokens can be part of an on-premises solution utilizing server-to-server high trust or a cloud-based solution using OAuth tokens. Because this article is concerned with the management of tokens, we’ll focus on the PHA model.

When you make REST calls to custom services, the security requirements are similar to the approach taken with SharePoint services. Custom services typically use OAuth or a custom tokening implementation. If, for example, you are creating a custom RESTful service using WebAPI, then the solution could be deployed to a Microsoft Azure web site where it would gain the ability to secure itself using OAuth tokens. If you are creating an on-premises solution, you may create a custom token provider. In any case, SharePoint apps would have to retrieve an access token and pass it to the custom service for authorization.

Regardless of whether the SPA is calling back into SharePoint or utilizing a custom service, as a developer you must be conscious of the security implications inherent in token-based security schemes. The tokens utilized by an app to call a service are referred to as bearer tokens. The most important characteristic of a bearer token is that it is unbound from the app that uses it. This means that the token itself contains all necessary security information to access the targeted service; it does not require any additional security information from the app that uses it. The implication of this scheme is that a bearer token can be used by any app that gets a copy of it. Bearer tokens are often described as cash – whoever possesses it, can spend it.

Because bearer tokens are so powerful, as the app developer, you must defend them. First and foremost, this means that all apps should utilize Secure Sockets Layer (SSL) for communication to avoid sending token information in clear text. Second, bearer tokens should never be visible in client-side JavaScript or retrievable using browser-based debugging tools. The first requirement is met by a proper infrastructure design, the second requirement is met by proper app design.

Designing a Single-Page Provider-Hosted App

The security implications of bearer tokens provide a special challenge for SPA developers. SPA architecture requires the use of JavaScript to provide a responsive end-user experience when you utilize REST calls for data-intensive operations. So, initially it appears that the SPA would need to have access to the bearer token in JavaScript in order to make a REST call. But exposing the bearer token in JavaScript violates the security rules for bearer tokens. Fortunately, SharePoint developers can implement a pattern that supports SPA development while defending bearer tokens.

The key to creating single-page provider-hosted apps in SharePoint 2013 is to utilize ASP.NET MVC5 and Web API as the underlying technologies. An MVC5 controller is used to retrieve the required bearer token during app startup. The bearer token is then stored in session state so that it is never visible in client side code. Once the token is retrieved, a view is rendered, along with appropriate JavaScript to implement the SPA.

The JavaScript code in the SPA will not have access to the bearer token. However, it can call a Web API service in the same project because that service will be in the same domain as the SPA. Therefore any calls made by the SPA to such a Web API service will not violate same-origin policy and will succeed.

The Web API project can then retrieve the bearer token, which was previously stored in session state, and use it to make calls back into SharePoint (or any other token-secured REST service).

Figure 1 shows the components of the solution. A detailed walkthrough of the communication sequence follows.

 00

Figure 1, Single-page provider-hosted app pattern

  1. End user logs into SharePoint

  2. End user launches provider-hosted app

    1. SharePoint redirects the user to the provider-hosted app

    2. A context token is passed from SharePoint to the provider-hosted app

    3. The context token contains a refresh token

  3. The MVC5 controller retrieves an access token from Azure Access Control Services (ACS)

    1. The controller retrieves the refresh token from the passed context token

    2. The refresh token is used to retrieve an access token from ACS

  4. The MVC5 controller launches the SPA view

    1. The controller stores the access token in session state

    2. The SPA is defined in the view that is associated with the controller

  5. The SPA makes RESTful calls to a custom Web API controller

  6. The Web API controller retrieves the access token from session state

  7. The Web API controller makes RESTful calls to SharePoint using the retrieved access token

Developing a Single-Page Provider-Hosted App

You can create a single-page provider-hosted app as either an on-premises or cloud-based solution. This walkthrough, will create a cloud-based app that uses Office 365 and Azure. In order to focus on the core concepts of managing OAuth tokens, the code will be kept simple and avoid the additional complexity of utilizing a SPA framework. Instead, this example will stick to simple jQuery code. However, you could easily expand the walkthrough to use a SPA framework.

Creating a New Project

The solution begins with the creation of a new provider-hosted app project in Visual Studio 2013. This process does not involve any special steps (as Figures 2 through 5 show), but the provider-hosted app should use the ASP.NET MVC5 framework and target an appropriate Office 365 developer site.

 01

Figure 2, Create a new SharePoint app project

 02

Figure 3, Select provider-hosted app

 03

Figure 4, Select MVC5

 04

Figure 5, Select Windows Azure Access Control Service

Modify the Home Controller Code

The app template provided by Visual Studio 2013 has some default code in the home controller for making a call back into SharePoint. Because the app will be a SPA, the default code will not work. Instead, you’ll need to modify this code so that it retrieves an access token and stores it in session state along with the URL of the host web as shown in Listing 1.

 05

Listing 1, Saving the access token to session state

Add a Web API Controller

Add a Web API Controller to the project by right-clicking the Controllers folder and selecting Add Controller. Select to add an empty Web API Controller, as shown in Figure 6. Note that when you add a Web API controller to a provider-hosted app project, you will have to perform some additional steps in the Global.asax.cs file. To help you complete the steps, Visual Studio presents you with a readme file detailing the required changes.

 06

Figure 6, Add a new Web API Controller

Enable Session State for Web API

While session state is enabled for MVC5 controllers by default, it is not enabled for Web API controllers by default. This makes sense because RESTful services should normally be designed as stateless. According to the REST restraints outlined by Roy Fielding, “Session state is therefore kept entirely on the client.” Recognize, however, that state is being enabled solely to hide the bearer token on the server; the intent is not to maintain transactional state information in the Web API controller.

In order to implement session state in a Web API controller, you must create two classes. One class implements IRouteHandler, and the other class implements IRequiresSessionState. You can read more details on this approach here. Listing 2 is the complete code for WebApiConfig.cs, where the solution is implemented.

 07

Listing 2, Enabling Web API Session State

Retrieve token and call SharePoint

Once state is enabled, then you can code the Web API controller. The controller will retrieve the token from session state and use the token to make a RESTful call back to SharePoint. This all works because the Web API controller is in the same domain as the MVC5 controller. The code in Listing 3 does a simple call to get the identity of the current user.

 08

Listing 3, Calling into SharePoint

Call the Web API Controller from the SPA

Once the Web API controller is coded, the SPA can call it. You use the view associated with the Home controller to implement the SPA. An MVC5 controller can have an associated HTML view that is rendered after the controller completes processing. In this case, the MVC5 controller retrieves the access token, saves it to session state, and then renders the SPA view. The SPA view then uses JavaScript to call the Web API controller. The SPA view does not need a token to call the Web API controller because the SPA and the Web API controller are in the same domain. The code in Listing 4 shows the SPA view.

 09

Listing 4, the SPA view

Conclusion

Increasingly, SharePoint developers are creating single-page apps in order to provide a high-quality end-user experience. SharePoint developers are also finding themselves interacting with services that require token based authorization schemes. Initially, SPA development seems to run counter to properly managing bearer tokens, but a properly-designed app makes it possible to create single-page applications that utilize token-based authorization.



2 months ago
Hi Scott,Thanks for sharing, great example! Stephane Eyskens

2 months ago
Can you share the source for this?