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);
        }
Esempio n. 4
0
        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.");
            }
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
 private void ConfigureCache(MsalCacheHelper cacheHelper)
 {
     if (cacheHelper != null)
     {
         // https://aka.ms/msal-net-token-cache-serialization
         cacheHelper.RegisterCache(_client.UserTokenCache);
     }
 }
Esempio n. 8
0
 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);
 }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
            }
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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));
        }
Esempio n. 17
0
 /// <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);
 }
Esempio n. 18
0
        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);
        }