You could find a lot of articles over internet on how to setup a development environment for developing SharePoint Apps. Some of those articles (including technet) nicely explain how to setup the Apps environment for SharePoint.However, when I started exploring, I found many confusing and contradicting stuffs there, for example Configure your Domain Name section in the technet article Configure an environment for apps for SharePoint (SharePoint 2013) is correct for SharePoint hosted Apps (or if you want to use SharePoint store apps) and NOT for provider hosted apps !!!
Anyway, I will skip these and assume that you have setup the Provider Hosted Apps environment correctly (you can refer this blogs for reference).
Same way you can follow this technet article to develop your first Provider Hosted App for Office 365.
All that work great separately 🙂 what if you want to develop an app which can run on both Office 365 and In-Premise SharePoint 2013 environment!
Well lets look into that –
The problem here is that by default In-Premise apps are High Trust Apps which use Certificates to Authenticate Apps whereas O365 uses ACS for the same. That’s why while creating the App in Visual Studio, it asks for which Authentication you would like to you.
Practically, it doesn’t matter which option you chose here if you want to develop a Hybrid App.
So, lets go ahead and create an App in VS for In-Premise one –
After the App is created in VS, open Web.config file, you would see something like this –
Now, open Office 365 site and browse to _layouts/15/appRegNew.aspx and create new ClientID and Client Secret –
Here I am hosting my App in an Azure Web Site, so I have provide app domain as my azure web site DNS, the redirect URI will be in form of https://azurewebsitedns//Pages/Default.aspx
Now, update your Apps, Web.config with the ClientID and Secret from here –
You also see, I have updated my Certificate Path, this is because the Path would change after the certificate is deployed in azure web site. I have added this certificate in a folder Cert inside my project which gets deployed in a virtual directory of my azure web site –
So, now we have a config file which has ClientID and ClientSecret which can be used by Office 365 and Certificate details which can be used by In-premise.
Now, we can open In Premise site and browse to _layouts/15/appRegNew.aspx and USE the same Client ID and ClientSecret as used in Office 365 and register the app.
Now, you can publish the app and upload the app file to both O365 and in-premise and see what happens.
You will find, it’s working in-premise but throwing some error in Office 365.
Let’s take a look what’s happening in background – if you open the default.aspx.cs page, you would see a pre_init method –
here, if you debug this method for Office 365, you would find that’s its treating the app, as a Full trust App and not a Low trust App, which would work with office 365.
Looking deeper, would reveal, the culprit is a method in TokenHelper class, there are a few private variables which read the values stored in Web.Config like Certificate location, password etc.
and this method simply returns true, if a certificate path and password are provided in the config file ! Not too smart I guess –
So, the solution finally, we need to do something with this method, so that it returns true only if the App in running In-Premise and false, if running in O365.
This is what I came up with, quick and dirty, but you got the idea. You can play with your own logic.
Lets, base this method’s output on the SPHostURL instead of the certificate.
SPHostURL is part of the standard token which is passed to the App from SharePoint when you launch the app.
So, lets get this done –
1. Add a new entry in web.config to have office 365 tenant URL –
2. Update TokenHelper.cs class with following –
Add a Public static variable to hold the value –
Update the IsHighTrust method –
3. Set the SPHostURL variable value from Page_Init of Default.aspx.cs
That’s it to get through this one, the TokenHelper will now check if the URL of SPHost starts with the O365 tenant URL, it will send back the ACS context otherwise S2S context.
And just to complete this blog,
You can use this method to find out SP context (it returns null for In-Premise and a some context value for O365).
So, your Page_Load will look something like –
Hope this helps 🙂