Home > Blogs > Eric Shupps | The SharePoint Cowboy > Posts > Configuring High Trust Apps for SharePoint 2013
Eric Shupps eshupps The SharePoint Cowboy is the founder and President of BinaryWave, a leading provider of operational intelligence solutions for Microsoft SharePoint. Eric Shupps eshupps The SharePoint Cowboy has worked with SharePoint Products and Technologies since 2001 as a consultant, administrator, architect, developer and trainer. he is an advisory committee member of the Dallas/Ft. Worth SharePoint Community group and participating member of user groups throughout the United Kingdom. Eric Shupps eshupps The SharePoint Cowboy has authored numerous articles on SharePoint, speaks at user group meetings and conferences around the world, and publishes a popular SharePoint blog at http://www.sharepointcowboy.com. Presentations by Eric Shupps eshupps The SharePoint Cowboy Webinar - Migrating Legacy On Premise Solutions to SharePoint Online and Windows Azure featuring Eric Shupps Who are you and what do you want - Working with OAuth in SharePoint 2013 SharePoint is Talking Are You Listening? Eric Shupps SharePoint 2013 Performance Enhancements Taking Advantage of the SharePoint 2013 REST API Eric Shupps on Improving Performance with New Features in SharePoint 2013 SharePoint 2013 New and Improved Migrating Legacy On Premise Solutions to SharePoint Online and Windows Azure Eric Shupps Presents SharePoint 2013 Real World Help Desk App End to End Windows Azure Apps for SharePoint 2013 Eric Shupps Demonstrates Customizing the Visual Studio 2010 SharePoint Deployment Process Introduction to SharePoint Development SharePoint 2010 Unit and Integration Testing with Eric Shupps Building Enterprise Records Management Solutions for SharePoint 2010 Taming Information Chaos in SharePoint 2010 SharePoint 2010 Performance and Capacity Planning Best Practices Building Dynamic Applications with the SharePoint Client Object Model Articles by Eric Shupps eshupps The SharePoint Cowboy Eric Shupps' Ten Steps to Optimize SharePoint Performance Webcasts by Eric Shupps eshupps The SharePoint Cowboy Secrets of SharePoint Part 5: Configuring Microsoft Office SharePoint Server 2007 for Optimal Performance Creating End User SharePoint Solutions for Performance and Scalability SharePoint 2010 Performance Enhancements for Administrators by Eric Shupps Microsoft SharePoint Server 2010 for the ASP.NET Developer Eric Shupps on Following Best Practices and Avoiding Common Errors with Microsoft Office SharePoint Server 2007 Development Eric Shupps - SharePoint Performance and Capacity Planning Essentials Troubleshooting Common Performance Problems in SharePoint 2010 Videos by Eric Shupps eshupps The SharePoint Cowboy Channel 9 Interview with Eric Shupps SharePoint TechTalk with Eric Shupps - Different Views on Social Computing SharePoint Post-Deployment Planning and Management with Eric Shupps SmartTrack for SharePoint Feature Overview SmartTrack for SharePoint Podcasts by Eric Shupps eshupps The SharePoint Cowboy SharePoint Pod Show - Design for Performance (Eric Shupps) SharePoint Pod Show - Test Driven Development with Andrew Woodward and Eric Shupps eshupps The SharePoint Cowboy Run As Radio - Eric Shupps Improves SharePoint Performance
SmartTrack for SharePoint Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave

​The SharePoint Cowboy

photo of  Eric Shupps
611 S. Main St., Suite 400
Grapevine , TX , 76051 USA
Eric Shupps and Eric Alan Shupps with BinaryWave the BinaryWave Inc in BinaryWave Incorporated around SmartTrack beside SharePoint Monitoring through SharePoint alongside SharePoint Monitoring visiting @eshupps via eshupps near SharePoint performance and SharePoint management. The SharePoint cowboy eshupps BinaryWave and more on Operational Intelligence via Eric Alan Shupps SharePoint blog. SharePoint monitoring is a hot topic along with SharePoint Performance Measurement and SharePoint tips and tricks from Eric Shupps for SmartTrack. Another Eric Shupps on Technology and Eric Shupps on SharePoint with a new SharePoint Post from Eric Shupps. New BinaryWave post through BinaryWave Inc. and with another SharePoint blog we get to Eric Alan Shupps Blog about SharePoint development. That's Eric Shupps - BinaryWave or Eric Alan Shupps Fort Worth Grapevine Texas Dallas of BinaryWave talking about BinaryWave Operational Intelligence at the SharePoint Cowboy blog and on twitter as @eshupps. Of course SharePoint Administration is on topic for eshupps and another great post from Eric Shupps regarding BinaryWave SharePoint and SharePoint Maintenance.
August 26
Configuring High Trust Apps for SharePoint 2013

The SharePoint 2013 Application Model supports app development for both cloud and on-premise environments; however, there are distinct differences between the two implementations. In the cloud, apps rely upon an external authorization process to validate that an application hosted outside of SharePoint – in a vendor's data center, for example – is allowed to communicate with the SharePoint site where the app has been deployed. Within the enterprise, it is unlikely that an authorization server will be present or even necessary; rather, apps developed and deployed internally are assumed to have "high trust". In order to facilitate a high trust relationship in the absence of a pre-configured authorizing entity, a specific set of configuration tasks must be performed for each app that will be deployed.

The following steps outline the process for creating a provider-hosted app (one that runs outside of SharePoint but within the same enterprise) and configuring it for high trust. ASP.NET developers should be familiar with most of the initial non-SharePoint steps; however, there are some specific requirements that can cause app deployment to fail if not performed in the right order so even basic tasks have been included. Some tasks are optional or up to the developer's discretion, such as the publishing method used for a standard ASP.NET web site, but others, like the PowerShell configuration commands for creating a trusted token service, must be performed as indicated. The example does not include the user of JavaScript-based SharePoint chrome elements – for more information on how to add basic SharePoint 2013 look and feel to remote web applications refer to How To: Use the Client Chrome Control in Apps for SharePoint on MSDN.

Note: Before attempting to create apps for SharePoint 2013 be sure to review the MSDN guidelines on setting up an on-premise development environment.



Create a Remote Web Project


The first step is to create a remote web application that users will be redirected to when they click on the app tile in a SharePoint 2013 site. In development, this site will likely be deployed as a disk-based web to the same server; however, in production, it is more likely that SharePoint and the remote web will not exist in the same farm or even in the same network.


In Visual Studio 2012, create a new ASP.NET Empty Web Application.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Add a default page to the project.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Modify the web.config file to support Windows authentication.




<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

<add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />



<compilation debug="true" targetFramework="4.5" />

<httpRuntime requestValidationMode="4.5" targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder, System.Web, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

<pages controlRenderingCompatibilityVersion="4.5" />

<authentication mode="Windows" />


<allow users="*" />


<machineKey compatibilityMode="Framework45" />





Publish the Remote Web Site


Once the project has been created there are several options for making it accessible to users. In this instance the project will be published as a disk-based web, a process familiar to most ASP.NET developers.  

Create an IIS web site (remember to set the Application Pool to use the .NET v4.0 framework instead of v2.0).


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Publish the remote web to the web site.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Create a new publishing profile.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Publish to the file system, specifying the directory and URL. Remember to create a DNS or host entry for the site URL prior to publishing in order to verify that the site is reachable after publishing is complete. Ideally, a fully qualified domain name should be used for the destination URL.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Publish the web application.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Configure Remote Web Authentication (Part 1)


In most cases, setting Windows authentication on the web application via web.config is sufficient; however, when creating a remote web for a provider hosted SharePoint app, there are some configuration steps which need to take place before the app can be accessed by users. In order to complete these tasks the web application must also have anonymous authentication enabled. Once configuration is complete anonymous can be disabled.  

Enable both Windows and anonymous authentication on the published web application. Depending upon your environment, it may also be necessary to promote NTLM above Negotiate as the preferred provider.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Create a Remote Web Certificate


SharePoint 2013 requires that all apps run over HTTPS. Apps may also run on HTTP (if, for example, they are also accessed by users outside of SharePoint) but they must have a certificate and SSL binding in order to proceed with app configuration. In development, it is acceptable to use a self-signed certificate; however, this should be replaced with a full certificate when the application is migrated to production.  

Create a self-signed certificate.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


The newly created certificate will be required in later configuration steps. Export the certificate to the remote web application and include it in the Visual Studio project. The certificate must be secured with a password.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Add certificate settings to the web.config file in the appSetttings section.



<add key="ClientSigningCertificatePath" value="c:\inetpub\wwwroot\ContosTestWeb\ContosoTestCertificate.pfx" />

<add key="ClientSigningCertificatePassword" value="password" />



Edit the bindings of the web site and apply the certificate. Assuming that other web sites are running on the same machine, it will probably be necessary to create a secondary IP address and assign ports 80 and 443 to that address. In addition, the site should use a fully-qualified domain name, such as "contosotestweb.contoso.com" instead of just "contosotestweb" (remember to add a host entry on the machine for the FQDN).



Create a Remote Web Metadata Document


Configuring a remote web for SharePoint trust involves the execution of PowerShell commands to create a new SPTrustedSecurityTokenService (as detailed in Step 12). In order for these commands to succeed, an HTTP Handler class must exist in the remote web. This class relies upon the certificate and web.config settings from Step 4.  

Add a Generic Handler to the remote web project.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Add the following reference to the remote web project:




Replace the contents of the MetadataDocument.ashx.cs file with the following code (substitute the correct namespace):


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Runtime.Serialization.Json;

using System.IO;

using System.Text;

using System.Security.Cryptography.X509Certificates;

using System.Web.Configuration;

using System.Runtime.Serialization;


namespace Contoso.TestWeb


public class MetadataDocument : IHttpHandler


#region IHttpHandler Members


public bool IsReusable


get { return true; }



public void ProcessRequest(HttpContext context)


if (null == context ||

null == context.Request ||

null == context.Request.QueryString ||

null == context.Response)


throw new ArgumentNullException("context");



string realm = context.Request.QueryString["realm"];  

JsonMetadataDocument document = GenerateMetadataDocument(realm);  

string responseText = Serialize(document);  

HttpResponse response = context.Response;

response.ContentType = "application/json";







private static string Serialize(JsonMetadataDocument metadataDocument)


if (null == metadataDocument)


throw new ArgumentNullException("metadataDocument");



string serializedDocument = null;

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(metadataDocument.GetType());


using (MemoryStream stream = new MemoryStream())


jsonSerializer.WriteObject(stream, metadataDocument);

serializedDocument = Encoding.UTF8.GetString(stream.ToArray());



return serializedDocument;



private static void AddCertificiateToMetadata(

JsonMetadataDocument metadataDocument,

X509Certificate2 certificate)


if (null == metadataDocument)


throw new ArgumentNullException("metadataDocument");



if (null == certificate)


throw new ArgumentNullException("certificate");



metadataDocument.Keys.Add(CreateKeyMetadata(certificate, SPSecurityTokenServiceJsonMetadataKeyUsage.Signing));



private static JsonMetadataKey CreateKeyMetadata(X509Certificate2 certificate, SPSecurityTokenServiceJsonMetadataKeyUsage usage)


if (null == certificate)


throw new ArgumentNullException("certificate");



JsonMetadataKey keyMetadata = new JsonMetadataKey


Usage = usage.ToString(),

KeyValue = new JsonMetadataKeyValue


Type = "x509certificate",

Value = Convert.ToBase64String(certificate.Export(X509ContentType.Cert))




return keyMetadata;



private static JsonMetadataDocument GenerateMetadataDocument(string realm)


JsonMetadataDocument metadataDocument = new JsonMetadataDocument();  

metadataDocument.ServiceName = metadataDocument.Name = HostedAppName;  

metadataDocument.Realm = realm;  

metadataDocument.Keys = new List<JsonMetadataKey>();

X509Certificate2 clientCertificate = new X509Certificate2(ClientSigningCertificatePath, ClientSigningCertificatePassword);

AddCertificiateToMetadata(metadataDocument, clientCertificate);  

return metadataDocument;



private static readonly string HostedAppName = WebConfigurationManager.AppSettings.Get("ClientId");

private static readonly string ClientSigningCertificatePath = WebConfigurationManager.AppSettings.Get("ClientSigningCertificatePath");

private static readonly string ClientSigningCertificatePassword = WebConfigurationManager.AppSettings.Get("ClientSigningCertificatePassword");



private class JsonMetadataDocument


[DataMember(Name = "serviceName", EmitDefaultValue = false)]

public string ServiceName { get; set; }


[DataMember(Name = "name", EmitDefaultValue = false)]

public string Name { get; set; }


[DataMember(Name = "realm", EmitDefaultValue = false)]

public string Realm { get; set; }


[DataMember(Name = "issuer", EmitDefaultValue = false)]

public string Issuer { get; set; }


[DataMember(Name = "keys", EmitDefaultValue = false)]

public List<JsonMetadataKey> Keys { get; set; }




private sealed class JsonMetadataKey


[DataMember(Name = "usage", EmitDefaultValue = false)]

public string Usage { get; set; }


[DataMember(Name = "keyValue", EmitDefaultValue = false)]

public JsonMetadataKeyValue KeyValue { get; set; }




private sealed class JsonMetadataKeyValue


[DataMember(Name = "type", EmitDefaultValue = false)]

public string Type { get; set; }


[DataMember(Name = "value", EmitDefaultValue = false)]

public string Value { get; set; }



private enum SPSecurityTokenServiceJsonMetadataKeyUsage








Configure Remote Web for OAuth/S2S


The SharePoint 2013 app model relies upon the OAuth protocol for authorization. OAuth integration for SharePoint and Office apps is made possible via the Azure Connect Service. Although it is certainly possible for an on-premise environment to make use of ACS it is unlikely that an organization will have this in place or will be implementing it in the near future. This is one distinct advantage of deploying remote apps to Office365 – OAuth and ACS are already configured and available to developers without any additional effort or investment. In order to facilitate on-premised deployments without ACS, Microsoft makes a fallback configuration available known as "Server to Server". This allows specific entities, such as web applications, to be explicitly trusted for authorization and is the crux of the entire High Trust Configuration method described in this guide.  

For those who are interested in learning the details of how the OAuth authorization process functions with SharePoint 2013 apps, the following graphic provides a high-level summary:


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


More information is available at: http://msdn.microsoft.com/en-us/library/fp142382(v=office.15).aspx  

The code to handle S2S authorization and client context initialization is somewhat complex; fortunately, Microsoft has provided sample code in the form of a C# class which abstracts the underlying methods and leaves developers free to concentrate on implementation of the process. To enable the remote web to handle S2S authorization, begin by adding the following references to the project:









The SharePoint client DLL's can be found in the following directory:


C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI


The Microsoft.IdentityModel DLL's can be found in the following directories:






Copy the TokenHelper.cs file from the SharePoint 2013 samples on MSDN (http://code.msdn.microsoft.com/sharepoint/) into the remote web project (substitute the correct namespace). It will then be necessary to edit the default.aspx.cs file to handle incoming traffic from SharePoint, calling out to the TokenHelper methods to handle authorization and establish context.  

When a user clicks on an app tile in SharePoint, the ensuing request takes the form of either a POST (in Office365 with full OAuth present) or a GET with a specific set of parameters. These parameters, specified in the app manifest file (Step 10), provide the remote web with the host and appweb URL's in SharePoint. If the operation is a POST the parameters will also include the token provided by ACS. In an on-premise implementation, there is no token so the process falls back to using the windows identity of the requestor to establish context (via the GetS2SClientContextWithWindowsIdentity method in TokenHelper.cs).  

As the remote web runs on an accessible port reachable from outside SharePoint, pages in the app should handle establishment of context for each user and catch those instances where a user is not authorized to access resources in SharePoint. As a simple example, the following code, when added to the Page_Load event of default.aspx.cs, will attempt to establish context, displaying an error message if the user is not authorized (the attempt to establish context fails):




string hostTitle = string.Empty;

Uri spUrl = null;


foreach (string key in Request.QueryString.Keys)


if (key == "HostUrl" || key == "SPHostUrl")


spUrl = new Uri(Request.QueryString[key]);





ClientContext clientContext = null;

clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(spUrl, Request.LogonUserIdentity);




hostTitle = clientContext.Web.Title;

Response.Write("Successfully authorized for: " + hostTitle);


catch (System.Exception ex)





*Note: Be sure to include a using statement for Microsoft.SharePoint.Client


At this stage, the application should return an "Object reference not set to an instance of an object" error as the SPHostUrl parameter is null. Proper context will be established once the app is accessed from SharePoint; however, it is important to point out that this process may have a detrimental impact to applications which are being ported to the app model but still need to be accessed outside of SharePoint. It is also worth noting that the above sample is very simple – developers will want to account for various scenarios in production code, such as persisting tokens and/or context so as not to make repeated calls back to SharePoint, porting to Office365 and processing of actual token values, etc.



Create a Developer Site


SharePoint 2013 contains several new site templates, one of which is "Developer Site". This template includes several artifacts that enable one-click deployment of apps from Visual Studio without the need for publication to a corporate catalog. In addition, this site template is roughly equivalent to the Developer Site in Office365, resulting in a more cohesive experience when creating apps that may be published both on-prem and to the cloud.  

Create a new site collection and choose "Developer Site" from the list of available templates.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Create a New App Registration


In Office365, app providers are assigned unique GUID's and key values for applications that will be sold in the marketplace. This helps Microsoft track individual apps and provides a level of verification that the app is genuine. For on-premise deployments, there is no marketplace; instead, SharePoint 2013 introduces the concept of the Corporate Catalog. This is a repository of trusted apps which administrators have made available for installation throughout the enterprise. The catalog is an effective mechanism for final publication but doesn't suit iterative development processes very well.  

In order to facilitate the traditional Build -> Deploy -> Test -> Refactor development cycle, SharePoint 2013 allows individual apps to be registered on a specific site. A GUID and secret value are assigned and those values are used in both the app manifest and the remote web. When development is complete and the app is ready for publication, these values will be replaced by global identifiers.  

Browse to the App Registration URL in the Developer Site.  


Generate a new App Id and App Secret using the buttons provided on the form. Enter the title of the app and the FQDN of the remote web without the protocol prefix (i.e. "contosotestweb.contoso.com" instead of "http://contosottestweb.contoso.com"). Finally, enter the full path to the default page of the remote web ("redirect" is a bit of a misnomer – it's actually the landing page that the user will be sent to when the app tile is clicked; however, this can be overridden in the app manifest). The Redirect URI must use https – http is not permitted.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Copy these values to a text file or other temporary location as they will be needed in the following step.



Create and Configure a Provider Hosted App


An "app" in and of itself is nothing more than a manifest file and related artifacts (if any), much like a Feature. There are several different hosting models for SharePoint apps (see Introducing the SharePoint 2013 Application Model), some of which can include actual SharePoint elements such as pages, lists and libraries. For a remote web app, there are no SharePoint components – all that is required is an app manifest file that contains configuration parameters and displays a link to the remote web within a SharePoint site.  

Create a new App for SharePoint 2013.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Provide a name for the app (which should be the same as the name from the app registration but it is not required that they match), select a target URL (for F5 deployment) and pick a hosting model – in this case "Self-hosted".


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


The Visual Studio tools assume that you want to create a new web application and app at the same time and that they should both be in the same solution. Although this is perfectly feasible, it does not really fit a distribution model for marketplace/catalog apps nor does it apply to existing apps being ported to SharePoint 2013. One advantage that it does provide is that the TokenHelper.cs file is automatically included (this is also available in most of the samples on MSDN). For purposes of keeping the SharePoint and non-SharePoint solutions separate, the web application Visual Studio creates will be removed from these examples but that is neither a recommendation nor a best practice; it is merely individual preference.  

The app project is very simple – just an image file and the app manifest XML.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


The app manifest file, much like Feature and Solution manifests, sets all the configuration options for the app. A visual designer is available to simplify the process of applying settings:


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Unfortunately, the configuration page assumes that the app uses the included web application created by Visual Studio and that the Redirect URI from the app registration will function as the remote web URL. It also fails to provide any facility for setting the app Client ID, which is an absolute necessity for provider-hosted apps. Instead of using the design surface, right-click on the AppManifest.xml file and choose "View Code". This will open the file in the Visual Studio text editor.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Note the <StartPage> node and the {StandardTokens} query string parameter. This parameter insures that the values needed for the remote web to call back into SharePoint are included in the request (such as the "SPHostUrl" value required by TokenHelper). The Redirect URI from the app registration can be overridden in this node by replacing the ~remoteAppUrl token with a full url:



<Title>Contoso Test App</Title>




Enter the App Id from the app registration step as the ClientId value.



<RemoteWebApplication ClientId="922e5692-8369-4ee1-b121-e95310c8e6ac" />



In addition to establishing context for client object model commands in the code-behind of the Default.aspx, an app must also be granted an explicit permission set which specifies what type of resources the app can access and at what level. For lists, libraries, and other common resources, the permission scope is "http://sharepoint/content", followed by the level in the hierarchy where access is permitted, such as "sitecollection", "web" or "list" (i.e. "http://sharepoint/content/sitecollection" or "http://sharepoint/content/sitecollection/web/list"). Scopes are cumulative, such that a permission value of "sitecollection" also grants permission for "web" and "list"; however, if the lowest permission level is specified explicitly, such as "http://sharepoint/content/sitecollection/web/list", then no higher-level permissions are available unless specifically allowed by additional AppPermissionRequest entries. Furthermore, the type of access must be specified. This is done via the "Right" attribute, which allows four permission types – "Read", "Write", "Manage" and "FullControl". Other scopes have different syntax and rights – see App Permissions in SharePoint 2013 on MSDN for more information on app permissions.  

Add an AppPermissionRequest entry for Read permissions at the Site Collection level.  

<AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />  

The final app manifest file should resemble the following:  

<?xml version="1.0" encoding="utf-8" ?>

<App xmlns="http://schemas.microsoft.com/sharepoint/2012/app/manifest"




SharePointMinVersion="" >


<Title>Contoso Test App</Title>




<RemoteWebApplication ClientId="922e5692-8369-4ee1-b121-e95310c8e6ac" />



<AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />





Modify Remote Web Configuration


Before the app can be deployed, the remote web must be configured with the App Id and App Secret values from the app registration. Edit the web.config file in the remote web project and add the following entries to the <appSettings> node, where ClientId and ClientSecret equal the App Id and App Secret values copied from the app registration:  

<add key="ClientId" value="922e5692-8369-4ee1-b121-e95310c8e6ac" />

<add key="ClientSecret" value="2RM054YeWEKvjqJFxSFeD64TU6M8IAm9txdxacL7RKc=" />



Configure Remote Web Trust


With all the prerequisites in place, the environment can now be configured for the server to server trust relationship between the remote web and SharePoint. This configuration is done via PowerShell. Begin by establishing a variable for the Developer Site web object (where the app registration was performed):


$web = Get-SPWeb http://dev.contoso.com


Create a variable for the metadata document URL.


$metadataDocumentUrl = "http://contosotestweb.contoso.com/MetadataDocument.ashx"


Get the authentication realm and store it in another variable.


$realm = Get-SPAuthenticationRealm -ServiceContext $web.Site


Create a new Trusted Security Token Service instance using the specified metadata document.


$trustedTokenService = New-SPTrustedServiceTokenIssuer -Name "Contoso Test App Token Service" -MetadataEndPoint $metadataDocumentUrl –confirm:$false


Register the app principal with the new token service.


$appPrincipal = Register-SPAppPrincipal -NameIdentifier $trustedTokenService.RegisteredIssuerName.Replace('*',$realm) -Site $web -DisplayName "Contoso Test App Principal"


Set the app principal permission.


Set-SPAppPrincipalPermission -Site $web -AppPrincipal $appPrincipal -Scope Site -Right FullControl


Note that the scope value in PowerShell does not use a URI syntax; instead, the allowable values are either "Site", "Web" or "List". Once complete, the remote web will be permitted to access SharePoint via the trust specified in the token service. It is important to note that each app must have a unique certificate AND a unique SPTrustedSecurityTokenService instance. At present these cannot be shared between apps.  

When the configuration commands are complete execute an IISRESET operation.


NOTE: The above procedure was applicable only to the SharePoint 2013 Beta releases.  For RTM and later, and in combination with subsequent releases of the developer tools, the procedure has changed.  See Kirk Evan's blog post and this MSDN article for further background and the new PowerShell commands for RTM.



Configure Remote Web Authentication (Part 2)


Once the trust relationship has been successfully established, anonymous authentication can be removed from the remote web.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Deploy Provider Hosted App


The app is now ready for deployment to the developer site. From the ContosoTestApp project, press F5. A prompt will be displayed asking for confirmation of the permission request being made by the app:


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack

Clicking "Trust It" will add the app to the site contents.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


Clicking on the app tile will load the default page of the remote web. The code in the default.aspx page will parse out the SPHostUrl query string parameter, passing it, along with the windows identify of the user, to the token helper method to establish context with the SharePoint site. The Client Side Object Model query will then be executed and, when the site title is successfully retrieved, the authorization message will be displayed.


Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack


The process is now complete. Follow the same steps for adding new apps to the developer site. Changes to the existing app will not require any further trust configuration modifications unless the URL, certificate, or AppPrincipal changes.



The most common error encountered in configuring high trust apps is a "401 – Unauthorized" exception after clicking on the app tile and being redirected to the remote web. This is most likely due to a bad setting or configuration parameter in the PowerShell commands. Check the following to resolve this issue:

  1. Ensure that the path and password are correct for the certificate in the web.config file and that it has been applied successfully to the SSL binding for the site in IIS.
  2. Leave anonymous authentication enabled on the remote web until after the PowerShell commands have been run. Then it must be removed in order for a valid windows identity to be established.
  3. The SPTrustedSecurityTokenService "Name" and SPAppPrincipal "DisplayName" values must be unique. If a mistake is made during configuration, re-run the commands using new values for each of these entities.

Additional troubleshooting steps:

  1. Be certain to set the Redirect URI value in the app registration to an HTTPS address – HTTP will not work. The same applies to substituting a full URL for the ~remoteAppUrl in the appmanifest.xml file.
  2. If the JavaScript OM is being utilized (such as invoking the SharePoint chrome via SP.UI.Controls.js) client context must first be established via the TokenHelper methods; otherwise, calls to retrieve the chrome controls will fail.
  3. Pay careful attention to the AppPermissionRequest scope value being used. If a granular scope is selected, such as "http://sharepoint/contents/sitecollection/web/lists", then access to data from parent web and site objects will be blocked.




Nik Patel

Wow!!! This is absolutely must resource for provider hosted App configuration without ACS.. very well detailed...
 on 9/9/2012 11:52 PM

Stuck at the 11th step

$trustedTokenService = New-SPTrustedSecurityTokenService -Name "Contoso Test App Token Service" -MetadataEndPoint $metadataDocumentUrl –confirm:$false

 New-SPTrustedSecurityTokenService Seems to be depricated in SP 2013 powershell.. can u plz lemmi know what is the alternative for this?
 on 2/8/2013 4:45 PM

@Stuck at the 11th Step

I have had the same problem.

Some of the PowerShell cmdlets have been renamed or deprecated in between the Beta and RTM versions. The one you need is New-SPTrustedServiceTokenIssuer.

SharePoint 2013 cmdlets (as of December 2012):



PS: Thank you very much for the great article Eric!

 on 2/10/2013 3:04 PM

EDIT - that cmdlet should be New-SPTrustedSecurityTokenIssuer

.. as per the link there. NOT New-SPTrustedServiceTokenIssuer.

 on 2/10/2013 7:25 PM

error when running the powershell script on sharepoint server

I followed the blog but when I ran the powershell script
PS C:\Users\SPFarm> $web = Get-SPWeb http://dev2013:4448/
PS C:\Users\SPFarm> $metadataDocumentUrl = "https://myapp.oepsharepointapp.com/MetadataDocument.ashx"
PS C:\Users\SPFarm> $realm = Get-SPAuthenticationRealm -ServiceContext $web.Site
PS C:\Users\SPFarm> $trustedTokenService = New-SPTrustedServiceTokenIssuer -Name "RemoteAppTokenService" -MetadataEndPoi
nt $metadataDocumentUrl –confirm:$false

I am getting the below error
"New-SPTrustedServiceTokenIssuer : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

Please let me know where I am going wrong..

 on 6/6/2013 11:09 AM

RTM PowerShell Commands

For all those who have trouble with the PoweShell commands provided in the original post, those have been superseded by new commands for RTM.  Since there's some additional background information on getting S2S to work in production and development environments, rather than re-post everything here I updated that section with links to the proper resources.
Eric Shupps on 6/22/2013 2:46 PM

Can you access SharePoint data?

I have been trying to do an on-site provider hosted app and I can do a simple site that displays text or out side data.  If I try to access SharePoint data, I get a 401 error.  I haven't been able to find an example of anyone who has been able to actually access SharePoint data.

 on 1/31/2014 9:06 PM

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.


Body *

Comment Date *

Select a date from the calendar.
Enter the current date to prevent automated spambot comments.

Spam Prevention *

How many letters, not including spaces, does it take to spell "SharePoint Cowboy"?


photo of Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave Eric Shupps
611 S. Main St., Suite 400
Grapevine , TX , 76051 USA

Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave 

Eric Shupps LinkedIn Eric Shupps Twitter Eric Shupps Facebook Eric Shupps Google+



BinaryWave Eric Shupps eshupps The SharePoint Cowboy SharePoint monitoring SharePoint monitoring tool SharePoint metrics SharePoint administratrion SharePoint monitoring best practices SharePoint management SharePoint management tool SharePoint operations SharePoint operationsmanagement SharePoint administration SharePoint administration tool SharePoint SLA SharePoint service level agreement SharePoint operational intelligence SharePoint performance SharePoint performance monitoring SharePoint analytics SharePoint real-time SharePoint intelligence SharePoint ITIL SharePoint service operations SharePoint uptime SharePoint alerts SharePoint health SharePoint tools SharePoint metrics SharePoint diagnostics SharePoint SmartTrack SmartTrack Operational Intelligence

Copyright © 2013 BinaryWave, Inc. All rights reserved.
This site is brought to you by BinaryWave in cooperation with Eric Shupps Eric Alan Shupps eshupps @eshupps The SharePoint Cowboy. We hope you enjoy the SharePoint-related content on topics such as performance, monitoring, administration, operations, support, business intelligence and more for SharePoint 2010, SharePoint 2013 and Office 365 created by Eric Shupps The SharePoint Cowboy. We also hope you will visit our product pages to learn more about SmartTrack, Operational Analytics for SharePoint, SharePoint monitoring, and SharePoint administration, while also discovering great offers from our partners. Please visit the blog of Eric Alan Shupps, Twitter handle @eshupps, for more information on application development, the SharePoint community, SharePoint performance, and general technology topics. Eric Shupps Eric Alan Shupps eshupps @eshupps The SharePoint Cowboy is the founder and President of BinaryWave, a leading provider of operational support solutions for SharePoint. Eric Shupps Eric Alan Shupps eshupps @eshupps The SharePoint Cowboy has worked with SharePoint Products and Technologies since 2001 as a consultant, administrator, architect, developer and trainer. He is an advisory committee member of the Dallas/Ft. Worth SharePoint Community group and participating member of user groups throughout the United Kingdom. Eric Shupps Eric Alan Shupps eshupps @eshupps The SharePoint Cowboy has authored numerous articles on SharePoint, speaks at user group meetings and conferences around the world, and publishes a popular SharePoint blog at http://www.binarywave.com/blogs/eshupps.