Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

the Method not found: AcquireToken(System.String, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate)

I followed the following document to create a x509 certificate with the Azure AD App Registration.

https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread

I generated the .pfx file, set the password, and I also registered the app in my tenant Azure AD, and then updated the manifest with the keycredentials section.

Then, I am creating a WEB API that receives some parameters, including the .pfx file.

 [HttpPut]
        public async Task<IHttpActionResult> PutTenant([ModelBinder(typeof(TenantModelBinder))] Tenant tenant)
        {
            try
            {               
                var cert = new X509Certificate2(tenant.CertificateFile, tenant.CertificatePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

                using (var cc = new OfficeDevPnP.Core.AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(tenant.SiteCollectionTestUrl, tenant.ApplicationId, tenant.TenantDomainUrl, cert))
                {
                    cc.Load(cc.Web, p => p.Title);
                    cc.ExecuteQuery();
                };
            }
            catch (System.Exception)
            {
                return BadRequest("Configuration Invalid");
            }

I am using the bytearray coming from the HttpRequest to create the x509 object.

However I get this error:

Message "Method not found: 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.AcquireToken(System.String, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate)'."   string

Stacktrace:

at OfficeDevPnP.Core.AuthenticationManager.<>c__DisplayClass36_0.<GetAzureADAppOnlyAuthenticatedContext>b__0(Object sender, WebRequestEventArgs args)\r\n   at Microsoft.SharePoint.Client.ClientRuntimeContext.OnExecutingWebRequest(WebRequestEventArgs args)\r\n   at Microsoft.SharePoint.Client.ClientContext.GetWebRequestExecutor()\r\n   at Microsoft.SharePoint.Client.ClientContext.GetFormDigestInfoPrivate()\r\n   at Microsoft.SharePoint.Client.ClientContext.EnsureFormDigest()\r\n   at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()\r\n   at TenantManagementWebApi.Controllers.TenantController.<PutTenant>d__2.MoveNext() in C:\\Users\\levm3\\source\\repos\\TenantManagementWebApi\\Controllers\\TenantController.cs

The error is thrown in the executequery

really clueless here.

Update:

I noticed this in my web.config

 <dependentAssembly>
        <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-3.19.5.13701" newVersion="3.19.5.13701"/>
      </dependentAssembly>

and this on my packages.config

  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.5" targetFramework="net461" />
like image 714
Luis Valencia Avatar asked Jul 05 '18 21:07

Luis Valencia


1 Answers

PnP Core currently uses the older version, 2.29.0, of the Microsoft.IdentityModel.Clients.ActiveDirectory package.

Best would be that you downgrade the version used in your API project to the one used by PnP Framework which will work for sure.

Related to the error, the framework is calling the AuthenticationContext.AcquireToken method internally which has been deprecated in the newer Nuget v3 package.

So, it looks like the PnP code is calling this method belongs to the v2 version while the correct method of v3 package to use is AcquireTokenAsync of the v3 version which is resulting in the conflict.

Reference - OfficeDevPnP Core package.config file

Now , we can see that the is already a PR in place to update the nuget package in the PnP Framework itself, which when accepted will solve your issue right away. But might take some to get accepted, so dont hold your breath :)

AuthenticationResult.AcquireToken deprecated in ADAL 3.x and how to fix.

Microsoft Docs - AuthenticationContext.AcquireTokenAsync Method

So best would be that you either downgrade your API project to v2 or wait for the PnP Framework to upgrade the package and its necessary dependencies.

Another option, if you are only using PnP to authenticate, then you can use the below helper method which wont require you to change the package. But if you using other functionality like provisioning or other extensions, then you need to downgrade it unfortunately. This is modified from what is used internally in PnP itself to make use of the v3 package changes :

public ClientContext GetAzureADAppOnlyAuthenticatedContext(string siteUrl, string clientId, string tenant, X509Certificate2 certificate)
{
    var clientContext = new ClientContext(siteUrl);

    string authority = string.Format(CultureInfo.InvariantCulture, "https://login.windows.net/{0}/", tenant);

    var authContext = new AuthenticationContext(authority);

    var clientAssertionCertificate = new ClientAssertionCertificate(clientId, certificate);

    var host = new Uri(siteUrl);

    clientContext.ExecutingWebRequest += (sender, args) =>
    {
        var ar = authContext.AcquireTokenAsync(host.Scheme + "://" + host.Host + "/", clientAssertionCertificate).GetAwaiter().GetResult();
        args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + ar.AccessToken;
    };

    return clientContext;
}
like image 77
Gautam Sheth Avatar answered Oct 14 '22 13:10

Gautam Sheth