private async ValueTask <AccessToken> GetTokenImplAsync(bool async, TokenRequestContext requestContext, CancellationToken cancellationToken)
        {
            using CredentialDiagnosticScope scope = _pipeline.StartGetTokenScopeGroup("DefaultAzureCredential.GetToken", requestContext);

            try
            {
                using var asyncLock = await _credentialLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

                AccessToken token;
                if (asyncLock.HasValue)
                {
                    token = await GetTokenFromCredentialAsync(asyncLock.Value, requestContext, async, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    TokenCredential credential;
                    (token, credential) = await GetTokenFromSourcesAsync(_sources, requestContext, async, cancellationToken).ConfigureAwait(false);

                    _sources = default;
                    asyncLock.SetValue(credential);
                }

                return(scope.Succeeded(token));
            }
            catch (Exception e)
            {
                throw scope.FailWrapAndThrow(e);
            }
        }
예제 #2
0
        private async Task <MsalCacheHelperWrapper> GetCacheHelperAsync(bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await cacheHelperLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            MsalCacheHelperWrapper cacheHelper;

            try
            {
                cacheHelper = await GetProtectedCacheHelperAsync(async, _name).ConfigureAwait(false);

                cacheHelper.VerifyPersistence();
            }
            catch (MsalCachePersistenceException)
            {
                if (_allowUnencryptedStorage)
                {
                    cacheHelper = await GetFallbackCacheHelperAsync(async, _name).ConfigureAwait(false);

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

            asyncLock.SetValue(cacheHelper);

            return(cacheHelper);
        }
예제 #3
0
        private async ValueTask <IAccount> GetAccountAsync(string tenantId, bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await _accountAsyncLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            IAccount account;

            if (_record != null)
            {
                account = new AuthenticationAccount(_record);
                asyncLock.SetValue(account);
                return(account);
            }

            List <IAccount> accounts = await Client.GetAccountsAsync(async, cancellationToken).ConfigureAwait(false);

            if (accounts.Count == 0)
            {
                throw new CredentialUnavailableException(NoAccountsInCacheMessage);
            }

            // filter the accounts to those matching the specified user and tenant
            List <IAccount> filteredAccounts = accounts.Where(a =>
                                                              // if _username is specified it must match the account
                                                              (string.IsNullOrEmpty(_username) || string.Compare(a.Username, _username, StringComparison.OrdinalIgnoreCase) == 0)
                                                              &&
                                                              // if _skipTenantValidation is false and _tenantId is specified it must match the account
                                                              (_skipTenantValidation || string.IsNullOrEmpty(tenantId) || string.Compare(a.HomeAccountId?.TenantId, tenantId, StringComparison.OrdinalIgnoreCase) == 0)
                                                              )
                                               .ToList();

            if (_skipTenantValidation && filteredAccounts.Count > 1)
            {
                filteredAccounts = filteredAccounts
                                   .Where(a => string.IsNullOrEmpty(tenantId) || string.Compare(a.HomeAccountId?.TenantId, tenantId, StringComparison.OrdinalIgnoreCase) == 0)
                                   .ToList();
            }

            if (filteredAccounts.Count != 1)
            {
                throw new CredentialUnavailableException(GetCredentialUnavailableMessage(filteredAccounts));
            }

            account = filteredAccounts[0];
            asyncLock.SetValue(account);
            return(account);
        }
예제 #4
0
        protected async ValueTask <TClient> GetClientAsync(bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await _clientAsyncLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            var client = await CreateClientAsync(async, cancellationToken).ConfigureAwait(false);

            if (EnablePersistentCache)
            {
                MsalCacheHelper cacheHelper;

                StorageCreationProperties storageProperties = new StorageCreationPropertiesBuilder(Constants.DefaultMsalTokenCacheName, Constants.DefaultMsalTokenCacheDirectory, s_msalCacheClientId)
                                                              .WithMacKeyChain(Constants.DefaultMsalTokenCacheKeychainService, Constants.DefaultMsalTokenCacheKeychainAccount)
                                                              .WithLinuxKeyring(Constants.DefaultMsalTokenCacheKeyringSchema, Constants.DefaultMsalTokenCacheKeyringCollection, Constants.DefaultMsalTokenCacheKeyringLabel, Constants.DefaultMsaltokenCacheKeyringAttribute1, Constants.DefaultMsaltokenCacheKeyringAttribute2)
                                                              .Build();

                try
                {
                    cacheHelper = await CreateCacheHelper(storageProperties, async).ConfigureAwait(false);

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

                        cacheHelper = await CreateCacheHelper(storageProperties, async).ConfigureAwait(false);

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

                cacheHelper.RegisterCache(client.UserTokenCache);
            }

            asyncLock.SetValue(client);
            return(client);
        }
예제 #5
0
        private static async Task <MsalCacheHelper> GetProtectedCacheHelperAsync(bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await s_ProtectedCacheHelperLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            MsalCacheHelper cacheHelper = await GetProtectedCacheHelperAsync(async, Constants.DefaultMsalTokenCacheName).ConfigureAwait(false);

            asyncLock.SetValue(cacheHelper);

            return(cacheHelper);
        }
예제 #6
0
        private protected virtual async ValueTask <IManagedIdentitySource> GetManagedIdentitySourceAsync(bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await _identitySourceAsyncLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            IManagedIdentitySource identitySource = AppServiceV2017ManagedIdentitySource.TryCreate(_pipeline.HttpPipeline, ClientId) ??
                                                    CloudShellManagedIdentitySource.TryCreate(_pipeline.HttpPipeline, ClientId) ??
                                                    await ImdsManagedIdentitySource.TryCreateAsync(_pipeline.HttpPipeline, ClientId, async, cancellationToken).ConfigureAwait(false);

            asyncLock.SetValue(identitySource);
            return(identitySource);
        }
        private protected virtual async ValueTask <ManagedIdentitySource> GetManagedIdentitySourceAsync(bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await _identitySourceAsyncLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            ManagedIdentitySource identitySource = AppServiceV2017ManagedIdentitySource.TryCreate(_options) ??
                                                   CloudShellManagedIdentitySource.TryCreate(_options) ??
                                                   AzureArcManagedIdentitySource.TryCreate(_options) ??
                                                   ServiceFabricManagedIdentitySource.TryCreate(_options) ??
                                                   await ImdsManagedIdentitySource.TryCreateAsync(_options, async, cancellationToken).ConfigureAwait(false);

            asyncLock.SetValue(identitySource);
            return(identitySource);
        }
예제 #8
0
        protected async ValueTask <TClient> GetClientAsync(bool async, CancellationToken cancellationToken)
        {
            using var asyncLock = await _clientAsyncLock.GetLockOrValueAsync(async, cancellationToken).ConfigureAwait(false);

            if (asyncLock.HasValue)
            {
                return(asyncLock.Value);
            }

            var client = await CreateClientAsync(async, cancellationToken).ConfigureAwait(false);

            if (TokenCache != null)
            {
                await TokenCache.RegisterCache(async, client.UserTokenCache, cancellationToken).ConfigureAwait(false);
            }

            asyncLock.SetValue(client);
            return(client);
        }