/// <inheritdoc/>
        public virtual async Task <AuthenticationResult> ValidateAuthenticationCredentials(
            IConnection connection,
            IAuthenticationCredentials request)
        {
            var handlers = this.AuthenticationCredentialsValidationRequiredEventHandler;

            if (handlers != null)
            {
                var tasks = handlers.GetInvocationList()
                            .Cast <AsyncEventHandler <AuthenticationCredentialsValidationEventArgs> >()
                            .Select(h =>
                {
                    AuthenticationCredentialsValidationEventArgs args = new AuthenticationCredentialsValidationEventArgs(request);
                    return(new { Args = args, Task = h(this, args) });
                });

                await Task.WhenAll(tasks.Select(t => t.Task).ToArray()).ConfigureAwait(false);

                AuthenticationResult?failureResult = tasks.Select(t => t.Args.AuthenticationResult)
                                                     .Where(r => r != AuthenticationResult.Success)
                                                     .FirstOrDefault();

                return(failureResult ?? AuthenticationResult.Success);
            }

            return(AuthenticationResult.Failure);
        }
Example #2
0
        /// <summary>
        /// Login User to OneDrive.
        /// </summary>
        public async Task LoginAsync()
        {
            AuthenticationResult?  authResult = null;
            IEnumerable <IAccount> accounts   = await publicClientApplication.GetAccountsAsync();

            // let's see if we have a user in our belly already
            try
            {
                IAccount firstAccount = accounts.FirstOrDefault();
                authResult = await publicClientApplication.AcquireTokenSilent(scopes, firstAccount).ExecuteAsync();

                GraphServiceClient = graphClientFactory.CreateClient(authResult);
            }
            catch (MsalUiRequiredException ex)
            {
                logManager.Debug(ex);
                // pop the browser for the interactive experience
                authResult = await publicClientApplication.AcquireTokenInteractive(scopes)
                             .WithParentActivityOrWindow(ParentActivityWrapper.ParentActivity)                              // this is required for Android
                             .ExecuteAsync();
            }
            catch (MsalClientException ex)
            {
                if (ex.ErrorCode == ERROR_CODE_CANCELED)
                {
                    logManager.Info(ex);
                    throw new BackupOperationCanceledException();
                }

                logManager.Error(ex);
                throw;
            }
        }
        public async void ThrowsIfAuthenticationFailure()
        {
            this.authenticationResult = AuthenticationResult.Failure;
            await Assert.ThrowsAnyAsync <AuthenticationException>(sendRandomEmail);

            // test if reauthentication works
            this.authenticationResult = AuthenticationResult.Success;
            await sendRandomEmail();
        }
Example #4
0
        public async Task <AuthenticationResult> GetRawTokenAsync(IEnumerable <string> scopes, CancellationToken cancellationToken)
        {
            var app = await GetOrCreateApp();

            AuthenticationResult?result = null;
            var accounts = await app.GetAccountsAsync() !;

            IAccount?account;

            if (!string.IsNullOrEmpty(Username))
            {
                account = accounts.FirstOrDefault(account => account.Username == Username);
            }
            else
            {
                account = accounts.FirstOrDefault();
            }
            try
            {
                result = await app.AcquireTokenSilent(scopes, account)
                         .WithAuthority(Instance, TenantId)
                         .ExecuteAsync(cancellationToken);
            }
            catch (MsalUiRequiredException ex)
            {
                if (account == null && !string.IsNullOrEmpty(Username))
                {
                    Console.WriteLine($"No valid tokens found in the cache.\nPlease sign-in to Visual Studio with this account:\n\n{Username}.\n\nAfter signing-in, re-run the tool.\n");
                }
                result = await app.AcquireTokenInteractive(scopes)
                         .WithAccount(account)
                         .WithClaims(ex.Claims)
                         .WithAuthority(Instance, TenantId)
                         .ExecuteAsync(cancellationToken);
            }
            catch (MsalServiceException ex)
            {
                if (ex.Message.Contains("AADSTS70002")) // "The client does not exist or is not enabled for consumers"
                {
                    Console.WriteLine("An Azure AD tenant, and a user in that tenant, " +
                                      "needs to be created for this account before an application can be created. See https://aka.ms/ms-identity-app/create-a-tenant. ");
                    Environment.Exit(1); // we want to exit here because this is probably an MSA without an AAD tenant.
                }

                Console.WriteLine("Error encountered with sign-in. See error message for details:\n{0} ",
                                  ex.Message);
                Environment.Exit(1); // we want to exit here. Re-sign in will not resolve the issue.
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error encountered with sign-in. See error message for details:\n{0} ",
                                  ex.Message);
                Environment.Exit(1);
            }

            return(result);
        }
Example #5
0
        /// <summary>
        ///     Login User to OneDrive.
        /// </summary>
        public async Task LoginAsync()
        {
            AuthenticationResult?  authResult = null;
            IEnumerable <IAccount> accounts   = await publicClientApplication.GetAccountsAsync();

            // let's see if we have a user in our belly already
            try
            {
                IAccount firstAccount = accounts.FirstOrDefault();
                authResult = await publicClientApplication.AcquireTokenSilent(scopes, firstAccount).ExecuteAsync();

                GraphServiceClient = new GraphServiceClient(
                    new DelegateAuthenticationProvider(requestMessage =>
                {
                    requestMessage.Headers.Authorization =
                        new
                        AuthenticationHeaderValue("bearer",
                                                  authResult
                                                  .AccessToken);
                    return(Task.CompletedTask);
                }));
            }
            catch (MsalUiRequiredException ex)
            {
                logManager.Debug(ex);
                // pop the browser for the interactive experience
                authResult = await publicClientApplication.AcquireTokenInteractive(scopes)
                             .WithParentActivityOrWindow(ParentActivityWrapper
                                                         .ParentActivity)                                 // this is required for Android
                             .ExecuteAsync();
            }
            catch (MsalClientException ex)
            {
                if (ex.ErrorCode == ERROR_CODE_CANCELED)
                {
                    logManager.Info(ex);
                    throw new BackupOperationCanceledException();
                }

                logManager.Error(ex);
                throw;
            }
        }
Example #6
0
        public ValueTask <AuthenticationResult> AcquireTokenAsync()
        {
            var token = _token;

            if (token != null && token.ExpiresOn >= DateTimeOffset.UtcNow.AddMinutes(5))
            {
                return(new ValueTask <AuthenticationResult>(token));
            }
            return(AcquireTokenAsyncWithAwait());

            async ValueTask <AuthenticationResult> AcquireTokenAsyncWithAwait()
            {
                await _acquireTokenLock.WaitAsync();

                try
                {
                    // Recheck the token in the lock
                    token = _token;
                    if (token != null && token.ExpiresOn >= DateTimeOffset.UtcNow.AddMinutes(5))
                    {
                        return(token);
                    }

                    // Acquire a new token
                    _logger.LogDebug("Acquiring new authentication token...");
                    _token = await _app.AcquireTokenForClient(_scopes)
                             .ExecuteAsync();

                    _logger.LogDebug("Token acquired.");

                    return(_token);
                }
                finally
                {
                    _acquireTokenLock.Release();
                }
            }
        }
Example #7
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 #8
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));
        }
Example #9
0
        public override async ValueTask <AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
        {
            AuthenticationResult?result = await GetRawTokenAsync(requestContext.Scopes, cancellationToken);

            return(new AccessToken(result.AccessToken, result.ExpiresOn));
        }