次のドキュメントに従って、Azure ADアプリ登録でx509証明書を作成しました。
https://docs.Microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread
.pfxファイルを生成し、パスワードを設定し、テナントのAzure ADにもアプリを登録し、keycredentialsセクションでマニフェストを更新しました。
次に、.pfxファイルを含むいくつかのパラメーターを受け取るWEB APIを作成しています。
[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コアは現在、2.29.0
パッケージの古いバージョンMicrosoft.IdentityModel.Clients.ActiveDirectory
を使用しています。
最善の方法は、APIプロジェクトで使用されているバージョンを、確実に機能するPnPフレームワークで使用されているバージョンにダウングレードすることです。
エラーに関連して、フレームワークはAuthenticationContext.AcquireToken
メソッドを内部的に呼び出していますが、これは新しいNuget v3パッケージで非推奨になっています。
したがって、PnPコードがこのメソッドを呼び出すのはv2バージョンに属しているように見えますが、使用するv3パッケージの正しいメソッドはv3バージョンのAcquireTokenAsync
であり、競合が発生しています。
リファレンス- OfficeDevPnP Core package.config ファイル
これで、PnPフレームワーク自体のnugetパッケージを更新するために既に [〜#〜] pr [〜#〜] が設定されていることがわかります。受け入れられたときに問題がすぐに解決されます。しかし、受け入れられるまでに時間がかかる可能性があるため、息を止めないでください:)
ADAL 3.xで廃止予定のAuthenticationResult.AcquireTokenと修正方法
Microsoft Docs- AuthenticationContext.AcquireTokenAsyncメソッド
したがって、APIプロジェクトをv2にダウングレードするか、PnPフレームワークがパッケージとその必要な依存関係をアップグレードするのを待つことが最善です。
別のオプションとして、認証にPnPのみを使用している場合は、パッケージを変更する必要のない以下のヘルパーメソッドを使用できます。ただし、プロビジョニングやその他の拡張機能などの他の機能を使用している場合は、残念ながらそれをダウングレードする必要があります。これは、v3パッケージの変更を利用するために、PnP自体で内部的に使用されているものから変更されています。
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;
}