找不到方法:AcquireToken(System.String, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate)
the Method not found: AcquireToken(System.String, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate)
我按照以下文档创建了带有 Azure AD 应用程序注册的 x509 证书。
https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread
我生成了 .pfx 文件,设置了密码,还在我的租户 Azure AD 中注册了该应用程序,然后用密钥凭证部分更新了清单。
然后,我正在创建一个 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");
}
我正在使用来自 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>
还有我的 packages.config
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.5" targetFramework="net461" />
PnP Core 当前使用 Microsoft.IdentityModel.Clients.ActiveDirectory
包的旧版本 2.29.0
。
最好将 API 项目中使用的版本降级为 PnP Framework 使用的版本,这肯定会起作用。
与错误相关,框架正在内部调用 AuthenticationContext.AcquireToken
方法,该方法已在较新的 Nuget v3 包中弃用。
因此,看起来 PnP 代码正在调用此方法属于 v2 版本,而要使用的 v3 包的正确方法是导致冲突的 v3 版本的 AcquireTokenAsync
。
参考 - OfficeDevPnP Core package.config 文件
现在,我们可以看到 PR 已经准备好更新 PnP 框架本身中的 nuget 包,接受后将立即解决您的问题。但可能需要一些时间才能被接受,所以不要屏住呼吸 :)
AuthenticationResult.AcquireToken deprecated in ADAL 3.x and how to fix.
Microsoft 文档 - AuthenticationContext.AcquireTokenAsync Method
最好是将 API 项目降级到 v2 或等待 PnP 框架升级包及其必要的依赖项。
另一种选择,如果您只使用 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;
}
我按照以下文档创建了带有 Azure AD 应用程序注册的 x509 证书。
https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread
我生成了 .pfx 文件,设置了密码,还在我的租户 Azure AD 中注册了该应用程序,然后用密钥凭证部分更新了清单。
然后,我正在创建一个 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");
}
我正在使用来自 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>
还有我的 packages.config
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.5" targetFramework="net461" />
PnP Core 当前使用 Microsoft.IdentityModel.Clients.ActiveDirectory
包的旧版本 2.29.0
。
最好将 API 项目中使用的版本降级为 PnP Framework 使用的版本,这肯定会起作用。
与错误相关,框架正在内部调用 AuthenticationContext.AcquireToken
方法,该方法已在较新的 Nuget v3 包中弃用。
因此,看起来 PnP 代码正在调用此方法属于 v2 版本,而要使用的 v3 包的正确方法是导致冲突的 v3 版本的 AcquireTokenAsync
。
参考 - OfficeDevPnP Core package.config 文件
现在,我们可以看到 PR 已经准备好更新 PnP 框架本身中的 nuget 包,接受后将立即解决您的问题。但可能需要一些时间才能被接受,所以不要屏住呼吸 :)
AuthenticationResult.AcquireToken deprecated in ADAL 3.x and how to fix.
Microsoft 文档 - AuthenticationContext.AcquireTokenAsync Method
最好是将 API 项目降级到 v2 或等待 PnP 框架升级包及其必要的依赖项。
另一种选择,如果您只使用 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;
}