2.2 Understanding how SharePoint 2013 authenticates apps
One of the biggest limitations with
respect to developing and deploying SharePoint solutions revolves
around security and the inability to configure permissions for a
SharePoint solution independently of user permissions. The underlying
problem is that SharePoint solutions are not recognized as first-class
security principals.
From the very beginning of the design phase, Microsoft created the
SharePoint app model so that apps could be authenticated and recognized
as first-class security principals. The obvious benefit here is that
app permissions can be configured independently of user permissions. To
achieve this goal, however, Microsoft had to build new infrastructure
into SharePoint 2013 that is capable of authenticating incoming calls
from apps and tracking app identity.
If you already have a firm understanding of how SharePoint
authenticates users, you should not assume anything is the same with
respect to how it authenticates apps. The authentication mechanisms
used for apps are completely different. SharePoint 2013 supports three
different types of app authentication:
-
Internal app authentication
-
External app authentication using OAuth
-
External app authentication using S2S High-trust
Note that app authentication is supported only for scenarios in which an app is calling to the SharePoint host environment by using client-side object model (CSOM) or the REST API. SharePoint 2013 does not support app
authentication in any other endpoints beyond these. This means it is
not possible to develop and deploy a set of custom web service entry
points that support app authentication.
Whenever the SharePoint host environment receives an incoming call
that targets either CSOM or the REST API, it must decide how to
authenticate the call. First, the SharePoint host environment must
determine whether the call was initiated by a user or by an app. If the
call was initiated by an app, the SharePoint host environment must also
determine whether to use internal authentication or external
authentication.
The SharePoint host environment inspects an incoming request to see
what type of security token has been passed. If an incoming call
contains a special type of security token used for app authentication
known as an access token,
the SharePoint host will know the call was made by an app. In this
scenario, the SharePoint host environment authenticates the caller by
using external app authentication.
If the SharePoint host environment sees a SAML token in an incoming
request, it knows that there is already an authenticated user
associated with the call. However, at this point the SharePoint host
environment cannot yet assume that call was initiated by a user as
opposed to an app. The SharePoint host environment must additionally
inspect the target URL to determine whether the call was initiated by a
user or by an app.
If an incoming request with a SAML token maps to a target URL within a domain associated with an app web, the SharePoint
host environment will assume that the call was made by an app. In this
scenario, the SharePoint host environment uses internal authentication
to authenticate the app and establish its identity. If an incoming
request with a SAML token does not map to a target URL within a domain
associated with an app web, the SharePoint host environment will know
that the call was not made by an app and it will initialize the call
context by using just the user’s identity.
The diagram in Figure 1
shows four different scenarios for CSOM and REST API calls that target
a SharePoint 2013 site. The first call (at the top) is a client-side
CSOM or REST API call that has been executed from a page in the host
web. The SharePoint host environment authenticates this type of call by
using standard user authentication, which results in the creation of a
SAML token.
The second call in Figure 1
(second down from the top) is similar to the first call in that the
SharePoint host environment uses the standard user authentication
process to create a SAML token with the user’s identity. However, the
second call is treated differently because it targets the domain of an
app web. The fact that this call targets an app web is what leads the
SharePoint host environment to authenticate the calling app by using
internal app authentication.
The third and fourth calls in Figure 1
both carry an access token instead of a SAML token. When the SharePoint
host environment sees an access token in an incoming CSOM or REST API
call, it can assume that it should authenticate the app by using
external authentication. The difference between the third call and the
fourth call involves whether the access token carries a user identity
along with the app
identity. The third call is an example of the more common scenario in
which the access token includes the identity of the current user in
addition to the identity of the app. The fourth call shows an example
of an access token that contains app identity but no user identity. The
use of this type of access token containing app-only identity is not as
common but is useful in specific scenarios.
Using Internal Authentication
The most common scenario in which the SharePoint host environment
uses internal authentication involves client-side calls that are
initiated from pages in an app web. The SharePoint host environment creates an isolated domain whenever it creates an app web during app installation. The cross-site
scripting (XSS) restrictions in the browser ensure that CSOM and REST
API calls made from pages in the app web target endpoints within the
same domain. This makes it possible for the SharePoint host environment
to map an incoming call that targets an app web domain to a specific
installed instance of an app.
When the SharePoint host environment has determined an incoming call
targets a URL that maps to a specific app, it uses internal
authentication to initialize the call context with the app’s identity.
Because this scenario involves an incoming call with a SAML token, the
SharePoint host environment can further initialize the call context
with the user’s identity in addition to the app’s identity.
SharePoint-hosted apps
always use internal authentication. That’s because all the pages for a
SharePoint-hosted app must be added to an app web. This means that the
SharePoint host environment can always use internal authentication to
authenticate any CSOM or REST API call from a SharePoint-hosted app.
The app manifest for a SharePoint-hosted app should be configured to
support internal authentication. This is accomplished in the app
manifest by adding an <AppPrincipal> element with an inner
<Internal> element.
<AppPrincipal>
<Internal />
</AppPrincipal>
SharePoint-hosted apps are not the only type of app that can use
internal authentication. A second scenario in which internal
authentication is used involves client-side calls initiated from a
cloud-hosted app using the cross-domain library. The cross-domain
library is a JavaScript library included with SharePoint 2013 with
which a cloud-hosted app can issue client-side calls to the SharePoint
host environment from pages in the remote web.
The cross-domain
library has been added to SharePoint 2013 to address the scenario in
which a cloud-hosted app calls back into the SharePoint host
environment by using client-side calls instead of server-side calls.
For example, your user interface design might favor client-side calls
over server-side calls to give pages in the remote web more of a web
2.0 look and feel.
In a different scenario, you might be required to use the
cross-domain library when deploying a cloud-hosted app in an
environment in which a firewall is blocking server-side code running in
the remote web from calling back to the SharePoint host environment.
The problem caused by the firewall can be solved by using client-side
calls initiated from pages served up by the remote web. This allows the
app to call back to the SharePoint host environment from the browser
running on the user’s computer or device.
Note that CSOM and REST API calls executed by using the cross-domain
library must be routed through the app web of the calling app. Although
cloud-hosted apps do not usually require an app web, this is a scenario
in which they do. Therefore, you must configure a cloud-hosted app to
create an app web if you plan to use the cross-domain library.
The high-level architecture of the cross-domain library involves a proxy page in the LAYOUTS directory named AppWebProxy.aspx.
When you execute a request by using the cross-domain library, the
library provides JavaScript code that sends the request to the proxy
page AppWebProxy.aspx by
using a URL scoped inside an app web. The proxy page responds by
returning a response that includes the requested data in an IFrame
along with some low-level JavaScript code that makes it possible for
JavaScript code in the cross-domain library to extract this data by
using the HTML5 postMessage API.
The cross-domain library provides two valuable yet distinct aspects.
First, it abstracts away all the grungy code required to get around the
browser restrictions for cross-domain scripting. Second, it provides
the SharePoint host environment with the ability to authenticate calls
from an app by using internal authentication.
Note that cross-domain library calls are authenticated by using
standard user authentication. That means that cross-domain library
calls are passed to the app web with a SAML token. As in the case with
client-side calls initiated from pages inside the app web, the
SharePoint host environment can inspect the sender’s URL with a
cross-domain library call and map the caller’s URL to a specific
installed instance of an app.
Suppose that you wanted to create a cloud-hosted app that supports
internal authentication but not external authentication. To accomplish
this, you should configure the app manifest with an
<AppPrincipal> element with an inner <Internal> element,
just like a SharePoint-hosted app, but you should additionally add the AllowedRemoteHostUrl attribute, as well.
<AppPrincipal>
<Internal AllowedRemoteHostUrl="~remoteAppUrl" />
</AppPrincipal>
Note that the ability for a cloud-hosted app to make client-side
calls by using the cross-domain library is not limited to apps whose
app manifest contains an <Internal> element with the AllowedRemoteHostUrl attribute. A cloud-hosted app that has been configured to use external
authentication can also make client-side calls from pages in the remote
web and those calls will be authenticated by using internal authentication.
Using external authentication
There are many scenarios in which a cloud-hosted app makes CSOM and
REST API calls to a SharePoint host that cannot be authenticated by using
internal authentication. In these scenarios, the app must be configured
to use external authentication. The key difference with external
authentication is that the app must include an access token when
calling to the SharePoint host environment.
There are two ways by which you can configure an app to use external authentication. The first is based on OAuth authentication,
which is the only type of external authentication supported in the
Microsoft Office 365 environment. The second way is based on
server-to-server authentication, which is only supported in on-premises
farms.
OAuth
authentication requires integration with Windows Azure ACS. That means
the remote web of the app requires access to Windows Azure ACS running
in the cloud to acquire access tokens. However, it is relatively simple
to set up because the required integration between the Office 365
environment and Windows Azure ACS is automatically configured for you.
Your primary requirement when configuring OAuth authentication is to register an app security principal that will have an identifying GUID known as a client ID.
The details of how to configure
Server-to-server
(S2S) authentication doesn’t require an app to access Windows Azure ACS
or any other authentication service in the cloud. The only computers
involved in the S2S authentication process are the web server running
the remote web and a SharePoint web server in an on-premises farm. This
makes this form of external authentication ideal for scenarios in which
you want to avoid dependencies on servers across the Internet where
everything needs to run inside a single, private network.
S2S authentication is configured by establishing a trust between the
web servers in an on-premises SharePoint farm and the web server
running the remote web of a provider-hosted app. This trust is created
by using an x.509
certificate with a public/private key pair. At a high level, S2S
authentication is based on the app creating an access token and signing
it with the private key. Web servers in the SharePoint farm then
authenticate these access tokens by using the public key.
At this point, you should have a high-level understanding of how
external authentication works. External authentication can be
configured by using either OAuth authentication or S2S authentication.
In either case, the remote web passes an access token by which the
SharePoint host environment can authenticate the app and establish the
app’s identity.
Although an access token is required to contain information about
the app’s identity, it can optionally contain information about the
identity of the current user, as well. Therefore, some access tokens
carry information about the identity of both the app and the current
user, whereas other access tokens only carry information about the
identity of the app.