コード例 #1
0
        private static MsalCacheHelper CreateCacheHelperAsync(string clientId)
        {
            StorageCreationProperties storageProperties;

            try
            {
                storageProperties =
                    new StorageCreationPropertiesBuilder(
                        "cache.plaintext",
                        System.AppContext.BaseDirectory,
                        clientId)
                    .WithLinuxUnprotectedFile()
                    .Build();

                var cacheHelper = MsalCacheHelper.CreateAsync(storageProperties).Result;
                return(cacheHelper);
            }
            catch (MsalCachePersistenceException e)
            {
                storageProperties =
                    new StorageCreationPropertiesBuilder(
                        "cache.plaintext",
                        System.AppContext.BaseDirectory,
                        clientId)
                    .WithLinuxUnprotectedFile()
                    .Build();

                var cacheHelper = MsalCacheHelper.CreateAsync(storageProperties).Result;

                cacheHelper.VerifyPersistence();

                return(cacheHelper);
            }
        }
コード例 #2
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;
            }

            // 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.");
            }
        }
コード例 #3
0
        public async Task <AcquireTokenResult> AcquireTokenAsync()
        {
            var app = PublicClientApplicationBuilder.Create(_clientId).WithTenantId(_tenantId).WithDefaultRedirectUri().Build();

            var storageCreationProperties = new StorageCreationPropertiesBuilder("tokenCache.dat", ".", _clientId).Build();

            (await MsalCacheHelper.CreateAsync(storageCreationProperties)).RegisterCache(app.UserTokenCache);
            var account = await GetAccountAsync(app);

            AuthenticationResult authenticationResult;

            try
            {
                authenticationResult = await app.AcquireTokenSilent(_scopes, account).ExecuteAsync();
            }
            catch (MsalUiRequiredException)
            {
                authenticationResult = await app.AcquireTokenWithDeviceCode(_scopes, deviceCodeResult =>
                {
                    Console.WriteLine(deviceCodeResult.Message);
                    return(deviceCodeResult.VerificationUrl == null ? Task.CompletedTask : OpenBrowserAsync(deviceCodeResult.VerificationUrl));
                }).ExecuteAsync();
            }

            return(new AcquireTokenResult(authenticationResult.AccessToken, ExtractObjectId(authenticationResult.IdToken)));
        }
コード例 #4
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            // Initialize services that you need before app activation
            await InitializeAsync();

            // https://aka.ms/msal-net-token-cache-serialization
            // this generates a file-system safe directory name to stick the cache in - or use something like Resources.AppDisplayName
            // should also consider this root dir for other configuration data
            var safeAppDirectoryName      = System.IO.Path.GetInvalidFileNameChars().Aggregate(typeof(App).Assembly.GetName().Name, (current, c) => current.Replace(c, '-'));
            var rootCacheDirectory        = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), safeAppDirectoryName, _config.IdentityCacheDirectoryName);
            var storageCreationProperties = new StorageCreationPropertiesBuilder(_config.IdentityCacheFileName, rootCacheDirectory, _config.IdentityClientId).Build();
            var cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties).ConfigureAwait(false);

            _identityService.InitializeWithAadAndPersonalMsAccounts(_config.IdentityClientId, "http://localhost", cacheHelper);
            var silentLoginSuccess = await _identityService.AcquireTokenSilentAsync();

            if (!silentLoginSuccess || !_identityService.IsAuthorized())
            {
                _logInWindow = _serviceProvider.GetService(typeof(ILogInWindow)) as ILogInWindow;
                _logInWindow.ShowWindow();
                await StartupAsync();

                return;
            }

            _shellWindow = _serviceProvider.GetService(typeof(IShellWindow)) as IShellWindow;
            _navigationService.Initialize(_shellWindow.GetNavigationFrame());
            _shellWindow.ShowWindow();
            _navigationService.NavigateTo(typeof(MainViewModel).FullName);

            // Tasks after activation
            await StartupAsync();
        }
        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);
        }
コード例 #6
0
        private async Task RegisterVisualStudioTokenCacheAsync(IPublicClientApplication app)
        {
            Context.Trace.WriteLine("Configuring Visual Studio token cache...");

            // We currently only support Visual Studio on Windows
            if (PlatformUtils.IsWindows())
            {
                // The Visual Studio MSAL cache is located at "%LocalAppData%\.IdentityService\msal.cache" on Windows.
                // We use the MSAL extension library to provide us consistent cache file access semantics (synchronisation, etc)
                // as Visual Studio itself follows, as well as other Microsoft developer tools such as the Azure PowerShell CLI.
                const string cacheFileName  = "msal.cache";
                string       appData        = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                string       cacheDirectory = Path.Combine(appData, ".IdentityService");

                var storageProps = new StorageCreationPropertiesBuilder(cacheFileName, cacheDirectory, app.AppConfig.ClientId).Build();

                var helper = await MsalCacheHelper.CreateAsync(storageProps);

                helper.RegisterCache(app.UserTokenCache);

                Context.Trace.WriteLine("Visual Studio token cache configured.");
            }
            else
            {
                string osType = PlatformUtils.GetPlatformInformation().OperatingSystemType;
                Context.Trace.WriteLine($"Visual Studio token cache integration is not supported on {osType}.");
            }
        }
コード例 #7
0
        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);
            }
        }
コード例 #8
0
        private static async ValueTask <MsalCacheHelper> CreateCacheHelper(StorageCreationProperties storageProperties, bool async)
        {
            return(async
                ? await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false)
#pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead.
                : MsalCacheHelper.CreateAsync(storageProperties).GetAwaiter().GetResult());

#pragma warning restore AZC0102 // Do not use GetAwaiter().GetResult(). Use the TaskExtensions.EnsureCompleted() extension method instead.
        }
コード例 #9
0
        public MicrosoftAuthentication(TeamsPresencePublisherOptions options)
        {
            var storageProperties =
                new StorageCreationPropertiesBuilder("TeamsPresencePublisher.msalcache.bin", options.CacheFolder, ClientId)
                .Build();

            _msalCacheHelper = MsalCacheHelper.CreateAsync(storageProperties).GetAwaiter().GetResult();

            _publicClientApplication = BuildPublicClientApplication();
            AuthProvider             = new InteractiveAuthenticationProvider(_publicClientApplication, s_scopes);
        }
コード例 #10
0
        /// <summary>
        /// Calls MSAL to get authentication token with AAD.
        /// </summary>
        /// <returns></returns>
        /// <remarks>https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively</remarks>
        public async Task <VssCredentials> CreateVssCredentialsWithAadAsync()
        {
            // 1. Configuration
            var app = PublicClientApplicationBuilder
                      .Create(VsoAadConstants.Client)
                      .WithTenantId(VsoAadConstants.MicrosoftTenantId)
                      .WithRedirectUri(VsoAadConstants.RedirectUri)
                      .Build();

            // 2. Token cache
            // https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=desktop
            // https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/wiki/Cross-platform-Token-Cache
            var storageProperties = new StorageCreationPropertiesBuilder(m_tokenCacheFileName, m_tokenCacheDirectory).Build();
            var cacheHelper       = await MsalCacheHelper.CreateAsync(storageProperties);

            cacheHelper.RegisterCache(app.UserTokenCache);

            // 3. Try silent authentication
            var accounts = await app.GetAccountsAsync();

            var scopes = new string[] { VsoAadConstants.Scope };
            AuthenticationResult result = null;

            try
            {
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                         .ExecuteAsync();

                m_logger("[VssCredentialsFactory] Successfully acquired authentication token through silent AAD authentication.");
            }
            catch (MsalUiRequiredException)
            {
                // 4. Interactive Authentication
                m_logger("[VssCredentialsFactory] Unable to acquire authentication token through silent AAD authentication.");
                // On Windows, we can try Integrated Windows Authentication which will fallback to interactive auth if that fails
                result = OperatingSystemHelper.IsWindowsOS
                    ? await CreateVssCredentialsWithAadForWindowsAsync(app, scopes)
                    : await CreateVssCredentialsWithAadInteractiveAsync(app, scopes);
            }
            catch (Exception ex)
            {
                m_logger($"[VssCredentialsFactory] Unable to acquire credentials with AAD with the following exception: '{ex}'");
            }

            if (result == null)
            {
                // Something went wrong during AAD auth, return null
                m_logger($"[VssCredentialsFactory] Unable to acquire AAD token.");
                return(new VssAadCredential());
            }

            return(new VssAadCredential(new VssAadToken(VsoAadConstants.TokenType, result.AccessToken)));
        }
コード例 #11
0
        /// <summary>
        /// Helper function to initialize the token cache for non-UWP apps. MSAL handles this automatically on UWP.
        /// </summary>
        /// <param name="provider">The instance of <see cref="MsalProvider"/> to init the cache for.</param>
        /// <param name="storageProperties">Properties for configuring the storage cache.</param>
        /// <param name="logger">Passing null uses the default TraceSource logger.</param>
        /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
        public static async Task InitTokenCacheAsync(
            this MsalProvider provider,
            StorageCreationProperties storageProperties,
            TraceSource logger = null)
        {
#if !WINDOWS_UWP
            // Token cache persistence (not required on UWP as MSAL does it for you)
            var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties, logger);

            cacheHelper.RegisterCache(provider.Client.UserTokenCache);
#endif
        }
コード例 #12
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.");
            }
        }
コード例 #13
0
        private static async Task <MsalCacheHelper> CreateCacheHelperAsync()
        {
            StorageCreationProperties storageProperties;

            try
            {
                storageProperties = new StorageCreationPropertiesBuilder(
                    Config.CacheFileName,
                    Config.CacheDir,
                    Config.ClientId)
                                    .WithLinuxKeyring(
                    Config.LinuxKeyRingSchema,
                    Config.LinuxKeyRingCollection,
                    Config.LinuxKeyRingLabel,
                    Config.LinuxKeyRingAttr1,
                    Config.LinuxKeyRingAttr2)
                                    .WithMacKeyChain(
                    Config.KeyChainServiceName,
                    Config.KeyChainAccountName)
                                    .Build();

                var cacheHelper = await MsalCacheHelper.CreateAsync(
                    storageProperties).ConfigureAwait(false);

                cacheHelper.VerifyPersistence();
                return(cacheHelper);
            }
            catch (Exception e)
            {
                Console.WriteLine($"WARNING! Libsecret is not usable. " +
                                  $"Secrets will be stored in plaintext at {Path.Combine(Config.CacheDir, Config.CacheFileName)} !");
                Console.WriteLine($"Libsecret exception: " + e);

                storageProperties =
                    new StorageCreationPropertiesBuilder(
                        Config.CacheFileName,
                        Config.CacheDir,
                        Config.ClientId)
                    .WithLinuxUnprotectedFile()
                    .WithMacKeyChain(
                        Config.KeyChainServiceName,
                        Config.KeyChainAccountName)
                    .Build();

                var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

                cacheHelper.VerifyPersistence();

                return(cacheHelper);
            }
        }
コード例 #14
0
        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);
            }
        }
コード例 #15
0
        /// <summary>
        /// Gets an aptly configured instance of the <see cref="MsalCacheStorage" /> class.
        /// </summary>
        /// <returns>An aptly configured instance of the <see cref="MsalCacheStorage" /> class.</returns>
        private MsalCacheHelper GetMsalCacheStorage()
        {
            StorageCreationPropertiesBuilder builder = new StorageCreationPropertiesBuilder(Path.GetFileName(CacheFilePath), Path.GetDirectoryName(CacheFilePath), ClientId);

            builder = builder.WithMacKeyChain(serviceName: "Microsoft.Developer.IdentityService", accountName: "MSALCache");
            builder = builder.WithLinuxKeyring(
                schemaName: "msal.cache",
                collection: "default",
                secretLabel: "MSALCache",
                attribute1: new KeyValuePair <string, string>("MsalClientID", "Microsoft.Developer.IdentityService"),
                attribute2: new KeyValuePair <string, string>("MsalClientVersion", "1.0.0.0"));

            return(MsalCacheHelper.CreateAsync(builder.Build(), new TraceSource("Partner Center PowerShell")).ConfigureAwait(false).GetAwaiter().GetResult());
        }
コード例 #16
0
        private static async Task <MsalCacheHelper> CreateCacheHelperAsync()
        {
            StorageCreationProperties storageProperties;

            try
            {
                storageProperties = new StorageCreationPropertiesBuilder(
                    Config.CacheFileName,
                    Config.CacheDir)
                                    .WithLinuxKeyring(
                    Config.LinuxKeyRingSchema,
                    Config.LinuxKeyRingCollection,
                    Config.LinuxKeyRingLabel,
                    Config.LinuxKeyRingAttr1,
                    Config.LinuxKeyRingAttr2)
                                    .WithMacKeyChain(
                    Config.KeyChainServiceName,
                    Config.KeyChainAccountName)
                                    .WithCacheChangedEvent( // do NOT use unless really necessary, high perf penalty!
                    Config.ClientId,
                    Config.Authority)
                                    .Build();

                var cacheHelper = await MsalCacheHelper.CreateAsync(
                    storageProperties).ConfigureAwait(false);

                cacheHelper.VerifyPersistence();
                return(cacheHelper);
            }
            catch (MsalCachePersistenceException e)
            {
                Console.WriteLine($"WARNING! Unable to encrypt tokens at rest." +
                                  $" Saving tokens in plaintext at {Path.Combine(Config.CacheDir, Config.CacheFileName)} ! Please protect this directory or delete the file after use");
                Console.WriteLine($"Encryption exception: " + e);

                storageProperties =
                    new StorageCreationPropertiesBuilder(
                        Config.CacheFileName + ".plaintext", // do not use the same file name so as not to overwrite the encypted version
                        Config.CacheDir)
                    .WithUnprotectedFile()
                    .Build();

                var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

                cacheHelper.VerifyPersistence();

                return(cacheHelper);
            }
        }
コード例 #17
0
        private async Task InitializeCacheAsync()
        {
            // Building StorageCreationProperties
            var storageProperties =
                new StorageCreationPropertiesBuilder(
                    CacheFileName,
                    CacheDir,
                    ClientId)
                .Build();

            // This hooks up the cross-platform cache into MSAL
            var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties);

            cacheHelper.RegisterCache(app.UserTokenCache);
        }
コード例 #18
0
        private async Task <MsalCacheHelper> GetMsalCacheHelperAsync()
        {
            // There are options to set up the cache correctly using StorageCreationProperties on other OS's but that will need to be tested
            // for now only support windows
            if (helper == null && this.cacheEnabled && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                var fileName  = Path.GetFileName(cacheLocation);
                var directory = Path.GetDirectoryName(cacheLocation);

                var builder = new StorageCreationPropertiesBuilder(fileName, directory, this.clientId);
                StorageCreationProperties creationProps = builder.Build();
                helper = await MsalCacheHelper.CreateAsync(creationProps);
            }

            return(helper);
        }
コード例 #19
0
        private static MsalCacheHelper InitializeCacheHelper(string clientId)
        {
            StorageCreationPropertiesBuilder builder = new StorageCreationPropertiesBuilder(Path.GetFileName(CacheFilePath), Path.GetDirectoryName(CacheFilePath), clientId);

            builder = builder.WithMacKeyChain(serviceName: "Microsoft.Developer.IdentityService", accountName: "MSALCache");
            builder = builder.WithLinuxKeyring(
                schemaName: "msal.cache",
                collection: "default",
                secretLabel: "MSALCache",
                attribute1: new KeyValuePair <string, string>("MsalClientID", "Microsoft.Developer.IdentityService"),
                attribute2: new KeyValuePair <string, string>("MsalClientVersion", "1.0.0.0"));

            StorageCreationProperties storageCreationProperties = builder.Build();

            return(MsalCacheHelper.CreateAsync(storageCreationProperties).ConfigureAwait(false).GetAwaiter().GetResult());
        }
コード例 #20
0
ファイル: Program.cs プロジェクト: tino-teuber/BCTech
        public async Task RunAsync()
        {
            Console.WriteLine("START");

            var ClientId = "<Client Id>";
            var TenantId = "<Tenant Id>";

            string[] Scopes = new[] { "https://api.businesscentral.dynamics.com/Financials.ReadWrite.All" };

            var app = PublicClientApplicationBuilder.Create(ClientId)
                      .WithDefaultRedirectUri()
                      .WithTenantId(TenantId)
                      .Build();

            //    OPTIONAL: Create cache helper to persist token cache

            var CacheFileName     = "msal_cache.dat";
            var CacheDir          = @"MSAL_CACHE";
            var storageProperties = new StorageCreationPropertiesBuilder(CacheFileName, CacheDir).Build();

            var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties);

            cacheHelper.RegisterCache(app.UserTokenCache);

            //    Acquire token interactively

            var result = await app.AcquireTokenInteractive(Scopes).ExecuteAsync();

            Console.WriteLine($"ACCESS TOKEN (INTERACTIVE): [{result.ExpiresOn}] {result.AccessToken}");
            Console.WriteLine();

            await Task.Delay(TimeSpan.FromSeconds(5));

            //    Acquire token silently

            var accounts = await app.GetAccountsAsync();

            var silentResult = await app.AcquireTokenSilent(Scopes, accounts.FirstOrDefault()).WithForceRefresh(true).ExecuteAsync();

            Console.WriteLine($"ACCESS TOKEN (SILENT): [{silentResult.ExpiresOn}] {silentResult.AccessToken}");
            Console.WriteLine();

            Console.WriteLine("FINISH");
        }
コード例 #21
0
        internal static async Task <(string[], IPublicClientApplication, MsalCacheHelper)> GetPublicClientAsync(
            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, clientId);

            storageCreationPropsBuilder = storageCreationPropsBuilder.WithMacKeyChain(serviceName, accountName);
            var storageCreationProps = storageCreationPropsBuilder.Build();

            // This hooks up our custom cache onto the one used by MSAL
            var cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProps).ConfigureAwait(false);

            cacheHelper.RegisterCache(app.UserTokenCache);

            Console.WriteLine($"Cache registered");

            return(scopes, app, cacheHelper);
        }
        private static async Task <MsalCacheHelper> CreateCacheHelperAsync()
        {
            StorageCreationProperties storageProperties;
            MsalCacheHelper           cacheHelper;

            try
            {
                storageProperties = ConfigureSecureStorage(usePlaintextFileOnLinux: false);
                cacheHelper       = await MsalCacheHelper.CreateAsync(
                    storageProperties,
                    new TraceSource(TraceSourceName))
                                    .ConfigureAwait(false);

                // the underlying persistence mechanism might not be usable
                // this typically happens on Linux over SSH
                cacheHelper.VerifyPersistence();

                return(cacheHelper);
            }
            catch (MsalCachePersistenceException ex)
            {
                Console.WriteLine("Cannot persist data securely. ");
                Console.WriteLine("Details: " + ex);


                if (SharedUtilities.IsLinuxPlatform())
                {
                    storageProperties = ConfigureSecureStorage(usePlaintextFileOnLinux: true);

                    Console.WriteLine($"Falling back on using a plaintext " +
                                      $"file located at {storageProperties.CacheFilePath} Users are responsible for securing this file!");

                    cacheHelper = await MsalCacheHelper.CreateAsync(
                        storageProperties,
                        new TraceSource(TraceSourceName))
                                  .ConfigureAwait(false);

                    return(cacheHelper);
                }
                throw;
            }
        }
        /// <summary>
        /// ctor for AuthenticationTokenFactory
        /// </summary>
        /// <param name="applicationClientId">ClientId for AAD application that accesses BingAdsApi</param>
        /// <param name="usernameLoginHint">Username LoginHint to retrieve matching AccessToken from TokenCache</param>
        /// <param name="tokenCacheCorrelationId">
        ///   Used to identify persisted TokenCache location.
        ///   Provide a consistent non-null value across sessions for access to the same persisted cache.
        ///   If app must not need TokenCache persistence, just pass in null.
        /// </param>
        /// <param name="acesssTokenExpirationOffsetInSec">
        ///   Specifies when a new Token will be refreshed silently, based on AccessToken's expiresOn property.
        ///   If AccessToken.ExpiresOn = "09:30" and offset = "-600",
        ///     then call to fetch accessToken after "09:20" will try to get a refreshed accessToken.
        /// </param>
        /// <param name="apiEnvironment"></param>
        public AuthenticationTokenFactory(
            string applicationClientId,
            string usernameLoginHint             = null,
            string tokenCacheCorrelationId       = null,
            int acesssTokenExpirationOffsetInSec = Config.DefaultAccessTokenExpirationOffsetInSec,
            ApiEnvironment apiEnvironment        = ApiEnvironment.Production)
        {
            if (string.IsNullOrWhiteSpace(applicationClientId))
            {
                throw new ArgumentNullException(nameof(applicationClientId));
            }
            if (acesssTokenExpirationOffsetInSec > 0)
            {
                throw new ArgumentException($"value of {nameof(acesssTokenExpirationOffsetInSec)} must be negative");
            }

            this.apiEnvironment    = apiEnvironment;
            this.usernameLoginHint = usernameLoginHint;
            this.acesssTokenExpirationOffsetInSec = acesssTokenExpirationOffsetInSec;

            // create IPublicClientApplication for accessing BingAdsApi
            application = PublicClientApplicationBuilder.Create(applicationClientId)
                          .WithRedirectUri(Config.RedirectUri[apiEnvironment])
                          .Build();

            // try load TokenCache from persisted file storage
            if (tokenCacheCorrelationId != null)
            {
                var cacheFileName = $".msalcache.{tokenCacheCorrelationId}";
                Logger.Verbose($"TokenCache persistence at {Config.DefaultTokenCacheFileLocation}\\{cacheFileName}");

                var cacheStorageInfo = new StorageCreationPropertiesBuilder(
                    cacheFileName,
                    Config.DefaultTokenCacheFileLocation,
                    applicationClientId)
                                       .Build();

                var cacheHelper = MsalCacheHelper.CreateAsync(cacheStorageInfo).Result;

                cacheHelper.RegisterCache(application.UserTokenCache);
            }
        }
コード例 #24
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            // Initialize services that you need before app activation
            await InitializeAsync();

            // https://aka.ms/msal-net-token-cache-serialization
            var storageCreationProperties = new StorageCreationPropertiesBuilder(_config.IdentityCacheFileName, _config.IdentityCacheDirectoryName, _config.IdentityClientId).Build();
            var cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties).ConfigureAwait(false);

            _identityService.InitializeWithAadAndPersonalMsAccounts(_config.IdentityClientId, "http://localhost", cacheHelper);
            await _identityService.AcquireTokenSilentAsync();

            _shellWindow = _serviceProvider.GetService(typeof(IShellWindow)) as IShellWindow;
            _navigationService.Initialize(_shellWindow.GetNavigationFrame());
            _shellWindow.ShowWindow();
            _navigationService.NavigateTo(typeof(MainViewModel).FullName);

            // Tasks after activation
            await StartupAsync();
        }
コード例 #25
0
        private async Task InitializeAsync()
        {
            Client = await CreateClientAsync().ConfigureAwait(false);

            if (EnablePersistentCache)
            {
                MsalCacheHelper cacheHelper;

                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();

                try
                {
                    cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

                    cacheHelper.VerifyPersistence();
                }
                catch (MsalCachePersistenceException)
                {
                    if (AllowUnencryptedCache)
                    {
                        storageProperties = new StorageCreationPropertiesBuilder(Constants.DefaultMsalTokenCacheName, Constants.DefaultMsalTokenCacheDirectory, ClientId)
                                            .WithMacKeyChain(Constants.DefaultMsalTokenCacheKeychainService, Constants.DefaultMsalTokenCacheKeychainAccount)
                                            .WithLinuxUnprotectedFile()
                                            .Build();

                        cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

                        cacheHelper.VerifyPersistence();
                    }
                    else
                    {
                        throw;
                    }
                }

                cacheHelper.RegisterCache(Client.UserTokenCache);
            }
        }
コード例 #26
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));
        }
コード例 #27
0
        private async Task <IPublicClientApplication> GetOrCreateApp()
        {
            if (App == null)
            {
                // On Windows, USERPROFILE is guaranteed to be set
                string userProfile = Environment.GetEnvironmentVariable("USERPROFILE") !;
                string cacheDir    = Path.Combine(userProfile, @"AppData\Local\.IdentityService");

                // TODO: what about the other platforms?
                string clientId          = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
                var    storageProperties =
                    new StorageCreationPropertiesBuilder(
                        "msal.cache",
                        cacheDir)

                    /*
                     * .WithLinuxKeyring(
                     *  Config.LinuxKeyRingSchema,
                     *  Config.LinuxKeyRingCollection,
                     *  Config.LinuxKeyRingLabel,
                     *  Config.LinuxKeyRingAttr1,
                     *  Config.LinuxKeyRingAttr2)
                     * .WithMacKeyChain(
                     *  Config.KeyChainServiceName,
                     *  Config.KeyChainAccountName)
                     */
                    .Build();

                App = PublicClientApplicationBuilder.Create(clientId)
                      .WithRedirectUri(RedirectUri)
                      .Build();

                // This hooks up the cross-platform cache into MSAL
                var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false);

                cacheHelper.RegisterCache(App.UserTokenCache);
            }
            return(App);
        }
コード例 #28
0
        private async Task <MsalCacheHelper> CreateCacheHelperAsync()
        {
            StorageCreationProperties storageProperties;
            MsalCacheHelper           cacheHelper;

            try
            {
                storageProperties = ConfigureSecureStorage();
                cacheHelper       = await MsalCacheHelper.CreateAsync(
                    storageProperties,
                    null).ConfigureAwait(false);

                cacheHelper.VerifyPersistence();
                return(cacheHelper);
            }
            catch (MsalCachePersistenceException ex)
            {
                Console.WriteLine("Cannot persist data securely. ");
                Console.WriteLine("Details: " + ex);
                throw;
            }
        }
コード例 #29
0
        public static MsalCacheHelper GetCacheHelper()
        {
            if (MsalCacheHelper == null)
            {
                lock (ObjectLock)
                {
                    if (MsalCacheHelper == null)
                    {
                        var cacheDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ".IdentityService");
                        try
                        {
                            StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder("msal.cache", cacheDirectory)
                                                                          .WithMacKeyChain("Microsoft.Developer.IdentityService", "MSALCache")
                                                                          .WithLinuxKeyring("msal.cache", "default", "MSALCache",
                                                                                            new KeyValuePair <string, string>("MsalClientID", "Microsoft.Developer.IdentityService"),
                                                                                            new KeyValuePair <string, string>("Microsoft.Developer.IdentityService", "1.0.0.0"))
                                                                          .Build();

                            var cacheHelper = MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false).GetAwaiter().GetResult();
                            cacheHelper.VerifyPersistence();
                            MsalCacheHelper = cacheHelper;
                        }
                        catch (MsalCachePersistenceException)
                        {
                            StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder("msal.cache", cacheDirectory)
                                                                          .WithMacKeyChain("Microsoft.Developer.IdentityService", "MSALCache")
                                                                          .WithLinuxUnprotectedFile()
                                                                          .Build();

                            MsalCacheHelper = MsalCacheHelper.CreateAsync(storageProperties).ConfigureAwait(false).GetAwaiter().GetResult();
                        }
                    }
                }
            }

            return(MsalCacheHelper);
        }
コード例 #30
0
        public async Task <IAzureWorkspace?> GetAuthenticatedWorkspaceAsync(
            IChannel channel,
            ILogger?logger,
            string resourceGroupName,
            string workspaceName,
            string location,
            bool refreshCredentials)
        {
            location = GetNormalizedLocation(location, channel);

            switch (Type)
            {
            case AzureEnvironmentType.Mock:
                channel.Stdout("AZURE_QUANTUM_ENV set to Mock. Using mock Azure workspace rather than connecting to a real service.");
                return(new MockAzureWorkspace(workspaceName, location));

            case AzureEnvironmentType.Canary:
                channel.Stdout($"AZURE_QUANTUM_ENV set to Canary. Connecting to location eastus2euap rather than specified location {location}.");
                break;

            case AzureEnvironmentType.Dogfood:
                channel.Stdout($"AZURE_QUANTUM_ENV set to Dogfood. Connecting to test endpoint rather than production service.");
                break;

            case AzureEnvironmentType.Production:
                logger?.LogInformation($"AZURE_QUANTUM_ENV not set, or set to Production. Connecting to production service.");
                break;
            }

            // Find the token cache folder
            var cacheDirectoryEnvVarName = "AZURE_QUANTUM_TOKEN_CACHE";
            var cacheDirectory           = System.Environment.GetEnvironmentVariable(cacheDirectoryEnvVarName);

            if (string.IsNullOrEmpty(cacheDirectory))
            {
                cacheDirectory = Path.Join(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), ".azure-quantum");
            }

            // Register the token cache for serialization
            var cacheFileName             = "iqsharp.bin";
            var storageCreationProperties = new StorageCreationPropertiesBuilder(cacheFileName, cacheDirectory, ClientId)
                                            .WithMacKeyChain(
                serviceName: "Microsoft.Quantum.IQSharp",
                accountName: "MSALCache")
                                            .WithLinuxKeyring(
                schemaName: "com.microsoft.quantum.iqsharp",
                collection: "default",
                secretLabel: "Credentials used by Microsoft IQ# kernel",
                attribute1: new KeyValuePair <string, string>("Version", typeof(AzureClient).Assembly.GetName().Version.ToString()),
                attribute2: new KeyValuePair <string, string>("ProductGroup", "QDK"))
                                            .Build();

            MsalCacheHelper?cacheHelper;

            try
            {
                cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties);

                cacheHelper.VerifyPersistence();
            }
            catch (MsalCachePersistenceException e)
            {
                // Will occur on Linux if encryption is unavailable. Fallback to unencrypted cache on Linux, as documented here:
                // https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/blob/master/docs/keyring_fallback_proposal.md
                var unencryptedCacheFileName = "iqsharp-unencrypted.bin";
                logger?.LogWarning(e,
                                   "Encrypted credential cache is unavailable. Cache will be stored in plaintext at {Path}. Error: {Message}",
                                   Path.Combine(cacheDirectory, unencryptedCacheFileName),
                                   e.Message);

                storageCreationProperties = new StorageCreationPropertiesBuilder(unencryptedCacheFileName, cacheDirectory, ClientId)
                                            .WithMacKeyChain(
                    serviceName: "Microsoft.Quantum.IQSharp",
                    accountName: "MSALCache")
                                            .WithLinuxUnprotectedFile()
                                            .Build();

                cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties);

                cacheHelper.VerifyPersistence();
            }

            var msalApp = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(Authority).Build();

            cacheHelper.RegisterCache(msalApp.UserTokenCache);

            // Perform the authentication
            bool shouldShowLoginPrompt = refreshCredentials;
            AuthenticationResult?authenticationResult = null;

            if (!shouldShowLoginPrompt)
            {
                try
                {
                    var accounts = await msalApp.GetAccountsAsync();

                    authenticationResult = await msalApp.AcquireTokenSilent(
                        Scopes, accounts.FirstOrDefault()).WithAuthority(msalApp.Authority).ExecuteAsync();
                }
                catch (MsalUiRequiredException)
                {
                    shouldShowLoginPrompt = true;
                }
            }

            if (shouldShowLoginPrompt)
            {
                authenticationResult = await msalApp.AcquireTokenWithDeviceCode(
                    Scopes,
                    deviceCodeResult =>
                {
                    channel.Stdout(deviceCodeResult.Message);
                    return(Task.FromResult(0));
                }).WithAuthority(msalApp.Authority).ExecuteAsync();
            }

            if (authenticationResult == null)
            {
                return(null);
            }

            // Construct and return the AzureWorkspace object
            var credentials        = new Rest.TokenCredentials(authenticationResult.AccessToken);
            var azureQuantumClient = new QuantumClient(credentials)
            {
                SubscriptionId    = SubscriptionId,
                ResourceGroupName = resourceGroupName,
                WorkspaceName     = workspaceName,
                BaseUri           = BaseUriForLocation(location),
            };
            var azureQuantumWorkspace = new Azure.Quantum.Workspace(
                azureQuantumClient.SubscriptionId,
                azureQuantumClient.ResourceGroupName,
                azureQuantumClient.WorkspaceName,
                authenticationResult?.AccessToken,
                BaseUriForLocation(location));

            return(new AzureWorkspace(azureQuantumClient, azureQuantumWorkspace, location));
        }