This post is article 30 from the 30 Articles App series for SharePoint
In this article, I will discuss about Licensing your SharePoint app on office store.
When you upload your app on the Office Store for publication, you can choose the terms of the license you want to offer, like offering your app for free, trial, or for purchase. Or your app can be acquired on a per-user or site basis.
SharePoint provides a licensing framework that lets you include code logic in your app to enforce whatever licensing restrictions you choose. For example, you can include code logic in your app that enables users to access certain app features if they have a paid license, but not if they have a trial license.
A user with a license for an app can use that app on any site for that particular SharePoint deployment. In general, for the purpose of app licenses, deployment is defined as the SharePoint farm for on-premises SharePoint installations, and the tenancy for SharePoint Online in Office 365. The app’s purchaser can manage the app license, assign those app licenses to other users within their deployment, and enable other users to manage the licenses. A user who is assigned an app license can access and use the app.
For apps for SharePoint that have a per-user license, each app license can be assigned to the specified number of SharePoint users. The app license applies only to the specified SharePoint deployment and the specified users.
For apps with a site license, that license is assigned to all users on that deployment automatically. You cannot programmatically assign app licenses.
App license query and validation process :
1. The user launches the app from within SharePoint.
2. This launches the app code in the cloud.
3. When the app needs to verify a user’s app license, it uses server-side code to query SharePoint, via the client object model, for the app license token.
4. It then passes that token to the Office Store verification service.
5. The verification service returns whether the license token is valid, and if it is, also returns the license properties.
6. The app can then take action, based on the validity of the license and its properties
Finally, after you finish testing your app and are ready to move it to production, you need to add code to the license checks in your app so that the app no longer accepts test licenses.
Let’s validate app’s Validate the app license token in code:
Retrieving app license tokens using GetAppLicenseInformation :
productId = new Guid(); using(ClientContext ctx = new ClientContext(webUrl)) { ClientResult licensecollection = Microsoft.SharePoint.Client.Utilities.Utility.GetAppLicenseInformation(ctx, productId); ctx.ExecuteQuery(); }
Validating the app license token
After you retrieve the appropriate app license token, pass that token to the Office Store verification web service for validation. The verification service is located at the following URL: https://verificationservice.officeapps.live.com/ova/verificationagent.svc
The Office Store license verification web service also supports verifying app license tokens using REST calls. To verify an app license by using REST, use the following syntax:
https://verificationservice.officeapps.live.com/ova/verificationagent.svc/rest/verify?token=token
Where {token} is the app license token
For test app licenses, the IsTest property returns true and the IsValid property returns false.
This sample requires a reference to Microsoft.SharePoint.Client.Utilities, and a web service reference to the Office Store verification service.
retrieving app license tokens : GetAppLicenseInformation
//Get the license token XML from SharePoint. this.rawToken = GetLicenseTokenFromSP(this.productId, this.clientcontext); //Call the Office Store verification service. VerifyLicenseToken(this.rawToken); private string GetLicenseTokenFromSP(Guid productId, ClientContext clientContext) { //Get the license from SharePoint. ClientResult licenseCollection = Utility.GetAppLicenseInformation(clientContext, productId); clientContext.Load(clientContext.Web); clientContext.ExecuteQuery(); foreach (AppLicense license in licenseCollection.Value) { //Just get the first license token for now. rawLicenseToken = license.RawXMLLicenseToken; break; } return (rawLicenseToken); } private void VerifyLicenseToken(string rawLicenseToken) { if (string.IsNullOrEmpty(rawLicenseToken)) { licVerifyEndPoint.Text = "There is no valid license for this user in SharePoint (OR) license cannot be obtained due to some error - check ULS."; return; } VerificationServiceClient service = null; VerifyEntitlementTokenResponse result = null; VerifyEntitlementTokenRequest request = new VerifyEntitlementTokenRequest(); request.RawToken = rawLicenseToken; lblSPLicenseText.Text = System.Web.HttpUtility.HtmlEncode(request.RawToken); try { service = new VerificationServiceClient(); result = service.VerifyEntitlementToken(request); } catch (EndpointNotFoundException) { licVerifyEndPoint.Text = "Cannot access verification service endpoint"; } catch (FaultException) { licVerifyEndPoint.Text = "Error: entitlement verification service is unavailable."; } catch (FaultException internalFault) { licVerifyEndPoint.Text = "Error: entitlement verification service failed. Details: " + internalFault.Detail.Message; } catch (Exception exception) { licVerifyEndPoint.Text = "Error: entitlement verification service failed. Details: " + exception; } if (result != null && result.AssetId !=null) { string licenseDetails = string.Format("Asset Id: {0}; Product Id: {1}; License Type: {2}; Is Valid: {3}; License Acquisition Date: {4}; License Expiry Date: {5}; IsExpired: {6}; IsTest: {7}; IsSiteLicense: {8}; Seats: {9}; TokenExpiryDate: {10}", result.AssetId, result.ProductId, result.EntitlementType, result.IsValid, result.EntitlementAcquisitionDate, result.EntitlementExpiryDate, result.IsExpired, result.IsTest, result.IsSiteLicense, result.Seats, result.TokenExpiryDate); if (result.EntitlementType.ToUpper() == "FREE") { //Allow basic functionality } else if (result.EntitlementType.ToUpper() == "PAID") { //Allow all functionality } else //trial { //Allow limited functionality } } else { licVerifyEndPoint.Text = "Verification service didn't return any results"; } }
Hope you have enjoyed this series !!