Standalone SharePoint Add-In

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.

  1. Create a provider hosted add-in using Visual Studio. You will end up with the below project structure:

    ProviderHostedAdd-In

  2. Install relevant nuget packages. Some of these will install other packages on which they are dependent. I installed the following:
    1. Microsoft ASP.NET Identity Core
    2. Microsoft ASP.NET Identity Owin
    3. Microsoft ASP.NET Identity EntityFramework
    4. Microsoft.Owin.Host.SystemWeb

      Nugetpackages

  3. 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:
    1. App_Data/IdentityConfig.cs
    2. App_Data/Startup.cs
    3. Controllers/AccountController
    4. Controllers/ManageController
    5. Models/AccountViewModel.cs
    6. Models/IdentityModel.cs
    7. Models/ManageViewModels.cs
    8. Views/Account -> complete folder
    9. Views/Manage -> complere folder
    10. Views/Shared/_LoginPartial.cshtml

      P.S. While copying all of these files; make sure the namespace of classes are correct

      NewClasses

  4. 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.

  5. 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.

    FilterAttribute

  6. 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

ProviderAddInRun

And if you run as standalone app then you will get below screen:

Stanalone

You can register a new user here and login to get the desired screen:

Stanalone-LoggedIn

Notice the user name here i.e. garima@outlook.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!

Advertisements

Manage Licenses in O365 using Powershell

Few days back, I got stuck in a weird issue while creating users in O365. For some of the users, the services like SharePoint, Exchange etc. were displaying “setting up…” status. I checked and was informed that it might take up to 4 hours for services to set up but even after 2 days, the issue was not resolved. I tried to remove and assign the license again for one of the user and it started working. As I have lots of users, I can not do it manually so eventually I ended up using powershell.

This post will take you through the process I followed while trying to resolve this issue and also the powershell script.

  1. The first step was to install Microsoft Online Services Sign-In assistant and Windows Azure Active Directory (Azure AD) module for Windows Powershell in my system. Both are 64 bit versions and you can find more details about it here.
  2. After that launch the powershell and connect to the tenant which is facing the issue using the Connect-MsolService command. It will ask for your O365 credentials.
    Powershell Credential Window
  3. To get the AccountSkuId and included ServicePlans for your tenant, you can use the following command:
    Get-MsolAccountSku | Where-Object {$_.SkuPartNumber -eq “yourpackname“} | ForEach-Object{$_.ServiceStatus}
    Account Details
    As you can see in the above screenshot, we now have tenant’s AccountSkuId and all the service plans with their status. Similarly, we can get the status of service plan assigned to all the users. For faulty licence assignment, usually the provisioning status is “Pending Input”.
  4. Next step is to create a CSV of all the users for which this issue is present. Let’s say the name of CSV is UsersList.csv.
  5. Run the below powershell command to remove and assign licenses again:
    $allUsers = Get-Content "{PathofFile}\UsersList.csv"
    :Outer foreach ($user in $allUsers)
    {
      Write-Host($user) -foregroundcolor "magenta"
      $IsFaulty = "false";
      $O365User = Get-MsolUser -User $user
      $Licenses = $O365User.Licenses[0].ServiceStatus
      :Inner foreach($lic in $Licenses) {
         If ($lic.ServicePlan.ServiceName -eq "SHAREPOINTSTANDARD_EDU" -and $lic.ProvisioningStatus -ne "Success")
         {
           $IsFaulty = "true"
            break Inner
          }
     }
     If ($IsFaulty -eq "true")
     {
       Set-MsolUserLicense -User $user -RemoveLicenses {AccountSkuId:screenshot2}
       Set-MsolUserLicense -User $user -AddLicenses {AccountSkuId:screenshot2}
     }
    }
    

The above code first reads all the users from the CSV file. After that it checks their SharePoint service status and reassigns the licence if the status is not equal to “Success”. You can check for any other service which is applicable to you.

The name of services are different for different plans so make sure to execute step 3 for exact service names. One important thing to note here is, if you remove the license, users might lose all of their data. In my scenario, the users were newly created so that was not an issue, but if that is the case don’t run this script.

Hope this helps!

References: