3

I'm trying to check user's Office Store license in SharePoint's provider hosted add-in using GetAppLicenseInformation method:

Microsoft.SharePoint.Client.Utilities.Utility.GetAppLicenseInformation(clientContext, productId)

The only difference is that I'm creating ClientContext using Azure AD AccessToken (example):

ClientContext clientContext = new ClientContext(spSiteUrl);
clientContext.ExecutingWebRequest += (sender, e) =>
{
    e.WebRequestExecutor.WebRequest.Headers["Authorization"] = "Bearer " + accessToken;
};

Regardless permissions set in Azure AD App I'm getting:

Microsoft.SharePoint.Client.ServerException: Access Denied: The app could not be authenticated or is not authorized to query licenses of this Product ID

Interesting fact: there's no problem with getting user's license using classic SharePoint ClientContext from TokenHelper.

Does anyone have idea how could I make it work?

3
  • 1
    Have you tried to check all permissions possible inside Azure AD for SharePoint? Also try to decode access token (because it's just jwt) using for example calebb.net and compare? Commented Feb 2, 2017 at 17:27
  • @SergeiSergeev yes, that's the first thing I did, same result. I will try to decode access token as you suggested and come back with results, thanks! Commented Feb 2, 2017 at 20:15
  • @SergeiSergeev so I've checked the token, everything seems correct, even updated ADAL to v3, still no success. That's pretty confusing since I have access to all other SharePoint's resources, except user's license. Commented Feb 3, 2017 at 6:17

1 Answer 1

3

From my understanding it's not possible. Let me explain why.

Access token holds also Id of the app, i.e. ClientId. In order to get licensing info, they are (MS) checking some internal database. I think they are using ClinetId (as well as user identity) in order to find the match.

Your CliendId registered as Azure Ad app and thus license validation process can't find it under licenses store for SharePoint apps and you got an error.

As you understand, the only option is to use access token obtained for this particular sharepoint add-in (not azure).

UPD actually reflector is not a bad idea. I found that all licenses are stored inside App Management database. May be that is the reason why you can't get license - there are no records about your add-in (since it Azure AD) in database.
Here is the code found in Microsoft.SharePoint.dll:

public SPAppLicense[] CheckLicense(Guid productId, string appId, string userKey, bool isExternalCall, out bool appAuthenticationFailed)
{
    SPAppLicense[] result;
    using (new SPMonitoredScope("AppManagementServiceApplicationProxy.CheckLicense"))
    {
        Guid rawPartitionId = this.GetRawPartitionId(SPServiceContext.Current);
        byte[] array = AppManagementServiceDatabase.GenerateCompositeKey(rawPartitionId, AppManagementDataSetType.AppLicensing, productId);
        SPAppLicense[] array2 = null;
        SqlParameter errorCodeParameter = null;
        appAuthenticationFailed = false;
        byte[] compositePartitionKey = array;
        bool? isExternalCall2 = new bool?(isExternalCall);
        using (SPSqlCommand sPSqlCommand = SPStoredProceduresAppMng.proc_AM_CheckLicense(userKey, compositePartitionKey, appId, isExternalCall2, out errorCodeParameter))
        {
            array2 = (SPAppLicense[])SPScaleOutDatabaseCommandExecutor.Execute(delegate(SqlSession sqlSession, SPSqlCommand command, out SPScaleOutDatabaseQueryErrorCode errorCode)
            {
                object result2;
                using (SPSqlDataReader sPSqlDataReader = sqlSession.ExecuteSPReader(command))
                {
                    errorCode = AppManagementServiceApplicationProxy.GetScaleOutDatabaseQueryErrorCode(errorCodeParameter);
                    if (errorCode != SPScaleOutDatabaseQueryErrorCode.None)
                    {
                        result2 = null;
                    }
                    else
                    {
                        result2 = AppManagementServiceApplicationProxy.GetAppLicenseCollectionFromSqlDataReader(sPSqlDataReader);
                    }
                }
                return result2;
            }, this, sPSqlCommand, array);
        }
        if ((int)errorCodeParameter.Value == -11)
        {
            appAuthenticationFailed = true;
        }
        else
        {
            AppManagementServiceApplicationProxy.HandleLicenseErrorCode(errorCodeParameter);
        }
        result = array2;
    }
    return result;
}
7
  • Sounds reasonable, but the exception says about denied access, and not problems with finding assigned license. Secondly, error appears while getting license information from local SharePoint, not Office Store (validation in the Office 365 services is not called at this point yet). Commented Feb 3, 2017 at 9:10
  • I would not pay attention at the message, sometimes the reason for the exception may be completely different. I believe SharePoint holds some license database behind the scene. Of course it's just my assumptions Commented Feb 3, 2017 at 9:33
  • Sure, it might. I believe the only way to check it is to decomplie Microsoft.SharePoint.Client.dll. Thanks Microsoft. Commented Feb 4, 2017 at 11:00
  • 1
    Do you have app web? If not, try to create app web for you provider hosted app (by adding empty element into the project for app web) and try to check license again. Commented Feb 4, 2017 at 11:49
  • yep, tried that also, but I'm not sure if the App Web has been actually created. Commented Feb 6, 2017 at 21:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.