Security in SharePoint Apps – Part 8

PREVIOUS:  Security in SharePoint Apps – Part 7

For this, the very last in the series, I just wanted to briefly talk at a high level about the process you should be doing when developing an App for a SharePoint site that uses SAML (or FBA for that matter).  I’ve already written a detailed post on the “how” you develop an application for this scenario, I just want to cover the high level overview because I’ve seen some folks getting stuck trying to wrap their head around this and figure out how to even get started.  So here are the basic steps when you need to build this out.

The first caveat here is I’m going to assume that you already have SharePoint up and running, and one or more web applications configured to use SAML authentication.  Also…I strongly recommend that at least at first, you use both Windows and SAML authentication on the web site where you will be doing your development.  It will greatly simplify the process while you are trying to get everything up and running.  Now…knowing that, here’s how you can think about tackling this:

  • Phase 1 – A working SharePoint App.  During this phase you’re going to create a new SPTrustedSecurityTokenIssuer, if you don’t already have one.  That’s because in order to use Apps with SAML you must use high trust; low trust will not work.  Once you have that in place you should create a new SharePoint App using the provider hosted option with high trust.  At this point you should just hit F5 to validate that you can trust the App and the App security is configured correctly so that you can use CSOM to retrieve the web site title.  NOTE:  I have periodically experienced problems when trying to use Visual Studio to deploy an App to a SharePoint site that uses SAML.  If that happens, you should use appregnew.aspx to create a client ID for your application, then hard-code that client ID into your AppManifest.xml and web.config files in your solution.  You can get to appregnew.aspx in the _layouts directory; for example, if your site is at https://sps, then you would navigate to https://sps/_layouts/15/appregnew.aspx.
  • Phase 2 – A functional provider hosted app.   What I mean by “functional” is that you should create an ASP.NET application that is going to be your provider hosted app.  You should go through all of the steps necessary to configure it to use SAML authentication, including setting up a relying party for it in ADFS.  You should be able to independently navigate to that ASP.NET site and successfully authenticate using SAML authentication before you ever try and integrate with SharePoint.  Generally speaking you should find it easier to configure your provider hosted web to use SAML authentication if you use the Identity and Access tool for Visual Studio.  You can download it from http://visualstudiogallery.msdn.microsoft.com/e21bf653-dfe1-4d81-b3d3-795cb104066e.   Once this phase is completed, you should have a working SharePoint site, a working App, and a working ASP.NET site that will become your provider hosted app – it just isn’t hooked up to SharePoint yet.
  • Phase 3 – A working provider hosted app.  At this point you’re going to hook up your ASP.NET app to SharePoint so you can use it to start making CSOM calls.  I’ve actually already written a fairly detailed set of instructions about how you can take the web application that Visual Studio creates for you and port it over to a full blown ASP.NET app; look at this post for more details:  http://blogs.technet.com/b/speschka/archive/2013/06/12/converting-a-vs-net-web-for-a-provider-hosted-sharepoint-app-to-a-full-blown-web-or-console-application.aspx.   Follow the guidance in there for getting your ASP.NET application hooked up as a provider hosted app.  Then you can use my original post on building Apps for SharePoint sites that use SAML and FBA:  http://blogs.technet.com/b/speschka/archive/2012/12/07/using-sharepoint-apps-with-saml-and-fba-sites-in-sharepoint-2013.aspx.   At this point you should have end-to-end connectivity, authorization and authentication and can access content in your SharePoint site.

With that, I’ll conclude this series.  This topic is one that I expect will continue to rapidly evolve over the next few years because let’s face it – SharePoint Apps are really a v1 release, so they’re going to keep getting better and open up many new opportunities.  I hope you find this series helpful as you build your SharePoint Apps and figure out how make the security model work for you.

Security in SharePoint Apps – Part 7

PREVIOUS:  Security in SharePoint Apps – Part 6

In this part of the series, I’m going to shift gears a bit and talk about high trust apps and the plumbing that goes along with them.  As I’ve explained somewhat earlier in this series, one of the big differences between low trust and high trust apps is that high trust apps do not get a context token.  The context token contains information about the App and the user, so without that, a high trust app identifies both itself and the user to SharePoint.

The first issue to overcome is to get SharePoint to trust your App when it comes asking for content and says “hey I’m Contoso App and I’m asking for data on behalf of Steve”.  Without checks in place to make sure the request is coming from a trusted source, your farm would be wide open to information leaks.  In order to prevent that, just as you do with low trust Apps, high trust Apps have to use a trust broker.  For a high trust scenario, that “broker” is really just an X509 certificate.  I’ve been asked a few times about what kind of certificate it needs to be.  In all honestly, I haven’t really found one that doesn’t work yet.  My only recommendation here is that you create one specifically for this purpose – i.e. I would not try and take, for example, a wildcard SSL cert that I’m using on my web site and use it as a trust broker.  You can create a self-signed certificate, you can create a domain-issued SSL certificate, etc…but I would create one specifically for this purpose.

Once you have the certificate you want to use, you need to configure SharePoint to trust it and to use it – these are two different things!  The first thing you need to do is configure SharePoint to trust it.  This is the same process as you go through when you create an SPTrustedIdentityTokenIssuer for SAML claims – you get the token signing certificate and you add it to the list of trusted root authorities.  When you are creating a new trust broker you need to do the same thing – add your certificate to the list of trusted root authorities.  Also, just like with an SPTrustedIdentityTokenIssuer, if your certificate has parent certificates in its certificate hierarchy, you need to add ALL of them to the list of trusted root authorities.  I’ve explained this concept in more detail here:  http://blogs.technet.com/b/speschka/archive/2010/02/13/root-of-certificate-chain-not-trusted-error-with-claims-authentication.aspx.  

After you’ve done this, then you need to create your trust broker, which in SharePoint world is an SPTrustedSecurityTokenIssuer.  When you create an SPTrustedSecurityTokenIssuer, you are basically saying that you are going to have Apps submitting requests to SharePoint, and those requests are going to be signed with the public key of this certificate.  The only way you can sign something with the public key, is if you possess the private key.  That’s how SharePoint knows if the request comes in signed by this certificate, then it could have only come from someone who possesses the keys to that certificate.  In looking through some of my blog postings I realized that it doesn’t really seem like I’ve ever shared the PowerShell for creating one based on a certificate, so here goes:

#NOTE:  You can use the .CER file here, i.e. without the private key

$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(“C:\spapps.cer”)

New-SPTrustedRootAuthority -Name “Apps Certificate” -Certificate $certificate

#NOTE:  Create your own GUID and put it here, make sure

#all alpha characters are lower case

$issuerId = “e9134021-0180-4b05-9e7e-0a9e5a524965”

$spurl =”https://foo.contoso.com”

$spsite = Get-SPSite $spurl

$realm = Get-SPAuthenticationRealm -ServiceContext $spsite

$fullAppIdentifier = $issuerId + ‘@’ + $realm

New-SPTrustedSecurityTokenIssuer -Name “High Trust Apps” -Certificate $certificate -RegisteredIssuerName $fullAppIdentifier -IsTrustBroker

 

They key to this bit of PowerShell is the -IsTrustBroker flag when you create your SPTrustedSecurityTokenIssuer.  If you don’t include that flag, then that certificate can only be used with a single App, and that App would need to use the $issuerId as both the clientId and issuerId in the web.config file.  That’s not to say that there aren’t scenarios where you might want to do that, but it’s certainly not the mainstream case.  I’ll talk more about certificate management issues later in this post.

Once you’ve created your SPTrustedSecurityTokenIssuer, you’re ready to create your applications.  That process is somewhat more complicated than when you build a low trust App.  You’ll open up Visual Studio and select new SharePoint App, then in the first page of the wizard you’ll pick the site you want to deploy to during development and configure it as a provider hosted app.  On the second page of the wizard though, instead of selecting a client secret you’ll need to browse and select the certificate – the .pfx version – that is configured to be the SPTrustedSecurityTokenIssuer.  You’ll need to provide the password to open up the PFX file, as well as the issuerId associated with that certificate.  Here’s what the second page of the wizard looks like when you create a high trust app – again, you MUST use only lower case for your alpha characters in the Issuer ID field or you will get 401 unauthorized errors when access SharePoint:

There is one thing that’s very important to note here about the location of your token signing certificate…I’m seeing this issue come up more and more frequently as folks deploy their apps so make sure you are on top of this.  When you create your provider hosted app, Visual Studio will create a new web app project that uses IIS Express.  When you run that App, IIS Express is effectively running in the context of your own credentials.  So when IIS Express tries to load the pfx certificate to use for signing your application request, it all just works.  Where the problems tend to occur is when you deploy your application to production.  Now it’s running on IIS and it’s doing so in the context of an app pool.  I’ve seen many times where the app pool account does NOT have rights to the directory where the pfx file is kept.  As a result you will get all sorts of nasty untrapped errors (bad TokenHelper class, bad TokenHelper).  Make sure you have at least Read rights to the directory for your app pool account before you deploy.

Now that all your plumbing is in place and you’re ready to write your app, you need to remember what “high trust” really means.  As I’ve said before it means it’s up to YOU to tell SharePoint who the App is and who the user is to SharePoint.  You tell it who the App is by the clientId value in your web.config.  How you tell it the user identity is completely up to you.  If you use the out of the box TokenHelper class, it’s configured to use the current user’s Windows identity.  It doesn’t have to work that way though – you can modify TokenHelper and have it send an identifier for whatever user you want.  I say “identifier”, because really you are just sending over a claim value – nameid, SMTP, SIP or UPN – that SharePoint will use to “rehydrate” the user when the request is received.  For a more complete discussion on what rehydrate means, you can read this post:  http://blogs.technet.com/b/speschka/archive/2012/08/15/oauth-and-the-rehydrated-user-in-sharepoint-2013-how-d-they-do-that-and-what-do-i-need-to-know.aspx.   The net of it is you need to have an up to date User Profile Application (UPA) so when your request arrives at SharePoint, it can look in the UPA and find a profile that matches the claim type and value you sent in.  As a high trust app you can tell SharePoint that you’re the Queen of England or the Mayor of Steveville and it will just take your word for it.

Since I keep pointing this fact out to people, I thought that perhaps it might help to actually dig into TokenHelper or ClaimsTokenHelper and show you exactly where and how you do that.  In fact I’m going to show ClaimsTokenHelper here, because that is the class that I wrote to do this “stuff” for SharePoint sites that use SAML or FBA so I had a delightful time playing with this very fun feature.  J  If you open up ClaimsTokenHelper.cs, go into the IssueToken method (the TokenHelper class has this same method as well).  Here’s an abbreviated version of what it looks like:

List<JsonWebTokenClaim> actorClaims = new List<JsonWebTokenClaim>();

actorClaims.Add(new JsonWebTokenClaim(samlClaimType, samlClaimValue));

 

In this case I’m passing some variable so I can plug in whatever claim type and value I want.  However you could just as easily replace this line of code with something like this:

 

JsonWebTokenClaim(“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress&#8221;,queen@england.com));

 

Congratulations – all of your users are now the Queen of England…as long as you have a user profile with an SMTP address of queen@england.com.

There’s one other point worth making about the clientId, which identifies the App.  Remember that when you are building your App in Visual Studio, VS will automatically generate a clientId and update the web.config, as well as configure the deployment site to ensure that everything works when you press F5.  Once you’re ready to deploy your App to production you need to take care of that yourself.  That means you need to go to a site and use appregnew.aspx to generate a new clientId for your application, republish your application using that clientId, deploy your App to the App Catalog, then install it in the site collection.  The use of appregnew.aspx is also covered in a little more detail in this post (as well as TechNet):  http://blogs.technet.com/b/speschka/archive/2013/02/18/when-do-your-apps-need-appregnew-aspx-in-sharepoint-2013.aspx.

Now that we’ve gone end-to-end on the high trust plumbing and application deployment, it’s worth taking a few minutes to come back to the topic of certificate management.  Generally speaking, as I’ve said, you want to use the –IsTrustBroker flag when you create your new SPTrustedSecurityTokenIssuer.  However you also need to understand the flip side of that arrangement – while every app can use that certificate as the trust broker, what happens if you want to stop trusting one particular App?  The only way to really do that is to remove the SPTrustedSecurityTokenIssuer.  When you do that of course, ALL of your Apps are broken.  To fix it, you would need to create a new certificate, create a new SPTrustedSecurityTokenIssuer, distribute the pfx version of the new certificate to all of your Apps, and then have all of the Apps change their issuerId to match the new SPTrustedSecurityTokenIssuer.  That’s potentially a lot of work.  Another option would be to create separate certificates based on your organizational hierarchy.  For example, you could create a separate certificate and SPTrustedSecurityTokenIssuer for each division, or each department, or however you organize your company.  That will reduce the impact when or if you want to stop trusting an App, but of course it also introduces some overhead you have to plan for – how are we going to track, store, and safeguard these certificates?  That’s an aspect of SharePoint Apps development that I really haven’t seen anyone address so far, which is kind of interesting in and of itself.  For more discussion on managing certificates you can also take a look at this article:  http://msdn.microsoft.com/en-us/library/jj945118.aspx.

That’s going to wrap up this discussion of high trust apps.  The next part will be the last part in this series, and it will be kind of short.  I’m going to talk briefly about developing Apps for SharePoint sites that use SAML authentication.  I already have a blog post with code that covers this in some detail, so in this last post I’m really going to look at it from a higher level.  The idea will be to set you up with the pieces you’ll need to put into place, what your high level plan should look like, etc. and not really the coding aspect since that’s covered in my other post.

NEXT:  Security in SharePoint Apps – Part 8

Security in SharePoint Apps – Part 5

PREVIOUS:  Security in SharePoint Apps – Part 4

As promised in Part 4, there’s actually a very interesting type of application that you don’t even install in a site collection.  How can this be you ask…well let’s talk about it. 

With most apps, you have to deploy it somewhere to be installed – the SharePoint Store or the app catalog.  A user then has to install that application by going to the Site Contents menu, finding the application they want, and installing it.  Once it’s installed, you will typically see a link (if it’s an App) somewhere in the site to launch it, or maybe it shows up looking like a web part (if it’s an App Part) or on the ribbon.  The key though is that they users go to their SharePoint site and then launch the application from there.

The exception to that is the focus of this posting, which is an app that uses “permissions on demand” (AKA “permissions on the fly”).  One of the biggest differences in the use case for it is that these applications typically initiate the connection to SharePoint, rather than the other way around.  For example maybe you have an ASP.NET web site and it needs to go out and pull in data for a user from SQL, from Facebook, and from a SharePoint list.  That’s a great use case for this kind of application.  There are a few steps and things to be aware of though, so let’s go through the process.

First, it’s important to understand that this kind of application can ONLY be used with low trust.  You cannot use a permissions on demand application with high trust.

Next, even though you don’t have to “install” the app per se, you need to start out by registering it with at least one site collection in your farm.  You can do that by going to any site collection, and navigating to the appregnew.aspx page.  For example, if you have a site collection at https://sps, then you would go to https://sps/_layouts/15/appregnew.aspx.  When you do the application registration there’s one important difference between how you register an application that’s going to be using permissions on demand: you need to provide a Redirect URI in addition to all of the other fields on the page.  The reason you provide this is because what is going to happen is that your app is going to make a request to SharePoint and say hey – I need to access this site for this user and I need this set of permissions.  The App won’t have an access token at first, so SharePoint is going to provide it with a code that it can use to get one.  The way SharePoint does that is that it puts the code in the query string and then redirects the request back to the Redirect URI that you have specified for the App.

The next thing that’s important to understand is that you decide when you make the request to SharePoint, what permissions you are going to ask for.  So how do you do that?  Well remember above I said that your App initiates the request to SharePoint, to get a code that it can use to get an access token.  When it makes that initial request it also tells SharePoint what rights it wants.  It does this by passing a parameter in a query string, where that parameter contains a set of one or more rights that are space delimited.  For example, if you wanted Read rights on a web, then you would specify Web.Read.  If you wanted rights to both read from the web and write to a list then you would ask for “Web.Read List.Write”.  You can get a complete list of all of the rights you can request at http://msdn.microsoft.com/en-us/library/jj687470.aspx.

There’s one more very important thing to understand about these kinds of Apps.  The first time it makes a request to a SharePoint site, you will get an App trust dialog – just like you do when you install an App from the App Catalog.  This is going to be as close as you get to “installing” the application – what it’s really doing is just creating an App Principal (which I described in Part 1).  The trust UI is slightly but not significantly different from a standard App trust dialog when you do this:

 

What’s especially important to remember here is that you must be a Site Owner or better in order to successfully trust this app.  Normally you might say hey, that’s okay, whenever I install an App you have to be a Site Owner to trust the app and then once that’s done everyone can use it.  That is not the case here.  EVERY user who uses the app will need to be able to trust the app.  In fact, if you do NOT cache the refresh token and/or access token for the user, that user will be asked to trust the App EVERY time they use the app.  This is important!  What that should tell you is that this kind of app is only going to be useful when you know your users are going to be Site Owners or better (like site collection administrator).  That obviously won’t make sense for every type of site collection out there, but it does for example work quite nicely with My Sites where you are always a site collection administrator by default. 

From a coding perspective, if you were to use the same page for both your code as well as your Redirect URI, it would look like this at a very high level:

if (Request.Cookies[myAccessTokenKey] != null)

{

//get your access token out of the cookie

}

else if (Request.Cookies[myRefreshTokenKey] != null)

{

               //get my refresh token out of the cookie

               //use the refresh token to get an access token

               //store the access token in the cookie (or wherever you want)

}

else if (Request.QueryString[“code”] != null)

//you don’t have a refresh token OR an access token; if you have “code” in the

//query string then you must have come from the SharePoint authorize page

//get a refresh token from the authorization code

//store the refresh token in the cookie (or wherever you want)

               //use the refresh token to get an access token

               //store the access token in the cookie (or wherever you want)

}

else if (Request.QueryString[“error”] != null)

{

               //if the query string contains an error key, then that means that the

               //SharePoint authorize page encountered a problem when we asked

               //it to issue a code.  A common cause would be if the current user

               //is not a Site Owner on the site we’re hitting up for data

               //do your error handling for this scenario here

}

else

{

//we have no access token, no refresh token, no errors and no

               //authorization codes that we can use to get one, so we need to

               //go ask for an authorization code.  Remember that every time we

               //do this, the user will be prompted to trust the application

 

//here is where we define as well what rights we want when we hit

//the site; you can use a space-delimited

Response.Redirect(TokenHelper.GetAuthorizationUrl(hostWeb, “Web.Read”));

}

I think the pseudo-code above should illustrate pretty clearly what you need to do, but here are a couple of points to add:

  • I’ve attached a sample program to this posting that has a complete implementation for you to review
  • You can get more details on permissions on demand and the specific steps you need to go through to configure at http://msdn.microsoft.com/en-us/library/jj687470.aspx.  My goal here was not to provide a step-by-step set of instructions because they already exist.  It was really to describe the concept and make you aware of the pros and cons, and generally how it works.

As I mentioned above, the “install” is not like a typical application install.  Normally when you install an application in a site, you can go into the Site Contents and you will see all of your Apps, including those that you have installed from the SharePoint Store or App Catalog.  Even after you trust a permissions on demand App, you will not see it in this list.  Remember I said though that it really just creates an App Principal?  Well the way you CAN see that is if you go to the appprincipals.aspx page in the _layouts directory.  So for example, if my SharePoint site is at https://sps, you would go to https://sps/_layouts/15/appprincipals.aspx.  That page also supports a query string variable called “Scope”.  If you wanted to see the App Principals that have Web-scoped rights, you would enter https://sps/_layouts/15/appprincipals.aspx?Scope=Web, and so on.  Here’s an example of what mine looks like after I’ve trusted my permissions on demand application, which is called Dynamo App:

That wraps up this part.  In the next part in this series we’ll look at some of the heavy hitters of SharePoint Apps – those that can access any content, anywhere.

NEXT:  Security in SharePoint Apps – Part 6

Security in SharePoint Apps – Part 4

PREVIOUS:  Security in SharePoint Apps – Part 3

In Part 3 I talked about how SharePoint sends over a context token with the request for an App when using low trust (this does NOT come over to a high trust app).  It’s worth looking at what a context token is, and how we compare that to a special class called SharePointTokenHelper that’s in TokenHelper.cs (the class that’s automatically added to your Visual Studio project when you create a new SharePoint App).

The context token that comes from SharePoint can be extracted out of the request using TokenHelper’s GetContextTokenFromRequest method.  When a request is made for a low trust App in SharePoint, SharePoint will initially go out to ACS and get this token, and it will contain information about the user making the request and the application being requested.  ACS sends a token back to SharePoint that is signed with the client secret for the application, so if you don’t have that, you can’t unwrap it.  SharePoint then sends that along with the request to the application.  Once the App has it, it uses the ReadAndValidateContextToken method in TokenHelper to extract it out into a SharePointContextToken class; that’s where the client secret is used. 

The data itself is really just a JWT token (pronounced “JWOT” – more information can be found here:  http://openid.net/specs/draft-jones-json-web-token-07.html), which contains some claims information in a JSON format.  ReadAndValidateContextToken just serializes that into the SharePointContextToken class.  There are some very important things that you can do with the SharePointContextToken class:

  • Get a refresh token – your refresh token is good for six months. 
  • Get an access token – use the refresh token to get your access token; the access token is what you need to present to SharePoint to access data.  Access tokens are good for 12 hours.  An access token can be cached and used on subsequent requests, which saves you the performance hit of having to go out and using the refresh token to get a new access token.
  • Get a cache key – as mentioned above, an access token can be cached.  Keeping track of all the different users, apps, sites and potentially tenants can be quite a challenge.  Fortunately the SharePointContextToken includes a cache key just for this purpose.  It does all the work of creating a separate cache key for each combination of user, app, site and tenant.  That allows you to just grab it and use it when caching an access token.

 Here’s an example of what the SharePointContextToken and its constituent properties looks like:

 

 

So having all this information in hand, this is what the typical use case might look like:

  • User clicks on link in SharePoint site that launches an App
  • App extracts SharePointContextToken and uses cache key to determine if it has an access token
    • If it does, it checks to see if the access token is still valid.  If so, it can use that access token; if not then it needs to follow the steps below to get a new one.
    • If it does not, it uses the refresh token to get a new access token and then it saves the access token in cache.

Here’s some code that demonstrates this process:

 

private class AccessTokenInfo

{

public string AccessToken { get; set; }

public DateTime Expires { get; set; }

 

public AccessTokenInfo() { }

 

public AccessTokenInfo(string accessToken, DateTime expires)

{

this.AccessToken = accessToken;

this.Expires = expires;

}

}

 

That class is used in the Page_Load event:

 

//get the context token first; it includes the cache key and refresh token

var contextToken = TokenHelper.GetContextTokenFromRequest(Page.Request);

var hostWeb = Page.Request[“SPHostUrl”];

 

//get the context token details

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

 

string accessToken = string.Empty;

 

//now look to see if we have cached an access token for this yet

if (Session[tokenContent.CacheKey] != null)

{

//we do, so extract out the info so we can see

//if the access token is expired yet

AccessTokenInfo ati = (AccessTokenInfo)Session[tokenContent.CacheKey];

 

//check the expiration

if (DateTime.Now < ati.Expires)

accessToken = ati.AccessToken;

}

           

//if we didn’t have a valid access token, then get one here

if (string.IsNullOrEmpty(accessToken))

{

//get an access token from the refresh token

accessToken = TokenHelper.GetAccessToken(

tokenContent.RefreshToken, TokenHelper.SharePointPrincipal,

new Uri(hostWeb).Authority, TokenHelper.GetRealmFromTargetUrl(

new Uri(hostWeb))).AccessToken;

 

//create a new AccessTokenInformation item and set the

//expiration of the access token to 11 hours and 50 minutes

//and put it in session state for next time

Session.Add(tokenContent.CacheKey,

new AccessTokenInfo(accessToken, DateTime.Now.AddMinutes(710)));

}

Hopefully the explanation and code demonstrates what the cache key is and how it can be used within your applications.  I’ve also attached the sample project that contains this code along with this posting so you can play with it yourself.  Just remember that you will need to configure the provider hosted app to work on your development system with your application values in the web.config file.

In the next part in this series we’ll take a look at an interesting application option that doesn’t even require you to install the App in the site collection!  It’s different from your ordinary App, and we’ll discuss that next.

NEXT:  Security in SharePoint Apps – Part 5

Security in SharePoint Apps – Part 3

PREVIOUS:  Security in SharePoint Apps – Part 2 

In the first two parts of this series we looked at what an App Principal is and what the security context is that we use when a request comes into SharePoint.  Now that we have those basic components of the framework defined, let’s talk a little about the types of trust we use for Apps in SharePoint.  We have two types of trusts for apps in SharePoint, which we call Low Trust and High Trust (sometimes also known as S2S).  Now that you know about App Principals and security contexts, how do these things differ between the two trust models?

In the low trust model, SharePoint provides a context token, that includes a refresh token, that has information about who the user is what the App is.  The App can use the refresh token to get an access token, and the access token is what’s actually presented to SharePoint when the request is made.  Remember in Part 1 when I described handing SharePoint a “note” that said what the App is and what it could do?  That is the role of the access token.

In a high trust model, the App tells SharePoint who the App AND who the user is.  How your App comes up with the user identity is completely up to you – but we will talk about this more in the part on high trust apps.

We can use either low trust or high trust with on-premises applications.  For purposes of our discussions you can use only low trust Apps when they are deployed to Office 365.  Each one uses different plumbing to work though, and we’ll look a little at the low trust plumbing for an on-premises SharePoint farm next (there’s no point in looking at it for Office 365 because it’s already configured for you there).

When you use low trust Apps on-premises, you’re deferring to ACS to act as a trust broker.  I would define ACS for you, but the acronym keeps changing on me…to me it will always mean Access Control Services but now it’s Azure something something.  J  Remember I mentioned the “trust broker” concept in Part 1.  You can think of the trust broker as the intermediary between SharePoint and your App.  SharePoint and your App both trust the trust broker, and it becomes something like a transitive trust in Windows Server – A trusts B and C trusts B, so therefore A trusts C.  So in a low trust app ACS is the trust broker; when we talk about high trust apps we’ll see how a simple certificate can become a trust broker.

To configure your on-premises farm to be able to use low trust apps, there are a few steps you need to take:

  1. Create an Office 365 tenant.  You don’t need to add user licenses and pay for them to use SharePoint and Exchange and Lync or anything like that.  You just need to have a tenant in Office 365 so that you can have a reference point for your on-premises farm to create a trust with ACS.
  2. Replace the token signing certificate for the on-premises SharePoint STS.  ACS needs to be able to trust the token signing certificate used by the SharePoint STS because they will mutually handshake over SSL when they go about exchange tokens with one another.  In the simplest case you can just create a new self-signed certificate and use that.  Beware though that by default self-signed certificates expire after one year.  When your certificate expires you will need to update your STS and also your trust relationship.  You can use a certificate issued by a public certificate root authority like Go Daddy, Verisign, Thawte, DigiCert (who does a GREAT job by the way), and many others.  What you CANNOT do is use a domain issued certificate.  It won’t work because there isn’t a public root authority for it that we can trust to.
  3. Set up an Azure Service Application Proxy, SPTrustedSecurityTokenIssuer, and SPNs for the MsolServicePrincipal.  The service application proxy is how the farm is going to communicate with ACS, and an SPTrustedSecurityTokenIssuer is where we define the trust brokers that are going to be used in our farm.  The Service Principal is like an App Principal, only it’s for the ACS service instead of one specific application, and the SPNs (Service Principal Names) define on which host Urls the Service Principal should be allowed to operate.

Okay, so on the previous two steps here I did not give you a lot of detail about how to do them, but there’s a reason for that.  We have a nice document already prepared that includes more details and a PowerShell script to take care of this for you.  All you have to do is go to http://msdn.microsoft.com/en-us/library/dn155905.aspx to more details and download the script from there.  A couple of other things worth noting about this:

  1. You need to create an SPN for every web application where you want to deploy apps!  Remember I mentioned above that the collection of SPNs determines where the Service Principal can be used.  The good news is that the link I provided above includes a PowerShell script that takes care of this for you as well, so you don’t have to worry about hunting that down.
  2. You should really reboot your SharePoint server(s) after making these changes.  I’ve found the functionality to be a little hit and miss when you do not do that.

Once you’ve done these steps – which when you think about it are really pretty simple; open a browser and create a tenant, copy some PowerShell script and run it, then reboot your server – you’re ready to write your first low trust app on-premises.  Doing so is actually quite simple:

  1. Open Visual Studio 2012 (with the Office Developer Tools installed) and create a new SharePoint App.
  2. When the wizard starts type in the Url to your SharePoint site where you want to deploy the app and choose a hosting option like Provider-hosted App, then click Next.
  3. Select the option to use a client secret and click Finish.
  4. Press F5 to run, deploy and test.

 Here’s how it looks running through the wizard:

 

 

 And that’s all there is too it.  If it all doesn’t “just work” for you though, here are a few troubleshooting tips:

 That wraps up this post.  In the next post we’ll look at the context token from SharePoint in a little more detail and see what you can do with it.

 

NEXT:  Security in SharePoint Apps – Part 4

 

Security in SharePoint Apps – Part 2

PREVIOUS:  Security in SharePoint Apps – Part 1

In Part 1 of this series I described how to think about an App Principal, and I mentioned that it is one of the main actors in determining who has rights to what content.  The other actor, of course, is the User Principal.  Between the two though, there are four possible security contexts that SharePoint may use when responding to requests for content.  In this post we’ll take a look at all four and how we determine when we use which.

It’s best to look at the process of determining the security context through a familiar paradigm, like a flowchart.  So here’s how our flowchart would look – our starting point is a request coming in to SharePoint, and we’ll take it from there.

  • Have user credentials been provided?
    • YES:  If user credentials are included, then the next thing we look at is where is the request going – is the request for an App Web (i.e. like a SharePoint-hosted app)?
      • NO:  If the request is not for an App Web, then that means it’s for a content web.  In that case, it’s like SharePoint as you have always known it – a user trying to get something out of a SharePoint site.  In that case we set a User Only security context with the request.
      • YES:  If the request is for an App Web, then it means that there is both an App AND a User that we need to add to the security context for the request.  In that case we set a User + App context to the request.
    • NO:  If user credentials were not included, then the next thing we need to determine is whether an App token was provided?
      • NO:  If there’s no user credentials and no App token, then we’ve got no security context whatsoever.  That’s okay – it just means that this is an Anonymous request.  That’s a completely valid scenario of course, that we frequently use on Internet-facing sites.
      • YES:  If there’s an App token, then we need to take a closer look at it and ask, is there a user identity included with it?
        • YES:  If there is a user identity included with it then it means that the App is acting on behalf of that user.  You will in fact see that sometimes when a list item is modified by an app for example – it will say something like “Modified by Contoso App On Behalf of Sam Jones”.  In this situation then we treat it like a scenario above and set a User + App context to the request
        • NO:  If there is ONLY an App token without any user identity, then we view it as making what’s called an App Only request.  App Only apps execute with elevated privileges, and can operate on data whether the current user has rights to it or not.  The only check that’s made is whether the App has rights to the content.

So those are the four identity contexts that we can have when making a request for content from SharePoint.  They’re important to know, because we can wind up in any of them when writing apps in general…but for purposes of this series we’re really just going to focus on User + App and App Only requests.   To make it a little easier to rationalize, here’s a picture of the flowchart I described above: 

 In the next post in this series we’ll talk about the simplest environment to write code in – an on-premise Low Trust App.

 

NEXT:  Security in SharePoint Apps – Part 3

Security in SharePoint Apps – Part 1

I recently put together a session around security in SharePoint Apps.  There seems to be enough content on this topic to keep people on their toes at all times, so I decided to try and assemble all this information all in one place on this blog with a series of posts.  Most of this information is scattered around on various pages on TechNet and whatnot, so hopefully at least some of this content will sound familiar.  I’ll also include some sample code and/or projects along the way to help illustrate a point.  Also, as I continue to add parts I’ll try and come back here each time and update the set of links to all the parts in this series:

There’s one other point I’d like to make here – this series is really just for developing provider-hosted applications.  Why not SharePoint-hosted apps you ask?  Because there really isn’t security to manage with a SharePoint-hosted App; the App takes on the security model of the host web, and you are limited to using client-side script only for development.  That’s it – nothing else to do.  It’s only when you go to the provider hosted model that you have all of the options and flexibility that I’ll be discussing in this series of posts.

So…to begin with, I think it’s useful to establish a common understanding of one of the main actors in SharePoint App security, which is the App Principal (AKA SpAppPrincipal).  Everyone should be familiar with a User Principal at this point – that concept has been around since the first version of SharePoint shipped in 2001.  User Principals are represented by claims of different types, such as my Windows account, my email address, my Active Directory group, etc.  We see User Principals in various formats, such as:

  • microsoft\stevep
  • fbaMembers:stevep
  • i:0e.t|aad|stevep@microsoft.com

We manage rights for user principals by adding them to SharePoint groups, adding them to Permission Levels, augmenting their claims, etc.

So what is an App Principal?  This is probably best explained by way of a little story, and it goes something like this.  Suppose I have a SkyDrive site.  I keep all of my documents and pictures up there.  When I want to access that content I have to enter my username and password.  SkyDrive validates my credentials and then gives me access to that content.

Now suppose I start using another cloud service; it’s called Contoso Photo and I want to use it to print out pictures that I store on SkyDrive.  To access Contoso Photo, I also have to enter a username and password, and it has to validate that before it lets me use their services.  So I have these two services I use, they both use a username and password, and I need to share data between them – how do I do that?

Well, one option would be that I could give the credentials I use for SkyDrive to Contoso Photo.  That sounds scary – and it is.  What’s even scarier is that there are some services out there that ask you to do exactly that.  So let’s play that scenario out a bit though and see how it works.  Now when I ask Contoso Photo to print a picture for me, it can ask for those resources from SkyDrive.  It will present my username and password to SkyDrive, and SkyDrive has no idea that it isn’t me.  It just sees a valid set of credentials and it knows that those credentials have rights to View the pictures so it hands them off to Contoso Photo.

The thing is though, I have a lot more rights than just being able to view content.  I can add content, tag content, add comments, etc.  Now that Contoso Photo has my credentials it can do all of that on my behalf as well.   You of course hope that Contoso Photo takes their reputation seriously enough that you don’t have to worry about that happening, but it’s certainly an unsettling position to be in.

Now what happens if I decide I don’t want to use Contoso Photo anymore?  Well I could go back and change my password to SkyDrive.  In fact Contoso Photo would also have rights to change my password with SkyDrive, but hopefully they would never do that.  But what if I had 10 cloud services I was using that were configured the same as Contoso Photo?  I would have to go back then and change my SkyDrive credentials in 9 other places, once for each of those other services I wanted to continue using.  As you can imagine, it creates a real mess.

So what if I took a different approach.  Suppose I created something for Contoso Photo that it could give to SkyDrive – let’s call it a “note”.  In that particular note, I’m going to say that Contoso Photo is allowed to View my photos in SkyDrive, and that’s it.  I’m going to sign that note and then Contoso Photo is going to give it to SkyDrive when it needs to access my photos.  SkyDrive looks at the note and sees that it says Contoso Photos can access Steve’s photos.  It also sees that the note is signed by Steve, so it knows that the note is legitimate.

In a nutshell, that “note” process is how you can think of an App Principal.  It describes how an application is able to separately identify itself from a User Principal, and describe exactly what it can do separately from what the User Principal can do.  It also shows how the App Principal can act on our behalf without needing our credentials each time it needs to talk to SharePoint.  SharePoint knows that it can trust the request from the App Principal because the requests it makes are “signed” by somebody it trusts – something we call a “trust broker”, which will discuss in a subsequent post.

That really is what I wanted to cover in part 1 – establish a common understanding of what an App Principal is, because it is one of the main actors when working with data in SharePoint.  Note that I did not say ALL the actors.  I’ll go into the further explanation on that in Part 2 of this series.

NEXT:  Security in SharePoint Apps – Part 2