Microsoft-authentication-library-for-dotnet: [Bug] [Xamarin.Mac] GetAccountsAsync is not returning any elements on Xamarin.Mac after an authentication

Created on 29 Apr 2020  路  13Comments  路  Source: AzureAD/microsoft-authentication-library-for-dotnet

After authenticating on Xamarin.Mac, we later call GetAccountsAsync() to try and refresh a token, but are not getting any results back. I think this is because the keychain caching is not working in Xamarin.Mac.

We're using version 4.12.0, and this is currently working on our other three Xamarin platforms: iOS/ Android and UWP.

I've tried to follow a similar approach to our iOS app, where we have set
CFBundleURLSchemes and keychain-access-groups in the Info.plist and Entitlements.plist files, however the Mac app appears not to be storing the credentials in the same way, so this hasn't helped so far.

Our iOS app does also use the line WithIosKeychainSecurityGroup in the PublicClientApplicationBuilder, however I'm not sure if we need an analogous approach for Mac here.

Is this a known issue specifically with Xamarin.Mac not caching the credentials after logging in, or is there a mistake/step that we're missing to get this working on Xamarin.Mac?

Feature Request external keychain access MacOS

Most helpful comment

I have a fix for the cache extension and should be able to release a new version on Monday or so. https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/issues/61

All 13 comments

@bgavrilMS can you assist with this?

We did not implement token cache persistence in xamarin.mac, just the browser popup. I can think of 2 workarounds:

  1. We do have a token cache extension that persist in keychain, written for .net core and .net standard, so it should work for xamarin.mac. Extension is here https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet

  2. Implement your own persistence:

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/token-cache-serialization

I have a fix for the cache extension and should be able to release a new version on Monday or so. https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/issues/61

Thanks @bgavrilMS
fyi: @kevcrooks

That's great, thank you @bgavrilMS we'll update to the next release once ready

@bgavrilMS we're having issues adding and using the extension you mentioned on Mac. We've set it up according to the example given here in the manual test app: https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/tree/master/tests/ManualTestApp

but we're getting an exception when calling MsalCacheHelper.CreateAsync(storageProperties)

Is there some more information on how to configure the app or what parameters to use (e.g. KeyChainServiceName and KeyChainAccountName) as I'm thinking some of the parameters must need to be linked to a configuration either in our plist files or on the Apple side - but we don't have too much experience setting this up - only following existing examples - so if you know of a demo Mac app that has this working for us to compare with, that would be useful?

What is the exception?

I'm getting Object reference not set to instance of an object exception from Msal.TraceSourceLogger.LogError inside Msal.MsalCacheHelper.CreateAsync

Ack, I logged bug https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/issues/84 to track this - plus a simple workaround.

I'll get that fixed and released once we release MSAL 4.13, probably early next week. Until then you should use the workaround (in fact, it's a good idea to use tracing for logging anyway).

I'll close this issue and continue and conversation on AzureAD/microsoft-authentication-extensions-for-dotnet#84

@bgavrilMS:
@kevcrooks got this working with your help: thanks very much!

I.e. we are using microsoft-authentication-extensions-for-dotnet cacheing to allow refreshing tokens on Mac.

I would suggest making this a default experience from msal.net, as users would expect refreshing tokens on mac to work out of the box.

MsalCacheHelper asked for some strings but they were all either strings already used in MSAL or strings that could be set to any reasonable default values. So just doing this registration automatically on mac would seem the right approach.

let registerTokenCacheForMac(pca: IPublicClientApplication) =
    async{
        let storageProperties =
            StorageCreationPropertiesBuilder("msal_cache.dat", MsalCacheHelper.UserRootDirectory, appId)
                .WithMacKeyChain("msal_service", "msal_account").Build()
        let! cacheHelper =
            MsalCacheHelper.CreateAsync(storageProperties, Diagnostics.TraceSource("MathSpireTokenCache"))
            |> Async.AwaitTask
        cacheHelper.VerifyPersistence()
        cacheHelper.RegisterCache(pca.UserTokenCache)
    }

@charlesroddie - thank your following up, this is great news!

Please use different values for the cache file name and keychain account and service to avoid clashing with other apps that might use the same. I've updated the sample on GitHub. AFAIK, VS for mac and PowerShell core also use "msal_cache.dat" in that location and similar keychain properties.

The file is used as a simple signaling mechanism, there's no data in it, so it's not a big deal. KeyChain however will ask the user smth like "You are trying to access a KeyChain record created by VS for Mac. Are you sure?" when they'll use you app.

@jmprieur @henrik-me @kalyankrishna1 - for the need to provide a default cache persistence layer on public client apps...

Was this page helpful?
0 / 5 - 0 ratings