private async Task InitializeAsync() { ConfidentialClientApplicationBuilder confClientBuilder = ConfidentialClientApplicationBuilder.Create(_options.ClientId).WithAuthority(_options.AuthorityHost.AbsoluteUri, _options.TenantId).WithHttpClientFactory(new HttpPipelineClientFactory(_options.Pipeline.HttpPipeline)); if (_options.Secret != null) { confClientBuilder.WithClientSecret(_options.Secret); } if (_options.CertificateProvider != null) { X509Certificate2 clientCertificate = await _options.CertificateProvider.GetCertificateAsync(true, default).ConfigureAwait(false); confClientBuilder.WithCertificate(clientCertificate); } _client = confClientBuilder.Build(); if (_options.AttachSharedCache) { StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder(Constants.DefaultMsalTokenCacheName, Constants.DefaultMsalTokenCacheDirectory, _options.ClientId) .WithMacKeyChain(Constants.DefaultMsalTokenCacheKeychainService, Constants.DefaultMsalTokenCacheKeychainAccount) .WithLinuxKeyring(Constants.DefaultMsalTokenCacheKeyringSchema, Constants.DefaultMsalTokenCacheKeyringCollection, Constants.DefaultMsalTokenCacheKeyringLabel, Constants.DefaultMsaltokenCacheKeyringAttribute1, Constants.DefaultMsaltokenCacheKeyringAttribute2) .Build(); MsalCacheHelper cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false); cacheHelper.RegisterCache(_client.UserTokenCache); } }
/// <inheritdoc /> public SharedTokenCacheProvider(IConfiguration config = null, ILogger logger = null) { _logger = logger; _config = config ?? new ConfigurationBuilder().AddEnvironmentVariables().Build(); const string serviceName = "Microsoft.Developer.IdentityService"; const string clientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46"; var storageCreationPropertiesBuilder = new StorageCreationPropertiesBuilder( Path.GetFileName(s_cacheFilePath), Path.GetDirectoryName(s_cacheFilePath), clientId) .WithMacKeyChain(serviceName: serviceName, accountName: "MSALCache") .WithLinuxKeyring( schemaName: "msal.cache", collection: "default", secretLabel: "MSALCache", attribute1: new KeyValuePair <string, string>("MsalClientID", serviceName), attribute2: new KeyValuePair <string, string>("MsalClientVersion", "1.0.0.0")); var authority = string.Format(CultureInfo.InvariantCulture, AadAuthority.AadCanonicalAuthorityTemplate, AadAuthority.DefaultTrustedHost, "common"); _app = PublicClientApplicationBuilder .Create(clientId) .WithAuthority(new Uri(authority)) .Build(); var cacheStore = new MsalCacheStorage(storageCreationPropertiesBuilder.Build()); _cacheHelper = new MsalCacheHelper(_app.UserTokenCache, cacheStore); _cacheHelper.RegisterCache(_app.UserTokenCache); }
public void TestInitialize() { var storageBuilder = new StorageCreationPropertiesBuilder( Path.GetFileName(CacheFilePath), Path.GetDirectoryName(CacheFilePath)); storageBuilder = storageBuilder.WithMacKeyChain( serviceName: "Microsoft.Developer.IdentityService.Test", accountName: "MSALCacheTest"); // unit tests run on Linux boxes without LibSecret storageBuilder.WithLinuxUnprotectedFile(); // 1. Use MSAL to create an instance of the Public Client Application var app = PublicClientApplicationBuilder.Create(ClientId) .Build(); // 3. Create the high level MsalCacheHelper based on properties and a logger _cacheHelper = MsalCacheHelper.CreateAsync( storageBuilder.Build(), new TraceSource("MSAL.CacheExtension.Test")) .GetAwaiter().GetResult(); // 4. Let the cache helper handle MSAL's cache _cacheHelper.RegisterCache(app.UserTokenCache); }
public static IPublicClientApplication CreatePublicClient( string authority = null, string clientId = null, string redirectUri = null, string tenantId = null) { PublicClientApplicationBuilder builder = PublicClientApplicationBuilder.Create(clientId); if (!string.IsNullOrEmpty(authority)) { builder = builder.WithAuthority(authority); } if (!string.IsNullOrEmpty(redirectUri)) { builder = builder.WithRedirectUri(redirectUri); } if (!string.IsNullOrEmpty(tenantId)) { builder = builder.WithTenantId(tenantId); } IPublicClientApplication client = builder.WithLogging( DebugLoggingMethod, LogLevel.Info, enablePiiLogging: false, enableDefaultPlatformLogging: true).Build(); MsalCacheHelper cacheHelper = InitializeCacheHelper(clientId); cacheHelper.RegisterCache(client.UserTokenCache); return(client); }
private async Task RegisterTokenCacheAsync(IPublicClientApplication app) { Context.Trace.WriteLine( "Configuring Microsoft Authentication token cache to instance shared with Microsoft developer tools..."); if (!PlatformUtils.IsWindows() && !PlatformUtils.IsPosix()) { string osType = PlatformUtils.GetPlatformInformation().OperatingSystemType; Context.Trace.WriteLine($"Token cache integration is not supported on {osType}."); return; } // We use the MSAL extension library to provide us consistent cache file access semantics (synchronisation, etc) // as other Microsoft developer tools such as the Azure PowerShell CLI. MsalCacheHelper helper = null; try { var storageProps = CreateTokenCacheProps(useLinuxFallback: false); helper = await MsalCacheHelper.CreateAsync(storageProps); // Test that cache access is working correctly helper.VerifyPersistence(); } catch (MsalCachePersistenceException ex) { Context.Streams.Error.WriteLine("warning: cannot persist Microsoft authentication token cache securely!"); Context.Trace.WriteLine("Cannot persist Microsoft Authentication data securely!"); Context.Trace.WriteException(ex); if (PlatformUtils.IsMacOS()) { // On macOS sometimes the Keychain returns the "errSecAuthFailed" error - we don't know why // but it appears to be something to do with not being able to access the keychain. // Locking and unlocking (or restarting) often fixes this. Context.Streams.Error.WriteLine( "warning: there is a problem accessing the login Keychain - either manually lock and unlock the " + "login Keychain, or restart the computer to remedy this"); } else if (PlatformUtils.IsLinux()) { // On Linux the SecretService/keyring might not be available so we must fall-back to a plaintext file. Context.Streams.Error.WriteLine("warning: using plain-text fallback token cache"); Context.Trace.WriteLine("Using fall-back plaintext token cache on Linux."); var storageProps = CreateTokenCacheProps(useLinuxFallback: true); helper = await MsalCacheHelper.CreateAsync(storageProps); } } if (helper is null) { Context.Streams.Error.WriteLine("error: failed to set up Microsoft Authentication token cache!"); Context.Trace.WriteLine("Failed to integrate with shared token cache!"); } else { helper.RegisterCache(app.UserTokenCache); Context.Trace.WriteLine("Microsoft developer tools token cache configured."); } }
internal override async Task RegisterCache(bool async, ITokenCache tokenCache, CancellationToken cancellationToken) { MsalCacheHelper cacheHelper = await GetCacheHelperAsync(async, cancellationToken).ConfigureAwait(false); cacheHelper.RegisterCache(tokenCache); await base.RegisterCache(async, tokenCache, cancellationToken).ConfigureAwait(false); }
private void ConfigureCache(MsalCacheHelper cacheHelper) { if (cacheHelper != null) { // https://aka.ms/msal-net-token-cache-serialization cacheHelper.RegisterCache(_client.UserTokenCache); } }
public void InitializeWithAadMultipleOrgs(string clientId, bool integratedAuth = false, string redirectUri = null, MsalCacheHelper cacheHelper = null) { _integratedAuthAvailable = integratedAuth; _client = PublicClientApplicationBuilder.Create(clientId) .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs) .WithRedirectUri(redirectUri) .Build(); cacheHelper?.RegisterCache(_client.UserTokenCache); }
public void InitializeWithAadSingleOrg(string clientId, string tenant, bool integratedAuth = false, string redirectUri = null, MsalCacheHelper cacheHelper = null) { _integratedAuthAvailable = integratedAuth; _client = PublicClientApplicationBuilder.Create(clientId) .WithAuthority(AzureCloudInstance.AzurePublic, tenant) .WithRedirectUri(redirectUri) .Build(); cacheHelper?.RegisterCache(_client.UserTokenCache); }
public void InitializeWithAadAndPersonalMsAccounts(string clientId, string redirectUri = null, MsalCacheHelper cacheHelper = null) { _integratedAuthAvailable = false; _client = PublicClientApplicationBuilder.Create(clientId) .WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount) .WithRedirectUri(redirectUri) .Build(); cacheHelper?.RegisterCache(_client.UserTokenCache); }
private async Task RegisterTokenCacheAsync(IPublicClientApplication app) { Context.Trace.WriteLine( "Configuring Microsoft Authentication token cache to instance shared with Microsoft developer tools..."); if (!PlatformUtils.IsWindows() && !PlatformUtils.IsPosix()) { string osType = PlatformUtils.GetPlatformInformation().OperatingSystemType; Context.Trace.WriteLine($"Token cache integration is not supported on {osType}."); return; } string clientId = app.AppConfig.ClientId; // We use the MSAL extension library to provide us consistent cache file access semantics (synchronisation, etc) // as other Microsoft developer tools such as the Azure PowerShell CLI. MsalCacheHelper helper = null; try { var storageProps = CreateTokenCacheProps(clientId, useLinuxFallback: false); helper = await MsalCacheHelper.CreateAsync(storageProps); // Test that cache access is working correctly helper.VerifyPersistence(); } catch (MsalCachePersistenceException ex) { Context.Streams.Error.WriteLine("warning: cannot persist Microsoft Authentication data securely!"); Context.Trace.WriteLine("Cannot persist Microsoft Authentication data securely!"); Context.Trace.WriteException(ex); // On Linux the SecretService/keyring might not be available so we must fall-back to a plaintext file. if (PlatformUtils.IsLinux()) { Context.Trace.WriteLine("Using fall-back plaintext token cache on Linux."); var storageProps = CreateTokenCacheProps(clientId, useLinuxFallback: true); helper = await MsalCacheHelper.CreateAsync(storageProps); } } if (helper is null) { Context.Streams.Error.WriteLine("error: failed to set up Microsoft Authentication token cache!"); Context.Trace.WriteLine("Failed to integrate with shared token cache!"); } else { helper.RegisterCache(app.UserTokenCache); Context.Trace.WriteLine("Microsoft developer tools token cache configured."); } }
private IPublicClientApplication BuildPublicClientApplication() { var application = PublicClientApplicationBuilder .Create(ClientId) .WithAuthority(Authority) //.WithDefaultRedirectUri() .WithRedirectUri("http://localhost") .Build(); _msalCacheHelper.RegisterCache(application.UserTokenCache); return(application); }
private async Task InitializeAsync() { if (_attachSharedCache) { StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder(Constants.DefaultMsalTokenCacheName, Constants.DefaultMsalTokenCacheDirectory, _clientId) .WithMacKeyChain(Constants.DefaultMsalTokenCacheKeychainService, Constants.DefaultMsalTokenCacheKeychainAccount) .WithLinuxKeyring(Constants.DefaultMsalTokenCacheKeyringSchema, Constants.DefaultMsalTokenCacheKeyringCollection, Constants.DefaultMsalTokenCacheKeyringLabel, Constants.DefaultMsaltokenCacheKeyringAttribute1, Constants.DefaultMsaltokenCacheKeyringAttribute2) .Build(); MsalCacheHelper cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false); cacheHelper.RegisterCache(_client.UserTokenCache); } }
internal static (string[], IPublicClientApplication, MsalCacheHelper) GetPublicClient( string resource, string tenant, Uri baseAuthority, bool validateAuthority, string clientId, string cacheFilename, string cacheDirectory, string serviceName, string accountName) { // tenant can be null resource = resource ?? throw new ArgumentNullException(nameof(resource)); Console.WriteLine($"Using resource: '{resource}', tenant:'{tenant}'"); var scopes = new string[] { resource + "/.default" }; Console.WriteLine($"Using scopes: '{string.Join(",", scopes)}'"); var authority = $"{baseAuthority.AbsoluteUri}{tenant}"; Console.WriteLine($"GetPublicClient for authority: '{authority}' ValidateAuthority: '{validateAuthority}'"); Uri authorityUri = new Uri(authority); var appBuilder = PublicClientApplicationBuilder.Create(clientId).WithAuthority(authorityUri, validateAuthority); var app = appBuilder.Build(); Console.WriteLine($"Built public client"); var storageCreationPropsBuilder = new StorageCreationPropertiesBuilder(cacheFilename, cacheDirectory); storageCreationPropsBuilder = storageCreationPropsBuilder.WithMacKeyChain(serviceName, accountName); var storageCreationProps = storageCreationPropsBuilder.Build(); // This hooks up our custom cache onto the one used by MSAL var cacheHelper = new MsalCacheHelper(storageCreationProps); cacheHelper.RegisterCache(app.UserTokenCache); Console.WriteLine($"Cache registered"); return(scopes, app, cacheHelper); }
internal SharedTokenCacheProvider(StorageCreationPropertiesBuilder builder, IConfiguration config = null, ILogger logger = null) { _logger = logger; _config = config ?? new ConfigurationBuilder().AddEnvironmentVariables().Build(); var authority = _config.GetValue <string>(Constants.AadAuthorityEnvName) ?? string.Format(CultureInfo.InvariantCulture, AadAuthority.AadCanonicalAuthorityTemplate, AadAuthority.DefaultTrustedHost, "common"); _app = PublicClientApplicationBuilder .Create(AzureCliClientId) .WithAuthority(new Uri(authority)) .Build(); var cacheStore = new MsalCacheStorage(builder.Build()); _cacheHelper = new MsalCacheHelper(_app.UserTokenCache, cacheStore); _cacheHelper.RegisterCache(_app.UserTokenCache); }
public void ImportExport() { var storageBuilder = new StorageCreationPropertiesBuilder( Path.GetFileName(CacheFilePath), Path.GetDirectoryName(CacheFilePath), ClientId); storageBuilder = storageBuilder.WithMacKeyChain( serviceName: "Microsoft.Developer.IdentityService.Test", accountName: "MSALCacheTest"); // unit tests run on Linux boxes without LibSecret storageBuilder.WithLinuxUnprotectedFile(); // 1. Use MSAL to create an instance of the Public Client Application var app = PublicClientApplicationBuilder.Create(ClientId) .Build(); // 3. Create the high level MsalCacheHelper based on properties and a logger _cacheHelper = MsalCacheHelper.CreateAsync( storageBuilder.Build(), new TraceSource("MSAL.CacheExtension.Test")) .GetAwaiter().GetResult(); // 4. Let the cache helper handle MSAL's cache _cacheHelper.RegisterCache(app.UserTokenCache); // Act string dataString = "Hello World"; byte[] dataBytes = Encoding.UTF8.GetBytes(dataString); var result = _cacheHelper.LoadUnencryptedTokenCache(); Assert.AreEqual(0, result.Length); _cacheHelper.SaveUnencryptedTokenCache(dataBytes); byte[] actualData = _cacheHelper.LoadUnencryptedTokenCache(); Assert.AreEqual(dataString, Encoding.UTF8.GetString(actualData)); }
/// <summary> /// Registers a token cache to synchronize with on disk storage. /// </summary> /// <param name="tokenCache"></param> public virtual void RegisterCache(ITokenCache tokenCache) { _helper.RegisterCache(tokenCache); }
public void MigrateFromAdalToMsal() { MsalCacheHelper cacheHelper = null; var builder = PublicClientApplicationBuilder.Create(PowerShellClientId); var clientApplication = builder.Build(); clientApplication.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) => { if (AdalToken != null) { try { args.TokenCache.DeserializeAdalV3(AdalToken); } catch (Exception) { //TODO: } finally { AdalToken = null; if (!HasRegistered) { HasRegistered = true; cacheHelper = MsalCacheHelperProvider.GetCacheHelper(); cacheHelper.RegisterCache(clientApplication.UserTokenCache); } } } }); clientApplication.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) => { if (args.HasStateChanged) { var bytes = args.TokenCache.SerializeAdalV3(); } }); var accounts = clientApplication.GetAccountsAsync().ConfigureAwait(false).GetAwaiter().GetResult(); foreach (var account in accounts) { try { var accountEnvironment = string.Format("https://{0}/", account.Environment); var environment = AzureEnvironment.PublicEnvironments.Values.Where(e => e.ActiveDirectoryAuthority == accountEnvironment).FirstOrDefault(); if (environment == null) { // We cannot map the previous environment to one of the public environments continue; } var scopes = new string[] { string.Format("{0}{1}", environment.ActiveDirectoryServiceEndpointResourceId, ".default") }; try { clientApplication.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false).GetAwaiter().GetResult(); } catch //For MSA account, real AAD tenant must be specified, otherwise MSAL library will request token against its home tenant { var tenantId = GetTenantId(account.Username); if (!string.IsNullOrEmpty(tenantId)) { clientApplication.AcquireTokenSilent(scopes, account).WithAuthority(environment.ActiveDirectoryAuthority, tenantId).ExecuteAsync().ConfigureAwait(false).GetAwaiter().GetResult(); } } //TODO: Set HomeAccountId for migration } catch { // Continue if we're unable to get the token for the current account continue; } } cacheHelper?.UnregisterCache(clientApplication.UserTokenCache); }