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 https://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 https://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

DynamicApp.zip