Search code examples
c#.net-coredependency-injectionmicrosoft.identity.web

How do I configure the basePath for TokenAcquirerFactory? Encountering an error that basePath cannot be null when trying to call GetDefaultInstance


I have a simple console app that works fine locally. I'm trying to put it in an Azure DevOps pipeline and I encounter an error executing it in the pipeline. It runs via an on-prem AzDO agent.

I'm somewhat new .net core and dependency injection. This is a .net core 7 app. I started with the source from https://github.com/Azure-Samples/active-directory-dotnetcore-daemon-v2/tree/master/1-Call-MSGraph. I added 3 statements between the comment lines below. I also updated the MSGraph query to return the information I seek vs number of users. I'd prefer to use environment variables vs the appsettings.json file, but it always gives an error that the basePath cannot be null, even if I put a string as the parameter for GetDefaultInstance. I'm not even sure I need the top two lines I inserted. There error is the same if I leave that out.

I'm not finding good examples or documentation for configuring TokenAcquirerFactory. It seems like maybe I do this in FileConfiguration or something instead. I also couldn't find any other questions dealing with TokenAcquirerFactory.

Any and all help is appreciated. Thanks!

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
using System;
using System.Threading.Tasks;

namespace daemon_console
{
    class CheckCertExpirationDate
    {
        static async Task Main(string[] _)
        {
            // added from here
            var builder = new ConfigurationBuilder()
                .SetBasePath(System.IO.Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables();
            var configuration = builder.Build();
                 // this outputs to true so I know the file exists
            Console.WriteLine(System.IO.File.Exists("appsettings.json")); 
            // added to here

            // error occurs on the line below
            TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();

            IServiceCollection services = tokenAcquirerFactory.Services;
            services.AddMicrosoftGraph();

            var serviceProvider = tokenAcquirerFactory.Build();

            try
            {
                GraphServiceClient graphServiceClient = serviceProvider.GetRequiredService<GraphServiceClient>();


                var cert = await graphServiceClient.DeviceManagement.ApplePushNotificationCertificate.Request().WithAppOnly().GetAsync();
                Console.WriteLine(cert.ExpirationDateTime);
                
                Console.WriteLine($"{cert.ExpirationDateTime}");

            }
            catch (ServiceException e)
            {
                Console.WriteLine("We could not retrieve the expiration date: " + $"{e}");
            }
        }
    }
}

This is the error I encounter:

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'basePath')
  at System.ThrowHelper.Throw(String paramName)
  at Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath(IConfigurationBuilder builder, String basePath)
  at Microsoft.Identity.Web.TokenAcquirerFactory.ReadConfiguration()
  at Microsoft.Identity.Web.TokenAcquirerFactory.GetDefaultInstance(String configSection)
  at daemon_console.CheckCertExpirationDate.Main(String[] _) in D:\a\1\s\CheckCertExpirationDate\CheckCertExpirationDate\CheckCertExpirationDate.cs:line 34
  at daemon_console.CheckCertExpirationDate.<Main>(String[] _)

Solution

  • I too had the same problem when using the TokenAcquirerFactory object. Everything ran locally fine, but the minute I published the app, I got the 'basePath is null error'. I am creating a Worker Service application.

    The solution I found in the end was attributed to the publish profile in Visual Studio 2022. In the profile settings and under File Publish options I was ticking the 'Produce single file' option. This caused the error.

    Leaving that option unchecked and re-publishing, solved the error and the application to work as expected.