This post is about developing and deploying an application which works both as a provider hosted add-in as well as a standalone application depending on the URL from which it is launched. So, if a user logins to O365 and click on the app, it will open a provider hosted add-in and follow O365 authentication and if I launch the app directly using URL, then it will ask me to login using ASP.Net credentials and will follow ASP.Net Identity Framework.
It took me some time to decide on the approach as normal ASP.Net application uses AuthorizeAttribute while SharePoint uses ActionFilterAttribute and TokenHelper.cs class which comes by default while creating provider hosted add-in. This post assumes that the reader is aware about:
- Provider Hosted Add-ins
- ASP.Net Web Application projects using Identity Framework
- Basics of MVC
Below are the steps I followed to achieve this.
- Create a provider hosted add-in using Visual Studio. You will end up with the below project structure:
- Install relevant nuget packages. Some of these will install other packages on which they are dependent. I installed the following:
- Microsoft ASP.NET Identity Core
- Microsoft ASP.NET Identity Owin
- Microsoft ASP.NET Identity EntityFramework
- Add relevant files in the project. When you create an ASP.Net MVC application, there are few files which gets added by default. Following is the list of such files which I added in the project:
- Views/Account -> complete folder
- Views/Manage -> complere folder
P.S. While copying all of these files; make sure the namespace of classes are correct
- Create the tables to store user credentials in your database. You can find the script here or download from internet. Run this script in your relevant database and add connection string in web.config.
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=AuthenticationProviderHosted;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
Also add this connection string name in IdentityModel.cs file.
- The final step is to add a common filter attribute which will work with both Sharepoint authentication and asp.net authentication. For this I created a new class called CommonContextFilterAttribute which inherits from AuthorizeAttribute. The code is simple here, if request has host URL present then authenticate using SharePoint else move to asp.net.
- In the HomeController.cs file change [SharePointContextFilter] to [CommonContextFilter]. Also, modify the Index action to handle the SP User class. I just added a host URL filter again to check if it is SP user or ASP.Net User. And you are done!
Try running the app as provider hosted add-in, just click on “Start” at the top and you will get the below screen
And if you run as standalone app then you will get below screen:
You can register a new user here and login to get the desired screen:
Notice the user name here i.e. email@example.com. I used this login to register a user and then logged in to the site.
Similarly, you can modify the code to integrate login through Facebook, Twitter or any other website using OWIN.
You can download the complete source code from here.
Note: To debug the add-in as a standalone application, please make the following changes:
- Set the web project as start-up project
- In the “Properties” of web project -> “Web” tab -> select “Current Page” as “Start Action”.
- Revert these changes to debug as SP add-in.
- You can deploy this project as a normal provider hosted add-in and it should work both ways. I tested by deploying the web project in IIS. Skipping the steps here as it is straightforward.
Hope this helps. Happy coding!