1

I am connecting to Graph API with Microsoft Identity Web (MSAL) library. [https://github.com/AzureAD/microsoft-identity-web][1]

For this I am using client credentials flow with certificate based authentication.

My configurations are below

Service Registration

  services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
           .EnableTokenAcquisitionToCallDownstreamApi()
           .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
           .AddInMemoryTokenCaches();

appSettings.json

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mydomain.onmicrosoft.com",
    "TenantId": "xxxxxxx",
    "ClientId": "yyyyyyyy",   
    "ClientCertificates": [
     {
       "SourceType": "Path",
       "CertificateDiskPath": "c:\\cert\\my-cert.pfx",
       "CertificatePassword": "password"
     }
 ] }

For this I am getting the below error

IDW10104: Both client secret and client certificate cannot be null or whitespace, and only ONE must be included in the configuration of the web app when calling a web API. For instance, in the appsettings.json file.

However I am able to accrue token and connect with Graph API using Microsoft.Identity.Client (Using client credentials-flow with certificate based auth)

    private GraphServiceClient GetGraphServiceClient()
    {
        var token = GetToken();
        GraphServiceClient graphServiceClient =
            new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
            {
                // Add the access token in the Authorization header of the API request.
                requestMessage.Headers.Authorization =
                        new AuthenticationHeaderValue("Bearer", token);
            })
            );
        return graphServiceClient;
    }

    private string GetToken()
    {
        var x509Certificate2 = 
            new X509Certificate2(System.IO.File.ReadAllBytes("MyCert.pfx"), "password");

        IConfidentialClientApplication app = 
            Microsoft.Identity.Client.ConfidentialClientApplicationBuilder.Create("my-client-id")
                .WithTenantId("my-tenent-id")
                .WithCertificate(x509Certificate2)
                .Build();

        // With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the
        // application permissions need to be set statically (in the portal or by PowerShell), and then granted by
        // a tenant administrator
        string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
         
        AuthenticationResult result =
                    app.AcquireTokenForClient(scopes)
                        .ExecuteAsync().Result;
        return result.AccessToken;
    }

Am I missing any configuration here?

Anand
  • 717
  • 6
  • 20

1 Answers1

1

On workaround

Try with the adding the certificate in the Azure App registration

1) Go to the Azure portal. In the left-hand navigation pane, select the Azure Active Directory service, and then select App registrations.

enter image description here

2) In the resultant screen, select the Select the your application.

3) In the Certificates & secrets tab, go to Certificates section:

4) Select Upload certificate and, in select the browse button on the right to select the your existing certificate.

enter image description here

5) Select Add.

For more details refer this document: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/blob/master/4-WebApp-your-API/4-1-MyOrg/README-use-certificate.md

ShrutiJoshi-MT
  • 1,622
  • 1
  • 4
  • 9
  • I hope not really in my case. Because ClientCertificates value from appSettings.json is not binding when I am using => services.AddMicrosoftIdentityWebApiAuthentication(Configuration) – Anand Dec 24 '21 at 14:33