Tuesday, April 23, 2013

SharePoint 2013 Elivating app permissions beyond the user permissions

Scenario: How to alleviate app permissions, say for example you want your app to add an item to a list, but user using the app doesn't have write permissions on the list. So how can you still make an app add a list item, when run by a user with read only permissions on a list?

Solution: Well to achieve this do not use user permissions at all. Just use app-only permissions  to elevate the permissions of the app above the current user running the app.

We can achieve this by adding "AllowAppOnlyPolicy" attribute to "AppPermissionRequests". Using this approach we can create an app that does some job repetitively, similar to timer jobs.

For more detailed information on this topic refer:-
http://blogs.msdn.com/b/kaevans/archive/2013/02/23/sharepoint-2013-app-only-policy-made-easy.aspx

SharePoint2013 Note on AppPrincipal

AppPrincipal Indicates what kind of authentication an app requires and what type of app it is.

Various types of AppPrinciplas are:-
1. Internal: This is the default for SharePoint Hosted apps. Indicates that no external authentication is required.

Some times a cloud-hosted app can use "internal" auth when calling back using cross-domain library. To achieve this you should configure AppPrincipal  with "Internal" element with attribute "AllowedRemoteHostUrl".

2. RemoteWebApplication: This is the default for a Provider Hosted apps. Indicates that app requires external authentication like Oauth
3. AutoDeployedWebApplication: Indicates that App is autohosted and requires external authentication.

Saturday, April 20, 2013

SharePoint2013: Shopping Cart Provider hosted app prototype

Scenario: How to develop a shopping cart provider hosted app prototype using managed CSOM

Solution: Create a Provider Hosted App using "App for SharePoint2013" template

Add the following code in the remote web (web application) projects home\landing page (.aspx) within the "body\form" section.

Add the following code in remote webs home\landing page code behind.

Call the "RetrieveWithCSOM" function in Page_Load, passing it the accessToken.

The sample shopping cart prototype app UI looks like below
 
Note: If your Remote webapplication is located outside the firewall , you may see 401 error while remote webapplication is trying to talk back to SharePoint, in this scenario use Cross-domain library to talk back to SharePoint.

Friday, April 12, 2013

SharePoint2013 Provider hosted app with ACS trust unable to talk back to SharePoint with Error: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. Certificate error

Scenario: When your provider hosed apps remote app web\webapplication is trying to talk back to SharePoint you may receive an Error: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. Certificate error.

Resolution: Although you may get this error for several reasons with SharePoint, one that worked for me within the context of the apps is: Open the website in the browser and Install the certificate to the local machines trusted root authority, by clicking on the "Lock" icon in the browsers address bar.

SharePoint2013 Provider hosted app with ACS trust unable to retrive Access Token. Error message: 400 Bad Request. Token request failed

Scenario: Provider hosted app with ACS trust unable to retrieve Access Token. The request for access token failed with error: 400 Bad Request. Token request failed.

Solution: Today I came across this issue, were the app gets the context and refresh token, but unable to get the Access Token. The issue was, Service Principal name (SPN) of the SharePoint site was deleted from azure.

 As part of establishing ACS trust in an on-premise farm we need to register the web application in Azure, so that ACS trusts the web application and will be prepared to accepts request from the web application for issuing Access token. So if you have more than one web application in your SharePoint farm you need to register each web application as SPN. Say if your web application URL is https://sharepoint.contoso.com then your SPN would be "sharepoint.contoso.com" OR if you have multiple web applications in your SharePoint farm ending with say "contoso.com" then you can register wild card SPN like "*.contoso.com".

To fix the issue check if SPN is registered on Azure by running below scripts from azure powershell window:-

$SPAppPrincipalId ="00000003-0000-0ff1-ce00-000000000000"
$ACSMetaDataEndPoint = "https://accounts.accesscontrol.windows.net/{0}/metadata/json/1" -f $SharePointAzureTenantName
Connect-MsolService
$ExistingKeyIds = Get-MsolServicePrincipal -AppPrincipalId $SPAppPrincipalId
$Spns = $ExistingKeyIds.ServicePrincipalNames
 
To Add the SPN run below scripts from azure powershell window:-
$FarmFQDN = "sharepoint.contoso.com"
$ServicePrincipalName = "{0}/{1}" -f $SPAppPrincipalId, $FarmFQDN
$Spns.Add($ServicePrincipalName)
  Set-MsolServicePrincipal -AppPrincipalId $SPAppPrincipalId -ServicePrincipalNames $Spns

Note: Replace "$FarmFQDN" with SPN of your web application.