0

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[] _)
Joshua K
  • 457
  • 3
  • 12
  • What is `System.IO.Directory.GetCurrentDirectory()` returning? Is it `null`? – Lajos Arpad Apr 29 '23 at 00:07
  • good question! i should've checked, lemme validate. – Joshua K Apr 29 '23 at 00:11
  • It is not null, but it is different from the path shown in the error. Perhaps I can update the current directory in the pipeline. – Joshua K Apr 29 '23 at 00:26
  • The error is complaining about it being `null` if I'm not mistaken. Maybe you have another call for `SetBasePath`? – Lajos Arpad Apr 29 '23 at 00:30
  • That's the entirety of the code, and I don't see it anywhere. However, on that same thought I see that the error is referencing FileConfigurationExtensions.SetBasePath but I'm not calling that anywhere. ahh... maybe I need to use SetBasePath in FileConfigurationExtensions. trying that. – Joshua K Apr 29 '23 at 00:36
  • didn't work with `.Build()` before the explicit call to `FileConfigurationExtensions.SetBasePath` so trying it with `.Build()` after. – Joshua K Apr 29 '23 at 00:48
  • 1
    It's just the `new ConfigurationBuilder().SetBasePath()` you have called. But it's still unclear to me. Is the error message claiming it's `null`? – Lajos Arpad Apr 29 '23 at 00:50
  • yes. unfortunately it does believe it is null. the error says `Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'basePath')` – Joshua K Apr 29 '23 at 00:55
  • What if you pass a "whatever" string to it, like `"whatever"`. Will it still complain about it being `null`? – Lajos Arpad Apr 29 '23 at 00:57
  • Yes. I get the same error. I noticed the tooltip had "AzureAd" as the parameter on the line that complains of the error, so I've tried with "AzureAd" on `GetDefaultInstance()` – Joshua K Apr 29 '23 at 01:01
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/253376/discussion-between-joshua-k-and-lajos-arpad). – Joshua K Apr 29 '23 at 01:08
  • I haven't found a solution for configuring TAF but I worked around it and am able to retrieve the information I need. I wouldn't mind seeing someone offer a solution though. – Joshua K May 01 '23 at 19:28

1 Answers1

1

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.

Rik
  • 26
  • 3
  • Wow. I haven't had a chance to try this yet, but my project was in fact using Produce single file enabled. I'm going to try this ASAP and mark as accepted answer afterwards. – Joshua K May 12 '23 at 21:01