AzureAD / microsoft-authentication-extensions-for-dotnet

Secure cross-platform token cache for MSAL public client apps
MIT License
83 stars 32 forks source link

Improved error message to steer users to .WithLinuxUnprotectedFile() or host workaround #154

Open NeilMacMullen opened 3 years ago

NeilMacMullen commented 3 years ago

When executing the following code on an application targeting .net 5 and the linux-x64 runtime and running on WSL (Ubuntu)

var storageProperties = new StorageCreationPropertiesBuilder(
        ".msalcache.bin", _directory)
        .WithCacheChangedEvent(_config.ClientId)
       .Build();
_cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties);

I receive this exception:

System.ArgumentNullException: Value cannot be null. (Parameter 'attributeKey1')
   at Microsoft.Identity.Client.Extensions.Msal.LinuxKeyringAccessor..ctor(String cacheFilePath, String keyringCollection, String keyringSchemaName, String keyringSecretLabel, String attributeKey1, String attributeValue1, String attributeKey2, String attributeValue2, TraceSourceLogger logger)
   at Microsoft.Identity.Client.Extensions.Msal.Storage.Create(StorageCreationProperties creationProperties, TraceSource logger)
   at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper..ctor(StorageCreationProperties storageCreationProperties, TraceSource logger, HashSet`1 knownAccountIds, FileSystemWatcher cacheWatcher)
   at Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.CreateAsync(StorageCreationProperties storageCreationProperties, TraceSource logger)

A workaround is to add .WithLinuxUnprotectedFile()

var storageProperties = new StorageCreationPropertiesBuilder(
        ".msalcache.bin", _directory)
        .WithLinuxUnprotectedFile() // bypass secure storage
        .WithCacheChangedEvent(_config.ClientId)
       .Build();

It's also possible there is some piece of Linux magic that would allow the code to work with secure-storage (install lib-secret?)

I would suggest that if possible this scenario should be detected and a more useful exception/message generated. E.g. "No secure storage available: create Storage using "WithLinuxUnprotectedFile" or install lib-secret using "sudu apt-get install....".

bgavrilMS commented 2 years ago

@mjcheetham - what does GCM on WSL ?

mjcheetham commented 2 years ago

If you install GCM on Windows, and then 'link' to it from the WSL Git via config, we use the Windows APIs/cache storage.

If you install GCM natively in WSL, we treat it identically to a normal Linux install. We will try and use WithLinuxKeyring(..) - we then catch MsalCachePersistenceExceptions from .VerifyPersistence() and retry with WithLinuxUnprotectedFile() (and print a warning to the user).

https://github.com/GitCredentialManager/git-credential-manager/blob/bdc20d91d325d66647f2837ffb4e2b2fe98d7e70/src/shared/Core/Authentication/MicrosoftAuthentication.cs#L371-L407