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" />
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With