Example #1
0
 public AzureWorkspace(QuantumClient azureQuantumClient, Azure.Quantum.Workspace azureQuantumWorkspace, string location)
 {
     AzureQuantumClient    = azureQuantumClient;
     AzureQuantumWorkspace = azureQuantumWorkspace;
     Location = location;
 }
Example #2
0
 public AzureWorkspace(QuantumClient azureQuantumClient, Azure.Quantum.Workspace azureQuantumWorkspace)
 {
     AzureQuantumClient    = azureQuantumClient;
     AzureQuantumWorkspace = azureQuantumWorkspace;
 }
Example #3
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));
        }
Example #4
0
        public async Task <IAzureWorkspace?> GetAuthenticatedWorkspaceAsync(IChannel channel, string resourceGroupName, string workspaceName, bool refreshCredentials)
        {
            if (Type == AzureEnvironmentType.Mock)
            {
                channel.Stdout("AZURE_QUANTUM_ENV set to Mock. Using mock Azure workspace rather than connecting to the real service.");
                return(new MockAzureWorkspace(workspaceName));
            }

            // 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();
            var cacheHelper = await MsalCacheHelper.CreateAsync(storageCreationProperties);

            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           = BaseUri,
            };
            var azureQuantumWorkspace = new Azure.Quantum.Workspace(
                azureQuantumClient.SubscriptionId,
                azureQuantumClient.ResourceGroupName,
                azureQuantumClient.WorkspaceName,
                authenticationResult?.AccessToken,
                BaseUri);

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