Issue Description

When using the K2 for SharePoint App with an on-premises SharePoint farm, the users may experience one of the following exception errors:

  • Microsoft.SharePoint.ClientServerUnAuthorizedAccessException with message: Access denied. You do not have permission to perform this action or access this resource.
  • System.Net.WebException 401 with message: Access denied. You do not have permission to perform this action or access this resource.

Image

The issue may occur for users in the following scenarios:

  • Any call that uses the K2 for SharePoint app’s OAuth security mechanism, which includes the following:
    • When clicking the app on the ribbon of a SharePoint List or Document Library.
    • When performing Create, Read, Update or Delete operations on SharePoint objects, such as list items using K2 smartforms on a list that has been activated using the K2 for SharePoint app.
    • Running workflows against a SharePoint objects, such as list items.

SharePoint has a +-15 minute cache that is resolved by looking into what groups the user belongs to by interpreting the OAuth token and then trying to resolve the groups by the User Profile store. It relies on the user profile synchronization configuration to be correct, which include the following:

  • Fully functional synchronization connection.
  • Fully functional profile import.

The following images illustrate the settings for a fully functional synchronization connection:

Image

And:

Image

The following image illustrates a fully functional profile import:

Image

Confirming the Issue

Unfortunately, the 401 exception is a widely used exception and there may be situations where 401 errors are thrown due to other issues not applicable this article. To confirm that the 401 exception is caused by the underlying issue described by this article, the following steps need to be followed. The following logs and configuration will indicate the existence of this known issue:

  1. Domain Security Group confirmation - The user who encountered the issue is not directly added into a SharePoint group on the site but added via a Domain Security group.
    1. In the following example, the users Tiaan, Maude and Jimi would not encounter this issue, but users that are in the CRICKET\domain users security group and not directly in the SharePoint group, will encounter the issue.
      Image
  2. ULS log confirmation - The following SharePoint ULS log entries will confirm the existence and validity of this issue. The entries will be fairly close to each other in the log and the following text can be used to search for the respective user’s 401 error:
    Permission check failed. asking for 0x10000, have 0x2000000000
    System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
    Throw UnauthorizedAccessException instead of SPUtilityInternal.Send401 for client.svc.

Note that Authentication and Authorization logging settings have to be set to Verbose in the SharePoint Diagnostic Logging in SharePoint Central Admin, as shown below
Image

Workarounds

SharePoint is reliant on a functional User Profile Synchronization service in order to construct user security context from an OAuth token. K2 for SharePoint uses OAuth tokens to communicate with SharePoint. During this process, SharePoint constructs the user information from the received token and caches the security context.

The K2 for SharePoint solution requires the User Profile Application (UPA) database in SharePoint be populated correctly. The reason for this is because SharePoint 2013 uses UPA to validate OAuth Tokens that are passed to it.
To determine if the UPA is populated correctly, simply login to SharePoint as the user in question and navigate to the following URL:
https://<siteurl>/_api/SP.UserProfiles.PeopleManager/GetMyProperties
This will return all of the UPA properties. Ensure that the following UPA properties are populated:
SPS-ClaimID
SPS-ClaimProviderID
SPS-ClaimProviderType
SPS-UserPrincipalName

If these UPA properties are not populated, ensure that the User Profile Service has been configured correctly. See below detailed steps on how to configure the User Profile Service or see the following article for more information:

Create, edit, or delete User Profile service applications in SharePoint Server 2013

The below steps provide detailed information to configure the User Profile Service. This assists in avoiding the aforementiond issue.

      1. Open Central Administration.
      2. Click on Manage service applications

        Image

      3. Click on User Profile Service Application

        Image

      4. Click Configure Synchronization Connections.

        Image

      5. Click on New Connection, or edit an existing connection if available.

        Image

      6. Complete the connection settings, and click on Populate Containers.
      7. Select the required containers that need to be imported.

        Image

        Note:  Ensure that the Organizational Units (OU's) contain the user and group in question and are selected as shown above via the green tick.
      8. Click OK.
      9. Go back to the User Profile Service.
      10. Click on Start Profile Synchronization.
      11. Click OK.
      12. Wait for the Synchronization to complete.

If the issue still occurs after configuring the User Profile Service see the below the two provide workarounds.

The proposed workarounds will require a waiting period of about 15 minutes for this cache to expire and be refreshed with new information. Either one of the following workarounds can be applied:

  • Workaround 1: Add user directly into SharePoint group
    1. Add the respective user directly into the SharePoint group and run an incremental user profile synchronization job.
  • Workaround 2: Delete the user’s OAuth Token from the K2 Database.
    Warning: This is a more technical solution and caution is advised when working directly on the K2 Database.
    1. Obtain the user’s PrimaryCredential ID from the [HostServer].[SecurityCredentialCache] table. For example, if we wanted to obtain the PrimaryCredential for the user Denallix\Mark, locate Mark's username in the UserName column and then copy the value of the PrimaryCredential column to notepad:
      Image
    2. Open the [Authorization].[OAuthIdentity] table and use the Guid of the PrimaryCredential you obtained in step 1 against the PrimaryCredentialID column to locate the user’s OAuthIdentity token entry. Make a note of the value for the ID column, and then delete that row from the table. In the sample below, we would delete the first row from the table since this row represents Mark's OAuthIdentity entry:
      Image
    3. Open the [Authorization].[OAuthToken] table and use the ID obtained in Step 2 against the OAuthIdentityId column to locate the token, and then delete that row from the table. In the sample below, we would delete the first row since this represents the encrypted token for the user Mark
      Image