Метод не найден: AcquireToken (System.String, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate)

Я выполнил следующий документ, чтобы создать сертификат x509 с регистрацией приложений Azure AD.

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

Я сгенерировал файл.pfx, установил пароль, и я также зарегистрировал приложение в моем арендаторе Azure AD, а затем обновил манифест с помощью раздела keycredentials.

Затем я создаю WEB API, который получает некоторые параметры, включая файл.pfx.

 [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");
            }

Я использую bytearray, исходящий из HttpRequest, чтобы создать объект x509.

Однако я получаю эту ошибку:

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

Трассировки стека:

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

Ошибка вызывается в executequery

действительно невежественный здесь.

Обновить:

Я заметил это в своем 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>

и это на моем package.config

  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.5" targetFramework="net461" />

Ответы

Ответ 1

В настоящее время PnP Core использует старую версию 2.29.0 пакета Microsoft.IdentityModel.Clients.ActiveDirectory.

Лучше всего было бы, чтобы вы понизили версию, используемую в вашем проекте API, до версии, используемой PnP Framework, которая будет работать точно.

В связи с этой ошибкой структура вызывает метод AuthenticationContext.AcquireToken внутри, который устарел в новом пакете Nuget v3.

Таким образом, похоже, что код PnP вызывает этот метод, принадлежащий версии v2, в то время как правильный метод использования пакета v3 - это AcquireTokenAsync версии v3, которая приводит к конфликту.

Справка - Файл Office пакета OfficeDevPnP Core.config

Теперь мы видим, что уже существует PR для обновления пакета nuget в самой PnP-платформе, которая, когда она будет принята, решит вашу проблему сразу. Но может потребоваться некоторое, чтобы принять, поэтому не задерживайте дыхание :)

AuthenticationResult.AcquireToken устарел в ADAL 3.x и как исправить.

Microsoft Docs - метод аутентификацииContext.AcquireTokenAsync

Лучше всего то, что вы либо понизите свой проект API до версии v2, либо дождитесь, пока PnP Framework обновит пакет и его необходимые зависимости.

Другой вариант, если вы используете PnP только для аутентификации, вы можете использовать вспомогательный метод ниже, который не требует от вас изменения пакета. Но если вы используете другие функции, такие как предоставление ресурсов или другие расширения, то вам, к сожалению, нужно понизить его. Это изменено из того, что используется внутри самого PnP, чтобы использовать изменения пакета v3:

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;
}