Friday, November 27, 2015

Limiting Add-in visibility in the corporate store

SharePoint Add-ins * are distributed through the App Catalog. This is a great method for end users to add functionality to their sites. Most apps you want to have available to as many users as possible, everybody should be able to add the local weather app, or the handy currency calculator to their sites.

However, some Add-ins should not be available to everyone. Think for example of Add-ins that allow for access into line of business applications. Users will probably not even be able to use the Add-in, if they are not able to access the LOB application, but you don't want them to be able to add the app to their sites in the first place.

I see five ways of preventing users from adding the app to their site. Spoiler alert; I think the fifth is the right way, so skip ahead if you are just looking for that :)


1. Sideloading the Add-in
Add-ins don't have to be distributed through the catalog. You can enable sideloading and just publish the Add-in to the target site directly. However, this is a development feature, meant for developers to quickly deploy and test their Add-ins. The catalog gives you a central place to push updates to the Add-in, and get error reports from the instances. Basically, you should not use developer tools to power a production scenario.

Still want to use sideloading? Look here for ways to enable this.


2. Remove the Add-in from the catalog
You could just quickly remove the Add-in from the catalog after you have deployed it to the right sites. However, you would have to add it again every time you want to add the Add-in somewhere else, and you lose the centralized error tracking. Furthermore, you would have to add it again to perform upgrades, which you then have to execute quickly on all instances, before pulling the Add-in again. All-in-all, quite cumbersome.


3. Check the location in the app installed event
If the app is a provider hosted app, you could execute the 'App Installing' event. This allows you to execute checks on for example the location the Add-in is being added, or the identity of the person doing the adding. If there is a mismatch, you can block the installation.

To use this method however, you need to be the developer of the Add-in. Furthermore, it requires you to either package the app with allowed locations or identities, or also create a location to manage this (the web.config of the provider hosted Add-in would be a logical place). Finally, this method doesn't prevent the user from seeing the Add-in in the catalog, just from adding it to the site.


4. Ask for extra permissions for the App
This might just be the easiest solution, but also the worst. Do not do this. :)

You could let your app just ask for extra permissions. For instance, tenant admin permissions. Remember, a user cannot install an Add-in with more permissions than the user has. So only tenant admins will be able to add an Add-in which requests tenant admin permissions.

However, if somebody manages to subvert the Add-in into doing something it shouldn't, it will be doing so with tenant admin permissions. This is bad and goes against the principle of least privilege.


5. Break permissions in the App Catalog
Still with us? This is the one I ended up using. You can use item level security in the App catalog. Just add the Add-in as you always would, but afterwards edit the security for the item:


 And stop inheriting:



Remember, the App Catalog is just a SharePoint library, so this is all possible with the OOTB tooling. Just remove the permissions to see the Add-in for anyone you don't want to let install the Add-in.

I like this way because it's easy, intuitive, and secure. It does not mess with updates or error reporting. However, I haven't been able to gather info anywhere on whether this is a supported scenario. Does Microsoft support breaking these permissions? Until I find somewhere that they don't, this is the way I'm leaning.



So, the fifth it is, according to me. But it is still not ideal. Do you disagree, or have another way? Please leave a comment below.

* note that I'm mention Add-in, instead of App. I seem to have finally accepted the change!

SharePoint remote event receivers returning 405 (Method not allowed)

The SharePoint app* infrastructure is a notably fickle beast. I've seen grown system administrators reduced to tears by obtuse error messages and exotic requirements which don't fit company infrastructure policies (wildcard certificates, no support for SSL offloading, multiple IP's or NICs etc etc.).

This week I was confronted by a new one. A provider hosted app we were deploying was unable to register remote event receivers (which we do from another remote event receiver triggered by the app installed event). The provider hosted app returned http error 405 (method not allowed). The relevant section of the ULS:

Error when get token for app i:0i.t|ms.sp.ext|xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, exception: Microsoft.SharePoint.SPException: The Azure Access Control service is unavailable.    
 at Microsoft.SharePoint.ApplicationServices.SPApplicationContext.GetApplicationSecurityTokenServicesUri(SPServiceContext serviceContext)    
 at Microsoft.SharePoint.ApplicationServices.SPApplicationContext..ctor(SPServiceContext serviceContext, SPIdentityContext userIdentity, OAuth2EndpointIdentity applicationEndPoint)     

Calling remote event receiver failed. URL = [https://xxxxxxxxxxxxxx.com/xxxx/Services/AppEventReceiver.svc], App Identifier = [i:0i.t|ms.sp.ext|xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx], Event Type = [AppInstalled], Exception = [The remote server returned an unexpected response: (405) Method Not Allowed.] 


The message that jumped at me directly is "The Azure Access Control service is unavailable". I'd hope so with my on premises SharePoint and provider hosted app deployment! This message however is a red herring and expected in an on premises configuration. I found multiple other possible reasons for a 405, including;
  • Certificate problems
  • SSL / TLS supported version mismatch between App server and SharePoint server
  • No handler in IIS for the incoming request

As the famous detective states; "when you have eliminated the impossible, whatever remains, however improbable, must be the truth". It turned out the App Server was missing a feature, specifically the ".Net Framework 4.5 > WCF Services > HTTP Activation" feature:



Adding this one allowed me to finally install the App. It's not clear why the feature was not installed, it was in the install scripts for the App server.


I hope if you're confronted by this 405 you'll find this post, and spend less time on it then I did.



* note the deliberate use of 'App' instead of 'Add-in'. It will require me some time to make the mental switch.

Rating