Tips and FAQ: OAuth and remote apps for SharePoint

apps for SharePoint

Get tips and answers to frequently asked questions about apps for SharePoint that run in remote web applications and communicate back to SharePoint 2013.

Last modified: April 07, 2014

Applies to: apps for SharePoint | Office 365 | SharePoint Server 2013

This article assumes that you are familiar with ASP.NET and how to configure Internet Information Services (IIS)—for example, configuring IIS to use a specific port.

Note Note

This article is not a guide about how to create a provider-hosted app. For a walkthrough about how to create a provider-hosted app, see How to: Create a basic provider-hosted app for SharePoint.

This section highlights questions related to retrieving app information after app registration.

How do I retrieve a list of app principals?

You can retrieve a list of app principals from the following page:


How do I retrieve app registration information?

You can look up app registration information for an app that you have registered. The lookup is at http://yourServerName/_layouts/15/appinv.aspx.

To do a lookup, you have to use the app Id that you used to register your app. The lookup returns the following corresponding information for that particular app Id:

  • Title

  • App domain

  • Redirect URL (that is, the redirect URI)

The lookup does not return the client secret (also known as app secret) value.

This section highlights questions related to the AppManifest.xml file. For more information about the elements and attributes in the AppManifest.xml file, see Explore the app manifest and the package of an app for SharePoint.

What is the URL in the <StartPage> element?

Your server name (and port, if you use a particular port) in the <StartPage> element in AppManifest.xml must match the following:

  • The app domain value

  • The URL binding configuration that you use in IIS Manager

For example, if you configure your URL binding in IIS as http://yourServerName:4186/, and your app domain value is yourServerName:4186, then, the <StartPage> element value should be the following:


If you use the following values, the callback into SharePoint from your remote app fails (for example, in the case where your ASP.NET web application is on the same server as SharePoint, in a testing or development environment):

  • <StartPage>https://yourServerName:43300/Home.aspx?{StandardTokens}</StartPage>

  • <StartPage>http://localhost:4186/Home.aspx?{StandardTokens}</StartPage>

Note Note

If you use ports (for example, during the development phase where you might use the same server for your ASP.NET web application and SharePoint Server), use a port that is not well known for your web application URL.

What are the elements and attributes of the AppManifest.xml file?

Ensure that your app manifest has an <AppPrincipal> element instead of an <AppPrincipal> property. Otherwise, you might encounter the following error when trying to deploy your app by using Visual Studio:

Error occurred in deployment step 'Install SharePoint App': There were errors when validating the App Package.

Your AppManifest.xml file should have the following elements. The values shown are examples.

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

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

This section highlights questions related to using the Web.config file.

What are the app settings of the Web.config file?

Ensure that the Web.config file for your web application has an <appSettings> element. If it does not, add the <appSettings> element and section. Your Web.config file should also have two keys under the <appSettings> element.

Note Note

The ClientId key is the same value as the ClientId property of the <RemoteWebApplication> element in the AppManifest.xml file. The values shown in the following xml are examples.

    <add key="ClientId" value="ce4030a4-99cb-43ee-abfd-df5ff47c640c" />
    <add key="ClientSecret" value="lXME/6H9mSDvdeDl04rGFDPbwfTSmuj0mle7dkeuAk4=" />

The following is an example of a complete Web.config file.

<?xml version="1.0"?>
  For more information about how to configure your ASP.NET application, visit
      <compilation debug="true" targetFramework="4.0" />
    <add key="ClientId" value="f8c9f105-435a-4179-b022-4eafaee4100d" />
    <add key="ClientSecret" value="rt0ZIDCr9I89ZJv8xBD55OJiGSANe6TSIuiUFRIXQXw=" />

This section highlights questions related to URL issues and calling back into SharePoint.

My web application has problems talking back to SharePoint. What should I check?

If your remote web application has problems communicating back to SharePoint, check your remote web application settings and bindings settings in IIS. For example, ensure that the URL (and port) for your remote web application is the same in the following:

  • The app domain value created using the appregnew.aspx page.

  • The URL binding configuration that you use in IIS. (Use the value that matches the app domain value.)

  • Your web application server name (and port) in the <StartPage> element in the AppManifest.xml file. They should be the same as in the app domain value.

Note Note

If you use ports (for example, during the development phase where you might use the same server for your ASP.NET web application and SharePoint Server), use a port for your web application URL that is not well known.

What URLs should I hard-code into my app to point to my cloud server?

If you have a provider-hosted app, you should hard-code the URL for the StartPage for your app, and any client and remote event receiver URLs. All these URLs have to be Secure Sockets Layer (SSL), and they must be on the domain that is registered for your app Id.

Should I register the CNAME alias or the actual underlying URL that is hosting the app?

Let's say the scenario is as follows:

  • You are hosting your app cloud pieces on Microsoft Azure under

  • You then set up a DNS CNAME alias,, to point to

  • You also registered your SSL certificate for, which is installed on

  • Your StartPage for your app for SharePoint and other actions point to

The URL to register for your app is the URL that goes into the StartPage element in the Appmanifest.xml. In this case, it is

I get the error "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel." What should I do?

This error is an SSL handshake issue, not an OAuth issue. If you are using SSL, you must make sure that the certificate you are using is trusted by SharePoint, and that the certificate matches the endpoint name.

This section highlights questions related to appredirect.aspx file.

What should I use the app redirect page for?

If, for example, you store the context token in a cookie, you can use appredirect.aspx to get a new context token if you get an expired one from a user's cookie.

How do I use an app redirect page to get the context token?

From an ASP.NET page (with TokenHelper.cs in your project), you can use the following code to get the context token.

Response.Redirect(TokenHelper.GetAppContextTokenRequestUrl(sharePointUrl, Server.UrlEncode(Request.Url.ToString())));

The GetAppContextTokenRequestUrl method constructs a URL pointing to appredirect.aspx on SharePoint. Therefore, if you are using the GetAppContextTokenRequestUrl method, you are already using app redirect. You don’t need to have a separate page. You can put the code directly into pageA.aspx.cs and use pageA.aspx as the redirect URI so that once the browser gets the context token from SharePoint, it will come directly back to pageA.aspx.

How do I use the appredirect page in the URL?

You can use the app redirect page by URL-encoding, as follows:

https://SharePointServerName/_layouts/15/appredirect.aspx?client_id=<the app client Id>&redirect_uri=URL you want to redirect to

This section highlights questions about when to use redirect URIs in apps.

Do I need a redirect URI?

The redirect URI is used only in apps that request permission on the fly. If your app is always launched from within SharePoint 2013, you don’t need a redirect URI, and you don’t have to register a redirect URI. The redirect URI field in appregnew.aspx is optional.

This section highlights questions related to OAuth tokens.

What is a context token?

A context token is specific to a configuration that uses Microsoft Azure Access Control Service (ACS). For more information about context tokens, see OAuth authentication and authorization flow for cloud-hosted apps in SharePoint 2013.

What is an access token?

What is a refresh token?

Should the context token string be stored in a cookie so that it can be used for other page requests directly from the provider-hosted app?

Storing the context token string in a cookie is fine. But, a context token expires after 12 hours or so. You must be ready to use the appredirect.aspx to get a new context token if you get an expired token from a user's cookie.

There are other options for handling token information. Some options depend on the server platform you have chosen. For example:

  • You can use session state or the equivalent capability on your server platform.

  • You can extract the immutable cache key from the context token and put the cache key in a cookie or session. Then you can use a server-side cache (for example, the default ASP.NET cache, Windows Server AppFabric Caching, Microsoft Azure Caching Service, memcached, or a database) to store information (for example, user profile information, access tokens, refresh tokens, and so on) between requests or between sessions.

What is the cache key value made up of? How is it unique?

The cache key is an opaque string that is unique to the combination of user, app, and tenant. Before it is encrypted, it has the following form, where Realm is the GUID, within ACS, of the on-premises SharePoint web application or the SharePoint Online tenancy.

UserNameId + "," + UserNameIdIssuer + "," + ApplicationId + "," + Realm

The cache key does not contain site URL information. Each SharePoint Online tenant (or SharePoint web application) has a unique realm, so, the cache key is unique for each (user, app, tenant/web application) combination. The following is an example of a context token.

bsH6SUtGB8aCB0xdyp0OnY8XNEbPTyVRkSR2Cln8OjvuwH+bNBtL5skIvbBFEF1fpkAxroRZxwPcTTa4GImH89Q+", "isbrowserhostedapp": "true"}

That is, in the previous example, the cache key value is:


How do I retrieve the context token?

If you call TokenHelper.ReadAndValidateContextToken(contextTokenString, Request.Url.Authority), you get back a SharePointContextToken object, which is the context token. The following code shows how you can retrieve a context token (with TokenHelper.cs in your project).

SharePointContextToken contextToken =
                    TokenHelper.ReadAndValidateContextToken(contextTokenString, Request.Url.Authority);

What information does the context token contain?

The following is an example of a context token value. The small JavaScript Object Notation (JSON) object at the top contains metadata about the token. (White space has been added for readability.)

 "isbrowserhostedapp": "true"

Table 1 describes the claims and information contained in a context token.

Table 1. Context token claims and information



Corresponding value in sample context token


Short for "audience", meaning the principal for which the token is intended. The format is app client Id/app URL@SharePoint realm, where SharePoint realm is the GUID, within ACS, of the SharePoint Online tenancy or the on-premises SharePoint web application that is sending the context token to the remote web application.



Short for "issuer". It represents the principal that created the token. The GUID 00000001-0000-0000-c000-000000000000 is ACS. The format is ACS GUID@SharePoint realm.



Short for "not before". It represents the time at which the token starts being valid, in seconds since midnight, January 1, 1970.



Short for "expiration". It represents the time the token expires.



See the question about cache key in this section.



The application principal identity for SharePoint 2013, Exchange 2013, Lync 2013, or Workflow. It has the form GUID of principal@SharePoint realm, where GUID of principal is the constant ID of the application principal.



The refresh token for the app.



A Boolean field that specifies whether the request to the app that contains the context token is coming from a browser (true) or from a remote event receiver (false).


What information does an access token contain?

The following is an example of the payload portion of an access token value.

 "aud": "00000003-0000-0ff1-ce00-000000000000/",
 "iss": "00000001-0000-0000-c000-000000000000@040f2415-e6e3-4480-96ce-26ef73275f73",
 "nbf": 1377549246,
 "exp": 1377592446,
 "nameid": "2303000085ff9abc",
 "actor": "00000003-0000-0ff1-ce00-000000000000@040f2415-e6e3-4480-96ce-26ef73275f73",
 "identityprovider": "urn:federation:microsoftonline"

The aud, iss, nbf, and exp claims are exactly the same as in a context token as described above. The actor claim is the same as the appctxsender claim in the context token. The nameid and identityprovider claims are described in the following table.

Table 2. Access token claims and information



Corresponding value in sample access token


A unique identifier for the user for whom the token is issued. The format varies depending on the identity provider. In this example, the provider is Microsoft Online, but if it was Active Directory, the ID would look like "s-1-5-21-2127521184-1604012920-1887927527-415149".



The unique name of the identity provider as registered with the Internet Assigned Numbers Authority (IANA).


How do I calculate the exact time and date from the value of nbf and exp?

The nbf and exp claims are in the format specified by the JWT specification. They are written as the number of seconds since Jan 1, 1970. You can use code similar to the following to evaluate them.

DateTime exp = new DateTime(1970,1,1).AddSeconds(1335822895);

I want to protect the svc for my apps from users who are not from SharePoint. I check the user’s legitimacy at the app's entry point (by creating ClientContext), but my WCF service can be called by anyone. Should I create ClientContext from a context token on every svc method call?

You should not need to create a full client context. You can just call TokenHelper.ReadAndValidateContextToken() to retrieve the context token. You can also check that the actor claim of the token starts with 00000003-0000-0ff1-ce00-000000000000, if you want to make sure that it is SharePoint 2013 (and not, for example, Exchange 2013, Lync 2013, or Workflow). If you want to do additional validation that requires a call back to SharePoint, you can cache the fact that you have done this validation for a particular user by using the token's "CacheKey" so that you have to do this only once (or once every certain period of time).

Is it okay to keep AppContext (obtained from a SharePoint POST request) as a hidden input field on the page?

Putting the AppContext value in a hidden field or in a cookie is fine. If you have a server-side cache, you can also consider extracting the "CacheKey" from the context token, putting that in the cookie or hidden input field, and keeping the refresh token (and even the access token) and other information in a server-side cache (that way you can make this cache durable between sessions).

How long is a refresh token valid?

Currently, a refresh token is good for six months.

I store the access token and host URL in cookies so they can be used on other page requests. But the user took a break and the access token expired. What should I do?

Instead of storing the access token in the cookie (which is not very secure), store the refresh token instead. The refresh token is good for six months and can be used to get a new access token anytime, as long as the refresh token is still good.

In what scenario should I discard an old unexpired refresh token that is still valid and use a new one?

If an app receives a new refresh token from SharePoint, the app should always replace the cached refresh token with the new one. This guarantees that the app extends the lifetime of its cache as long as possible.

This section highlights questions related to permission request scopes for apps.

What are the permission request scopes and available rights for list, library content, and other features?

This section highlights questions related to OAuth authorization policy types.

What is the difference between the app-only policy and the user + app policy?

Is there a way to grant or deny the right to launch an app?

Grant/deny of an app is only at install time. Permission requests are specifically permissions the app is requesting of the user. The ability for a user to launch the app is determined by the user's ability to browse the site that hosts the app. As long as users can browse the hosting site, they can launch the app.

The app can, of course, make further authorization decisions based on the identity of the user, their permissions to the parent web, or their membership in certain SharePoint groups.

This section highlights questions related to debugging.

Using Fiddler

For information about Fiddler, see the next section about high-trust apps (server-to-server apps) on-premises.

This section highlights questions related to high-trust apps that run on SharePoint 2013 on-premises.

I'm getting a 401 unauthorized error when running a high-trust app. What should I do?

If you are getting a 401 unauthorized error at the following:

ClientContext clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(sharepointUrl, Request.LogonUserIdentity); 


And the exception looks similar to this:

[WebException: The remote server returned an error: (401) Unauthorized.]
   System.Net.HttpWebRequest.GetResponse() +8515936
   Microsoft.SharePoint.Client.SPWebRequestExecutor.Execute() +178
   Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb) +1427
   Microsoft.SharePoint.Client.ClientRequest.ExecuteQuery() +270
   Microsoft.SharePoint.Client.ClientRuntimeContext.ExecuteQuery() +146
   Microsoft.SharePoint.Client.ClientContext.ExecuteQuery() +666
   S2STestWeb.Default.Page_Load(Object sender, EventArgs e) in c:\MyFiles\HightrustTest\HightrustTestWeb\Default.aspx.cs:28
   System.Web.UI.Control.LoadRecursive() +71
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3178

Upon debugging the code, you can see that the access token and the ClientContext object are constructed successfully.

Possible issues and resolution:

  • There is no user profile created for the user the app is acting on behalf of. Ensure that you have created a user profile for the user who is accessing the remote app.

  • Your app does not have permission to the resource you are trying to access. Ensure that the following Windows PowerShell cmdlet has been run (with appropriate values for $web and $appPrincipal) for the app Id you are using and the SharePoint web you are trying to get access to:

    Set-SPAppPrincipalPermission -Site $web -AppPrincipal $appPrincipal -Scope Site -Right FullControl
  • Your .NET web application is accepting anonymous requests. This means there is not a real user identity in the access token. Ensure that the root directory of your remote web app has anonymous access disabled in IIS. You can also check this by debugging your remote web application, and checking the value of Request.LogonUserIdentity in the default.aspx.cs file to ensure that it's not an anonymous user.

  • Your app certificate was not added to the trusted certificate store.

All of these issues can result in the same 401 unauthorized error. Here are some useful steps to help you debug:

  • You can install Fiddler and add the following markup to your Web.config file to make requests from your remote web app go through this proxy. This way, you can capture a Fiddler trace and see the full response from SharePoint when you get a 401 unauthorized error.


    Ensure that you remove this markup if you are not running Fiddler. If you don't remove the markup, your app won't be able to make HTTP requests.

          <proxy usesystemdefault="False" bypassonlocal="False" proxyaddress="" />
  • After you have Fiddler installed and ready to use, you can also check the response headers from SharePoint, which will include a request GUID. This request GUID is a correlation Id you can look up in the logs to find any log errors associated with that request.

How do I get a context token for a high-trust app?

In a server-to-server on-premises setup for a high-trust app, there is no context token, even if you use appredirect.aspx. The context token is specific to a configuration that uses Azure ACS. If you are using a server-to-server setup, your web application has to authenticate the user the same way that SharePoint does.

This section highlights questions about miscellaneous OAuth-related issues.

When trying to read a file using the HTTP DAV method, I get an error. What should I do?

HTTP DAV does not work with OAuth. Use the following code instead.

File f = clientContext.Web.GetFileByServerRelativeUrl( url);
ClientResult<Stream> r = f.OpenBinaryStream();

Is there a way to forward OAuth authorization to other components in different domains, or to configure OAuth for multiple URIs?

Let's say you have the following scenario:

Your cloud-hosted app UI calls back into SharePoint 2013 via OAuth. Downstream in the process, when a user has submitted a job via the autohosted app UI to the back-end components of your platform, one of the components in that platform will retrieve files from SharePoint 2013 and write output back to SharePoint 2013. The component doing the SharePoint file reading/writing is not hosted in the same domain as the UI.

How do you have components in different domains talk to SharePoint via OAuth when these components are not in the same domain as the cloud-hosted app UI? Domain is only important when you fetch/refresh the OAuth access token. After you have the access token, operations in the background can use it, and it does not matter what domain the call is being issued from.

Is the SharePoint 2013 principal value constant?

The SharePoint 2013 principal value, 00000003-0000-0ff1-ce00-000000000000, is constant for all apps.

Is the app Id and app secret constant across all tenants for a given app?

App Id and app secret are constant across all tenants for a given app if your app is a remote web application and you register the app in the Seller Dashboard.

Are realms unique?

Realm is unique to each tenant in Office 365 or to each SharePoint farm on-premises. It is possible to discover the realm at run time. So, it is not necessary to cache this information between requests, but it will cost you an extra round trip to SharePoint each time you want to look it up. If you use code similar to TokenHelper.GetRealmFromTargetUrl with the site URL, and cache the result per site (or even per site and per user), you can use this later without making the extra call.

How do I turn off the HTTPS requirement for OAuth during development?

OAuth now requires SharePoint to run HTTPS (not only your service, but SharePoint too). You can still get a context token, and you can exchange it for an access token, but you get a 403 (forbidden) message when attempting to make a call to SharePoint.

You can turn off the HTTPS requirement during development using the following Windows PowerShell cmdlets.

$serviceConfig = Get-SPSecurityTokenServiceConfig
$serviceConfig.AllowOAuthOverHttp = $true

To turn the HTTPS requirement back on later, use the following Windows PowerShell cmdlets.

$serviceConfig = Get-SPSecurityTokenServiceConfig
$serviceConfig.AllowOAuthOverHttp = $false

This section highlights questions related to social features.

How do I retrieve a user's identity and properties?

What is the usage for the different social features and permission request scopes?

The tenant permission (http://sharepoint/social/tenant) gives access to all profiles. Read access is currently required to use microfeeds or to follow content APIs.

The required permission scopes for microfeeds are:

  • http://sharepoint/social/core

  • http://sharepoint/social/microfeed

  • http://sharepoint/social/tenant

The required permission scopes for followed content are:

  • http://sharepoint/social/core

  • http://sharepoint/social/tenant

Note Note

For more information about social features app permission request scope, see Social and collaboration features in SharePoint 2013.

How do I get the user profile properties of people following me?

The following code example shows how to get the user profile properties of people who are following you.

string contextTokenString = TokenHelper.GetContextTokenFromRequest(Request);

            if (contextTokenString != null)
                Uri sharepointUrl = new Uri(Request.QueryString["SP.Url"]);

                ClientContext clientContext = TokenHelper.GetClientContextWithContextToken(sharepointUrl.ToString(), contextTokenString, Request.Url.Authority);

                PeopleManager peopleManager = new PeopleManager(clientContext);
                ClientObjectList<PersonProperties> peopleFollowedBy = peopleManager.GetMyFollowers();
                clientContext.Load(peopleFollowedBy, people => people.Include(person => person.PictureUrl, person => person.DisplayName));

                foreach (PersonProperties personFollowedBy in peopleFollowedBy)
                    if (!string.IsNullOrEmpty(personFollowedBy.PictureUrl))
                        Response.Write("<img src=\"" + personFollowedBy.PictureUrl + "\" alt=\"" + personFollowedBy.DisplayName + "\"/>");


For more information about social features app permission request scope, see Social and collaboration features in SharePoint 2013.

© 2014 Microsoft