Monday, March 18, 2013

How to use security tokens in SharePoint / ProjectServer 2013

Hi! As we know, SharePoint / Project Server 2013 Online allows to extend its functionality with help of SharePoint apps. In order to identify users and perform communication between the app and SharePoint itself, special mechanism is proposed - security tokens are used for this purpose. This post describes how to create such app and access SharePoint / Project Server 2013 Online data using security tokens mechanism. In our case we will consider reading Project Server data from provider-hosted web app via OData protocol.

1. Create App for SharePoint 2013 (provider-hosted app) in Visual Studio 2012. MS Office development Tools should be installed for this purpose (Web Platform Instaler is used for this purpose). This will create 2 projects in your solution - SP App project and Web App project.

2. Fill in the ClientId app settings in Web.config of Web project. It should be your Company’s ClientId received when you register as MS Seller here. For dev purposes you can generate it yourself using http://SP_HOST_NAME/SP_SITE_NAME/_layouts/15/AppRegNew.aspx page.

3. Declare all necessary permissions. This can be done in AppManifest.xml file. In our case we are adding Reporting permission for future OData requests.

4. Publish SP App and upload it to the App Store. For development purposes it can be deployed to local App Store.

5. Add app to SharePoint site

6. Click on app icon to get to the hosted site

Hosted site actions:

7. Get context token from request. This can be done with help of TokenHelper class generated by Visual Studio. The code looks like the following:

var contextToken = TokenHelper.GetContextTokenFromRequest(Page.Request);

8. Get ClientContext instance with context token. Code:

var hostWeb = Page.Request["SPHostUrl"];
var clientContext = TokenHelper.GetClientContextWithContextToken(hostWeb, contextToken, Request.Url.Authority);

9. Get access token. Code:

var accessToken = TokenHelper.GetAccessToken(contextToken, targetHost);

10. In case if you need delayed assess to SP / PS data, you can use Refresh token. It can be built from the context token the following way:

var appToken = GetAppToken(Page.Request);
var refreshToken = TokenHelper.ReadAndValidateContextToken(appToken, null).RefreshToken;
var accessToken = new TokenHelper().GetAccessToken(refreshToken, targetPrincipal, targetHost, realm);
public string GetAppToken(HttpRequest request)
{
   string[] paramNames = { "AppContext", "AppContextToken", "AccessToken", "SPAppToken" };
            foreach (string paramName in paramNames)
            {
                if (!string.IsNullOrEmpty(request.Form[paramName])) return request.Form[paramName];
                if (!string.IsNullOrEmpty(request.QueryString[paramName])) return request.QueryString[paramName];
            }
}

11. Obtain client context with access token. Code:

var context = TokenHelper.GetClientContextWithAccessToken(targetUrl, accessToken.AccessToken);

12. Now we can finally perform data request. In our code we use OData:

var req = (HttpWebRequest)WebRequest.Create(url);
       req.Credentials = CredentialCache.DefaultCredentials;
       req.Headers["Authorization"] = "Bearer " + accessToken;
       req.Accept = "application/atom+xml";
var response = req.GetResponse();
Hope these instructions will save someone's time. Have fun!
Read more...