September 24, 2013

SharePoint 2013 CSOM via S2S authentication

Client-Side Object Model

The purpose of using client-side object model is build application capable of accessing SharePoint 2013 data while being deployed on another machine or even developed using a different technology. We would also like to access and store data on SharePoint using application code but still be able to apply SharePoint security model to the user that is logged in to our application. This is possible using new server-to-server (S2S) authentication model also called as a High Trust.
There are several development and configuration steps required to enable this scenario. Unfortunately none of the articles I have found in the net cover the whole process, so I will try to cover them in this article.
There are few articles I have used as a stating point:
  1. http://msdn.microsoft.com/en-us/library/fp179901.aspx - How to: Create high-trust apps for SharePoint 2013 using the server-to-server protocol
  2. http://blogs.msdn.com/b/shariq/archive/2013/05/07/how-to-set-up-high-trust-apps-for-sharepoint-2013-amp-troubleshooting-tips.aspx- How to - Set up High Trust Apps for SharePoint 2013 & Troubleshooting Tips

Prerequisites

  1. User Profile service must be enabled on SharePoint 2013 farm and synchronization must be run at least once, so user profiles are created.

Create certificate


The S2S authentication model uses asymmetric keys encryption to establish trust between servers: App and SharePoint. We will need a certificates to do that. Any valid X.509 certificate will suit including SSL ones. There are plenty of ways to generate certificates. I would recommend using Active Directory Certification Authority to generate certificates. But the easiest way is to generate self-signed certificates using IIS.
  1. Open IIS and open server Home Page
  2. Select Server Certificates feature
  3. Click Create self-signed certificate
  4. Enter friendly name and click OK
  5. Select certificate you have just created and click export.
  6. Enter the protection password you will later use to decrypt certificate and save the file in .pfx format. This file contains private key and will be used on application side.
  7. Now we need to create .cer file for SharePoint side only with public key.
    1. Double click on certificate in the certificate list.
    2. Go to details tab
    3. Click "Copy to File…"
    4. Click Next several times and save file in .cer fomat.

Create a SharePoint App



  1. Start Visual Studio 2012
  2. Click Create New Project
  3. Select Office/SharePoint  SharePoint 2013 App
  4. Enter project name
  5. Specify your SharePoint 2013 URL and select Provider-hosted
  6. Click Next
  7. Select Use certificate
    1. Browse the file
    2. Specify certificate password
    3. Leave Issuer ID
  8. Now make one adjustment to generated token helper file TokenHelper.cs.
    1. Find line
      private const string NameIdentifierClaimType = JsonWebTokenConstants.ReservedClaims.NameIdentifier;
    2. And replace it with
      private const string NameIdentifierClaimType = "upn";
    3. Without this modification I was unable to authenticate on behalf of any user.
  9. Use
    ClientContext client = TokenHelper.GetS2SClientContextWithWindowsIdentity(newUri(siteUrl), identity);to create client context with user identity. Pass null if you want to make operation under your app's identity.

Configuring SharePoint App


Use sp_admin account to configure your App. It must be different from sp_farm account and must be added to local administrators group, it also must have access to SharePoint database via PowerShell.
  1. Enable App Management Service
    1. Go to SharePoint Central Administration  Application Management Manage services on Server
    2. Click Start button beside App Management Service
    3. Go to Manage Application Management  Service applications
    4. In the ribbon New  App Management Service
    5. Configure service settings and click OK button
  2. Start SharePoint powershell
    add-pssnapin Microsoft.SharePoint.Powershell
  3. Enable Subscription Settings Service(http://technet.microsoft.com/en-us/library/fp161236.aspx#section253)
    $account = Get-SPManagedAccount "domain\sp_admin"
    $appPoolSubSvc = New-SPServiceApplicationPool -Name SettingsServiceAppPool -Account $account
    $appSubSvc = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPoolSubSvc –Name SettingsServiceApp –DatabaseName SettingsServiceDB
    $proxySubSvc = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $appSubSvc
  4. Create App Catalog site collection
    1. Go to SharePoint Central Administration  App  Manage App Catalog
    2. Create App Catalog site collection
  5. Install App certificate into SharePoint store (http://msdn.microsoft.com/en-us/library/fp179901.aspx#Configure2)
    $publicCertPath = "c:\tmp\adlordy.SharePointApp.cer"
    $spurl = "http://sharepoint2013"
    $issuerId = "48053b08-abd3-4394-8c86-07b5417124fd"
    $spweb = Get-SPWeb $spurl
    $realm = Get-SPAuthenticationRealm -ServiceContext $spweb.Site
    $certificate = Get-PfxCertificate $publicCertPath
    New-SPTrustedRootAuthority -Name "adlordy.SharepointApp" -Certificate $certificate
    $fullIssuerIdentifier = $issuerId + '@' + $realm
    New-SPTrustedSecurityTokenIssuer -Name $issuerId -Certificate $certificate -RegisteredIssuerName $fullIssuerIdentifier –IsTrustBroker
  6. Register app principal in SharePoint
    1. App Id is: 48053b08-abd3-4394-8c86-07b5417124fd
    2. Use http://sharepoint2013/ _layouts/15/Appregnew.aspx to register new app principle. Enter above App Id into the App Id field. Client Secret field is irrelevant
    3. Use following PowerShell script to register app principal:
      $clientId = "48053b08-abd3-4394-8c86-07b5417124fd"
      $spurl = "http://sharepoint2013/"
      $spsite = Get-SPSite $spurl
      $realm = Get-SPAuthenticationRealm -ServiceContext $spsite
      $fullAppIdentifier = $clientId + '@' + $realm
      $appPrincipal = Register-SPAppPrincipal -NameIdentifier $fullAppIdentifier -Site $spsite.OpenWeb() -DisplayName "adlordy.SharepointApp"
  7. Allow HTTP requests
    $config = (Get-SPSecurityTokenServiceConfig)
    $config.AllowOAuthOverHttp = $true
    $config.Update()
  8. Set app domain for applications
    set-spappdomain sharepoint2013.domain.local
  9. Create subscription
    New-SPSiteSubscription
     
    After competing above step you should be able to publish your application from Visual Studio or install it from the App package.