@@ -270,7 +270,7 @@ public async Task<IMicrosoftAuthenticationResult> GetTokenForUserAsync(
270270
271271 public async Task < IMicrosoftAuthenticationResult > GetTokenForServicePrincipalAsync ( ServicePrincipalIdentity sp , string [ ] scopes )
272272 {
273- IConfidentialClientApplication app = CreateConfidentialClientApplication ( sp ) ;
273+ IConfidentialClientApplication app = await CreateConfidentialClientApplicationAsync ( sp ) ;
274274
275275 try
276276 {
@@ -528,7 +528,7 @@ private async Task<IPublicClientApplication> CreatePublicClientApplicationAsync(
528528 return app ;
529529 }
530530
531- private IConfidentialClientApplication CreateConfidentialClientApplication ( ServicePrincipalIdentity sp )
531+ private async Task < IConfidentialClientApplication > CreateConfidentialClientApplicationAsync ( ServicePrincipalIdentity sp )
532532 {
533533 var httpFactoryAdaptor = new MsalHttpClientFactoryAdaptor ( Context . HttpClientFactory ) ;
534534
@@ -554,6 +554,8 @@ private IConfidentialClientApplication CreateConfidentialClientApplication(Servi
554554
555555 IConfidentialClientApplication app = appBuilder . Build ( ) ;
556556
557+ await RegisterTokenCacheAsync ( app . AppTokenCache , CreateAppTokenCacheProps , Context . Trace2 ) ;
558+
557559 return app ;
558560 }
559561
@@ -713,6 +715,38 @@ internal static ManagedIdentityId GetManagedIdentity(string str)
713715 throw new ArgumentException ( "Invalid managed identity value." , nameof ( str ) ) ;
714716 }
715717
718+ /// <summary>
719+ /// Create the properties for the application token cache. This is used by confidential client applications only
720+ /// and is not shared between applications other than GCM.
721+ /// </summary>
722+ internal StorageCreationProperties CreateAppTokenCacheProps ( bool useLinuxFallback )
723+ {
724+ const string cacheFileName = "app.cache" ;
725+
726+ // The confidential client MSAL cache is located at "%UserProfile%\.gcm\msal\app.cache" on Windows
727+ // and at "~/.gcm/msal/app.cache" on UNIX.
728+ string cacheDirectory = Path . Combine ( Context . FileSystem . UserDataDirectoryPath , "msal" ) ;
729+
730+ // The keychain is used on macOS with the following service & account names
731+ var builder = new StorageCreationPropertiesBuilder ( cacheFileName , cacheDirectory )
732+ . WithMacKeyChain ( "GitCredentialManager.MSAL" , "AppCache" ) ;
733+
734+ if ( useLinuxFallback )
735+ {
736+ builder . WithLinuxUnprotectedFile ( ) ;
737+ }
738+ else
739+ {
740+ // The SecretService/keyring is used on Linux with the following collection name and attributes
741+ builder . WithLinuxKeyring ( cacheFileName ,
742+ "default" , "AppCache" ,
743+ new KeyValuePair < string , string > ( "MsalClientID" , "GitCredentialManager.MSAL" ) ,
744+ new KeyValuePair < string , string > ( "GitCredentialManager.MSAL" , "1.0.0.0" ) ) ;
745+ }
746+
747+ return builder . Build ( ) ;
748+ }
749+
716750 private static EmbeddedWebViewOptions GetEmbeddedWebViewOptions ( )
717751 {
718752 return new EmbeddedWebViewOptions
0 commit comments