ASP.NET MVC Integration with Sharepoint 2013. Part 1: High-Trusted provider-hosted APP


    My name is Denis and I work as a senior developer at DoxVision. With this post I want to start a series of articles related to development in the field of SharePoint 2013. They will cover various aspects of this topic, starting with the possibilities of basic integration of a Web application and ending with publication in the SharePoint Store. Knowing the nuances and pitfalls that I came across can be useful to those who will face a similar task for the first time.

    So, following the chronology, I’ll start by describing how I solved the first task set for me: on the basis of the existing ASP.NET MVC application “Docsvision Easy Client” create a new one - “Docsvision Client for SharePoint”, which would integrate into SharePoint 2013 and expand its Light client capabilities.

    In SharePoint 2013, a new model of Apps has appeared, which is fundamentally different from the old model of Solutions. However, you should not be scared - Solutions have not disappeared. First of all, you should choose what to use: Solutions or App. An article on MSDN can help with this issue .
    Our choice fell on the Sharepoint App, as integration requirements at that time could well be implemented through the App. In the future, when we decided to integrate into the Sharepoint store, it turned out to be absolutely correct, because, as you will see in the following articles, Solutions cannot be placed in the Sharepoint store.
    Despite all this, no one forbids using both approaches. In the following articles I will definitely tell you how we managed to connect App and Solutions.

    Let us dwell on our choice - SharePoint App. According to the documentation, there are several integration options: SharePoint-hosted, Auto-hosted, Provider-hosted. Considering that our application is not a Web API, but MVC in the classic version and that the application will be delivered on-premises - we decided to use the High-Trusted Provider-Hosted App option. High-Trusted implies that our Web application communicates with SharePoint through a one-to-one certificate. There is also the so-called Low-Trusted mode - it is used for the SharePoint Store or in the company's local corporate application directory.

    So, we all decided, set up a testing ground with SharePoint 2013 - and here we are met by the first surprise from Microsoft - you can’t just take and create an App and implement it in SharePoint. First we need to prepare SharePoint for using the App. The preparation process is described in detail on MSDN . I will briefly go over the points:
    1. verify that SharePoint services are running: User Profile Service Application, App Management Service
    2. check for at least one SharePoint user profile and create one if not
    3. create an isolated application domain
    4. configure DNS for application domain address

    On the 3rd point, you need to stop in more detail. What is an application domain? When you install an application (APP) in SharePoint, it is allocated a unique address where you can access this App-application. The address looks like this: http: // [app prefix] - [app id]. [Domain name] / [site collection path] / [app path] /pages/default.aspxwhere app prefix is ​​the application prefix for the entire SharePoint farm; app id - a unique identifier for the application; domain name - application domain. Actually, the configuration of the application domain - this is the setting of the app prefix and domain name values, and they could be set through Central Administration (Apps -> Configure App URLs), if not one but - you must first create two new services SubscriptionSettingsServiceApplication and SPAppManagementServiceApplication. I will provide a slightly improved PowerShell script below to create these services and configure application domain settings:
    $appDomain = "your app domain"
    $appPrefix = "your app prefix"
    $accountName = "your account name"
    $accountPassword = "your account password"
    net start spadminv4 
    net start sptimerv4 
    $existedAppDomain = Get-SPAppDomain
    $existedAppPrefix = Get-SPAppSiteSubscriptionName
    if (!existedAppDomain || !existedAppPrefix)
            if (!$existedAppDomain)
               Set-SPAppDomain $appDomain -ea:Stop
            Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"} | Start-SPServiceInstance
            Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"}
            $User = $accountName
            $account = Get-SPManagedAccount  -Identity $User -ea:Silently
               $PWord = ConvertTo-SecureString –String $accountPassword –AsPlainText -Force
               $Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord
               $account = New-SPManagedAccount -Credential $Credential -ea:Stop
            $appPoolSubSvc = Get-SPServiceApplicationPool -Identity SettingsServiceAppPool 
            if (!$appPoolSubSvc)
               $appPoolSubSvc = New-SPServiceApplicationPool -Name SettingsServiceAppPool -Account $account
            $appPoolAppSvc = Get-SPServiceApplicationPool -Identity AppServiceAppPool 
            if ($appPoolAppSvc!)
               $appPoolAppSvc = New-SPServiceApplicationPool -Name AppServiceAppPool -Account $account
            $appSubSvc = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPoolSubSvc –Name SettingsServiceApp –DatabaseName SettingsServiceDB 
            $proxySubSvc = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $appSubSvc
            $appAppSvc = New-SPAppManagementServiceApplication -ApplicationPool $appPoolAppSvc -Name AppServiceApp -DatabaseName AppServiceDB
            $proxyAppSvc = New-SPAppManagementServiceApplicationProxy -ServiceApplication $appAppSvc
            Set-SPAppSiteSubscriptionName -Name $appPrefix -Confirm:$false -ea:Stop

    I want to warn that the last command for some reason is very resource-intensive and may require all the minimum requirements of SharePoint to the physical components of the server (hardware). In my case, the command was not executed several times, because there was not enough free memory on the virtual machine. If you previously reinstalled SharePoint, you will need to delete the existing SettingsServiceDB and AppServiceDB database files.

    So, SharePoint is installed and configured for our applications. Now you need SharePoint to report that our Web application will be trusted. This process is described in detail here .
    In short, it is necessary
    1. create a self-signed IIS certificate (this certificate is suitable only for the debug stage, for complete solutions, a domain or commercial certificate is required)
    2. upload pfx and cer files
    3. upload the certificate to SharePoint and associate it with our web application

    At the last point I will stop and sign in more detail. Essentially, you need to run the following PowerShell script:
    $publicCertPath = "publicCertPath *.cer"
    $appId = "app Id Guid"
    $spurl ="SharePoint site url"
    $appPrincipalDisplayName = "your app pricipal name"
    $spweb = Get-SPWeb $spurl
    $realm = Get-SPAuthenticationRealm -ServiceContext $spweb.Site
    $certificate = Get-PfxCertificate $publicCertPath
    $fullAppIdentifier = $appId + '@' + $realm
    $principal = Get-SPAppPrincipal –NameIdentifier $fullAppIdentifier -Site $spweb 
    	$issuer = Get-SPTrustedSecurityTokenIssuer | where {$_.NameId -eq $fullAppIdentifier} 
    	if ($issuer) 
    	Remove-SPTrustedSecurityTokenIssuer -Identity $issuer.Id -Confirm:$False -ea:Stop
    	New-SPTrustedSecurityTokenIssuer -Name $appPrincipalDisplayName -Certificate $certificate -RegisteredIssuerName $fullAppIdentifier -Confirm:$False -ea:Stop
    	$principal = Register-SPAppPrincipal -NameIdentifier $fullAppIdentifier -Site $spweb -DisplayName $appPrincipalDisplayName
    Set-SPAppPrincipalPermission -Site $spweb -AppPrincipal $principal -Scope Site -Right FullControl

    After executing this script, any remote application with the identifier $ appId will be able to access the SharePoint items through a certificate with a private key (pfx).
    It’s worth remembering the app id. This is the identifier of our Web application. It will be used later in the web.config Web application under the name IssuerId.

    The final step is to create a SharePoint App application. This process is described in detail later in the article.. When creating a project, the Wizard will offer to fill out a number of parameters: Issuer Id (the app id generated by us), the path to the pfx certificate, and the password for the certificate. The created Web application can be replaced with an existing one in Visual Studio solution in the project properties. After connecting the SharePoint project and the Web application in the Web application, the parameters are filled in the web.config file:

    Also, useful classes SharePointContext.cs and TokenHelper.cs will appear in the Web application project. These classes provide quite a few features for interacting with SharePoint.

    This completes the integration. If you then start the SharePoint App project through debug - SharePoint will first ask for permissions for our App. After accepting the permissions, going through a special SharePoint page (appredirect.aspx), we will get to the root of our Web application. It is believed that the integration process has been completed at this, however, as will be seen later, many pitfalls await us.

    In the following articles I’ll describe in more detail how to organize interaction with SharePoint (search and reading of documents and other elements of SharePoint), create app-parts, localize App, create your own RibbonTab, automate the installation of App & Solution and how to prepare for publication on the SharePoint Store.

    Also popular now: