The process of app authentication is what makes it possible to establish app identity and to map incoming calls from an app to a unique ID for the app which is tracked in the App Management Service database known as the app identifier. This, in turn, makes it possible for the SharePoint host environment to create and track app permissions by associating each one with an app identifier.
When you begin to think about app identity and app permissions, you should keep in mind that an app must be installed before it can be used and that the installation of an app creates a new app instance. For example, if you install the same SharePoint app into two different Office 365 tenancies, you will create two separate app identities as opposed to creating a single app identity that is recognized across tenancy boundaries.
SharePoint 2013 uses app identifiers that are made by combining a GUID that identifies the app instance together with the unique identifier for the hosting tenancy. Each time the SharePoint host environment creates an app permission, it must tag this permission with an app identifier to map it back to an installed instance of an app.
Note that much of the Microsoft documentation on app security often uses the generic term “realm” in place of the SharePoint-specific term “tenancy.” When you hear someone talking about the hosting realm for an app, he is really just talking about the tenancy in which the app was installed. The realm identifier is just the identifier for the current tenancy.
When you install a SharePoint-hosted app, the app identifier is created and configured automatically as part of the app installation process. After a SharePoint-hosted app has been installed, the SharePoint host environment is able to use internal authentication map CSOM and REST API calls from pages in the app web to an existing app identifier.
Managing app identifiers becomes more complicated with apps that use external authentication. In certain scenarios, you must explicitly create the app identifier by registering an app principal before the app is installed. It is the act of registering the app principal that actually creates the app identifier.
Understanding app permission policies
Now, it’s time to discuss what happens after a call from an app has been authenticated and mapped to an app identifier. That’s the point in time when the SharePoint host environment inspects permissions on the target object to determine whether the calling app should be able to succeed in what it is attempting to do. If the SharePoint host environment does not find that the correct set of permissions has been granted to the app, an access denied error will be returned to the caller.
As you might expect, an app must be granted the appropriate app permission to read or modify an object in a SharePoint site such as a list or a list item. Moreover, the default authorization policy for apps requires that the current user has the appropriate permissions, as well. Let’s look at a simple example to illustrate how the default app authorization policy works.
Imagine that an app has been granted write access to the host web. This means that it has the required permissions to create a new list item in the host site. However, for the app to create a new list item by using CSOM or the REST API, the current user requires the permissions to create a new list item, as well. When the app is launched by a site administrator, it can succeed in creating a list in the host web. If the app is launched by a user without write permissions such as a visitor, an attempt by the app to create a new list item will fail with an access-denied error.
A key point here is that the default app authorization policy used for calls from apps checks user permissions as well as app permissions. Therefore, you need to understand how the SharePoint host environment manages user permissions as well as app permissions before you can fully understand how the app authorization process works.
Reviewing how SharePoint manages user permissions
SharePoint 2013 doesn’t introduce any significant changes with respect to how it manages user permissions. If you understand how user permissions are managed in SharePoint 2010, you already know the important aspects of how they are managed in SharePoint 2013. The next few paragraphs will provide a quick primer for readers who need to solidify their understanding of how user permissions are managed.
The SharePoint host environment tracks user permissions at site-collection scope. Within the scope of a site collection there are three types of securable objects: sites, lists, and list items. The SharePoint host environment provides a user-interface experience for privileged users such as a site administrator to configure permissions on securable objects such as the top-level site, child sites, lists, and list items. The SharePoint host environment tracks these user permissions by adding them to access control lists (ACLs) that are maintained in the content database associated with the current site collection.
Within the scope of a site collection, user permissions are maintained within a hierarchy of securable objects. The securable object at the top of the hierarchy in any site collection is the top-level site. When a user attempts to access a securable object such as a list or list item, the SharePoint host environment checks to see if that securable object has its own unique ACL. If it does, the SharePoint host environment uses that ACL to determine whether to allow the current user access to the securable object. However, it is quite common that a securable object under the top-level site will not have its own unique ACL.
If a user attempts to access a securable object that does not have its own unique ACL, the SharePoint host environment moves up the hierarchy of securable objects to see if that securable object’s parent has a unique ACL. If the parent object does not have a unique ACL, the SharePoint environment moves further up the hierarchy until it finds a securable object that has its own unique ACL, which it can use to determine whether the user is authorized. The only securable object in a site collection that is guaranteed to have its own unique ACL is the top-level site. It’s not uncommon for a site collection to have just one ACL on the top-level site that is used to control access to all the child sites, lists, and list items within it.
Even though user permissions are most often managed within the scope of a site collection, it is also possible to grant permissions to a user by configuring a web app with a user policy. Creating a user policy in this manner provides a more efficient means to grant a user or an Active Directory group with access to all the site collections within a web app at once. For example, you can create a user policy to give a specific user read access to every site collection within a specific web app. It is important to note that a web app policy will override any user permissions that are configured at site-collection level.
In summary, user permissions are most commonly configured within the scope of a site collection. However, user policy can be created to quickly and effectively provide a user permission to access every site collection within a specific web app. Now, it’s time to move on and discuss how app permissions are configured and tracked by SharePoint 2013.
Requesting and granting app permissions
The SharePoint host environment configures a set of default permissions for an app to provide it with full control over its app web. This means that an app that creates an app web during installation always has a place to create new lists and document libraries without having to request additional permissions.
In many scenarios, the default permissions granted to an app will not suffice. Think about the common scenario in which an app is required to create a new list in the host site. In such a scenario an app will require additional permissions beyond the default app permissions.
An app acquires additional permissions by using permission requests. A permission request is an XML-based element that the app developer adds to the app manifest file. When a user or administrator attempts to install a SharePoint app that contains one or more permissions requests, the SharePoint host environment displays a prompt asking the installing user to grant or deny the permissions that the app has requested.
Figure 1 shows a screenshot of the page that the SharePoint host environment uses to prompt the person who is installing an app with permission requests. The user must either click the Trust It button to grant the app’s permission requests or click the Cancel button the deny them.
Figure 1. The user is prompted to grant or deny permission requests when an app is installed.
If the user clicks the Cancel button to deny the app’s permission requests, the SharePoint host environment aborts the installation. In other words, you must grant all the permissions requested by an app to install it. It is not possible to selectively grant some permissions an app has requested while denying other permission requests. Granting permission requests during app installation is an all or nothing proposition.
It is also important to note that a user must possess any permissions that are granted to an app. For example, an app might request write capabilities on the site collection or the tenancy in which the host web is located. The user must also possess write permissions on the hosting site collection or the hosting tenancy in order to grant that permission to an app during installation. Therefore, you can encounter scenarios in which a site administrator cannot install an app because the app is requesting permissions that the installing user does not possess.
If the installing user clicks the Trust It button to grant the app’s permission requests, the SharePoint host environment tracks these permissions in one or more of the SharePoint databases. The permissions that are specific to a site or a site collection are stored in the content database associated with the hosting site collection. Other types of permissions that are scoped above the site-collection level are stored in the App Management Service database.
Permission requests are created by adding <AppPermissionRequest> elements into the AppManifest.xml file within the scope of a top-level <AppPermissionRequests> element. Each <AppPermissionRequest> element must contain the Scope attribute and the Right attribute, as shown in Example 3-1.
Example 3-1. Permissions requests inside the app manifest
<AppPermissionRequests> <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" /> <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write" /> </AppPermissionRequests>
The Scope attribute is used to define the type of object for which the permissions are being requested. The value of the Scope attribute is a URI that contains several distinct parts. Consider the URI value of the Scope attribute from the previous listing.
The first part of the Scope URI defines the Product, which in this example is sharepoint. In some scenarios, an app might need to request permissions from another Microsoft product such as exchange or lync.
The second part of the Scope URI defines the permission provider, which in this example is content. SharePoint 2013 provides several other permission providers such as search, social, and bcs.
The final part of the Scope URI defines the target object type, which in this example is sitecollection/web. This is the target object type used to define the host web. Note that this Scope URI will also include any child sites below the host web.
The Right attribute defines the type of permission you are requesting. The SharePoint Foundation platform defines four common rights, which include Read, Write, Manage, and FullControl. The various teams that have created SharePoint 2013 have tried to use these four basic rights as consistently as possible. However, some permission providers have added rights beyond these four. For example, the search permission provider defines the QueryAsUserIgnoreAppPrincipal right.
<AppPermissionRequest Scope="http://sharepoint/search" Right="QueryAsUserIgnoreAppPrincipal" />
You can encounter scenarios in which the Scope attribute does not provide enough control to specify a certain type of object. For example, imagine that you have an app that needs the Manage right on all document libraries in the host web. The Scope attribute will let you define a more general target object type for all lists, including document libraries as well as all the other list types.
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Manage" />
However, the app that requests permissions with this Scope URI is requesting the Manage right on every type of list, which is more permissions than the app actually needs. You can add a <Property> element into an <AppPermissionRequest> element to filter the object type beyond what is possible by using the Scope URI alone. Here’s an example of adding the BaseTemplateId property with a value of 101 to filter the permission request to just document libraries:
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Manage" > <!-- add filter property to permission request --> <Property Name="BaseTemplateId" Value="101" /> </AppPermissionRequest>
In certain cases, you are not required to make direct edits to the AppManifest.xml file to add permission requests. The Permissions tab of the app manifest designer supplied by Microsoft Visual Studio 2012 makes it easy to add and configure permissions requests without having to work with the XML elements directly. The screenshot in Figure 2 shows what the Permissions tab looks like when you are configuring permission requests.
Figure 2. App permission requests are made by using the manifest designer in Visual Studio.
There are several different types of permissions that an app can request in SharePoint 2013. Table 1 provides a listing of the more common ones that can be used in app development in SharePoint 2013.
Table 1. Permission types in SharePoint 2013
|Object type||Scope URI||Rights|
|Tenancy||Read, Write, Manage, FullControl|
|Site collection||Read, Write, Manage, FullControl|
|Host web||Read, Write, Manage, FullControl|
|Lists||Read, Write, Manage, FullControl|
|Managed metadata||Read, Write|
|Social core||Read, Write, Manage, FullControl|
|Social tenancy||Read, Write, Manage, FullControl|
|Microsofeed||Read, Write, Manage, FullControl|
Requesting app-only permissions
For certain scenarios, the authorization system for SharePoint apps makes it possible for an app to call into the SharePoint host environment with app identity but not user identity. This relaxes the rules of app authorization because only the app needs permissions to access an object instead of both the app and the current user. In such a scenario, calls from an app are authorized by using app-only permissions.
App-only permissions are used for two specific scenarios. The first scenario is to elevate the permissions of the app above the permissions of the current user. For example, consider the case in which the app has been granted permissions to create a new list but the current user doesn’t possess the same permissions. By using the default app authorization policy, the app cannot create a new list. However, an app using app-only permissions would be able to create a new list even when the current user doesn’t have those permissions.
The second scenario for using app-only permissions involves an app that accesses the SharePoint host environment in a time when there is no current user. Imagine a scenario in which an app has been automated to run a job every night at midnight to update a set of documents in the host web. In this scenario there is no current user. However, the app still needs to be authorized to access the host web.
You must make a modification to the AppManifest.xml file if you require an app to make calls that are authorized by using app-only permissions. The way this is accomplished is by adding the Allow AppOnlyPolicy attribute to the <AppPermissionRequests> element in the app manifest.
<AppPermissionRequests AllowAppOnlyPolicy="true" > <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Manage" /> </AppPermissionRequests>
Adding the AllowAppOnlyPolicy attribute to the <AppPermissionRequests> element alone is not enough to execute calls from an app run with app-only policy. You must additionally create an access token with app identity but not user identity.
It is worth noting that running with app-only permissions is only possible when using external authentication. Executing calls from an app with app-only permissions is not possible when using internal authentication. Therefore, running with app-only permissions is not possible from SharePoint-hosted apps. Calls from a SharePoint-hosted app always require that app permissions and user permissions succeed.