private KeyVaultClientEx CreateKeyVaultClientEx(VaultAccessTypeEnum accessType, string vaultName) => new KeyVaultClientEx(vaultName, (authority, resource, scope) => { lock (Lock) { Utils.GuardVaultName(vaultName); if (false == VaultsConfig.ContainsKey(vaultName)) { throw new KeyNotFoundException($"{vaultName} is not found in {VaultsConfigFile}"); } VaultAccessType vat = VaultsConfig[vaultName]; VaultAccess[] vas = (accessType == VaultAccessTypeEnum.ReadOnly) ? vat.ReadOnly : vat.ReadWrite; // Order possible VaultAccess options by Order property IEnumerable <VaultAccess> vaSorted = from va in vas orderby va.Order select va; // In case VaultAccessUserInteractive is in the list, we will use our FileTokenCache with provided domainHint, otherwise use MemoryTokenCache string domainHint = (from va in vaSorted where va is VaultAccessUserInteractive select(VaultAccessUserInteractive) va).FirstOrDefault()?.DomainHint; string userAliasType = (from va in vaSorted where va is VaultAccessUserInteractive select(VaultAccessUserInteractive) va).FirstOrDefault()?.UserAliasType; // Token cache name is unique per login credentials as it uses alias type or env user name and domain hint. string tokenCacheName = $"{(userAliasType ?? Environment.UserName)}@{domainHint ?? "microsoft.com"}"; // If either user alias or domain hint are empty, cache in memory instead. var authenticationContext = new AuthenticationContext(authority, string.IsNullOrEmpty(domainHint) && string.IsNullOrEmpty(userAliasType) ? new MemoryTokenCache() : (TokenCache) new FileTokenCache(tokenCacheName)); Queue <Exception> exceptions = new Queue <Exception>(); string vaultAccessTypes = ""; foreach (VaultAccess va in vaSorted) { try { // If user alias type is different from environment, force login prompt, otherwise silently login var authResult = va.AcquireToken(authenticationContext, resource, userAliasType == Environment.UserName ? Environment.UserName:""); AuthenticatedUserName = authResult.UserInfo?.DisplayableId ?? $"{Environment.UserDomainName}\\{Environment.UserName}"; return(Task.FromResult(authResult.AccessToken)); } catch (Exception e) { vaultAccessTypes += $" {va}"; exceptions.Enqueue(e); } } throw new VaultAccessException($"Failed to get access to {vaultName} with all possible vault access type(s){vaultAccessTypes}", exceptions.ToArray()); } });
private KeyVaultClientEx CreateKeyVaultClientEx(VaultAccessTypeEnum accessType, string vaultName) => new KeyVaultClientEx(vaultName, (authority, resource, scope) => { Utils.GuardVaultName(vaultName); if (false == VaultsConfig.ContainsKey(vaultName)) { throw new KeyNotFoundException($"{vaultName} is not found in {VaultsConfigFile}"); } VaultAccessType vat = VaultsConfig[vaultName]; VaultAccess[] vas = (accessType == VaultAccessTypeEnum.ReadOnly) ? vat.ReadOnly : vat.ReadWrite; // Order possible VaultAccess options by Order property IEnumerable <VaultAccess> vaSorted = from va in vas orderby va.Order select va; // In case VaultAccessUserInteractive is in the list, we will use our FileTokenCache with provided domainHint, otherwise use MemoryTokenCache string domainHint = (from va in vaSorted where va is VaultAccessUserInteractive select(VaultAccessUserInteractive) va).FirstOrDefault()?.DomainHint; var authenticationContext = new AuthenticationContext(authority, string.IsNullOrEmpty(domainHint) ? new MemoryTokenCache() : (TokenCache) new FileTokenCache(domainHint)); Queue <Exception> exceptions = new Queue <Exception>(); string vaultAccessTypes = ""; foreach (VaultAccess va in vaSorted) { try { var authResult = va.AcquireToken(authenticationContext, resource); AuthenticatedUserName = authResult.UserInfo?.DisplayableId ?? $"{Environment.UserDomainName}\\{Environment.UserName}"; return(Task.FromResult(authResult.AccessToken)); } catch (Exception e) { vaultAccessTypes += $" {va}"; exceptions.Enqueue(e); } } throw new VaultAccessException($"Failed to get access to {vaultName} with all possible vault access type(s){vaultAccessTypes}", exceptions.ToArray()); });