diff --git a/src/service/API/Microsoft.FeatureFlighting.API.csproj b/src/service/API/Microsoft.FeatureFlighting.API.csproj index 3d5b7a9..f342293 100644 --- a/src/service/API/Microsoft.FeatureFlighting.API.csproj +++ b/src/service/API/Microsoft.FeatureFlighting.API.csproj @@ -21,7 +21,7 @@ - + @@ -45,6 +45,7 @@ + diff --git a/src/service/API/Program.cs b/src/service/API/Program.cs index bab153a..c6baa3e 100644 --- a/src/service/API/Program.cs +++ b/src/service/API/Program.cs @@ -10,7 +10,7 @@ using Azure.Extensions.AspNetCore.Configuration.Secrets; using Microsoft.Extensions.Configuration.AzureAppConfiguration; using Azure.Core; - +using Microsoft.FeatureFlighting.Common; namespace Microsoft.PS.Services.FlightingService.Api { [ExcludeFromCodeCoverage] @@ -38,14 +38,9 @@ public static IHostBuilder CreateHostBuilder(string[] args) private static void AddKeyVault(IConfigurationBuilder config) { - var builtConfig = config.Build(); + var builtConfig = config.Build(); TokenCredential credential; - #if DEBUG - credential = new VisualStudioCredential(); - #else - credential = new ManagedIdentityCredential( - ManagedIdentityId.FromUserAssignedClientId(builtConfig["UserAssignedClientId"])); - #endif + credential = ManagedIdentityHelper.GetTokenCredential(); config.AddAzureKeyVault( new SecretClient( @@ -66,15 +61,9 @@ private static void AddAzureAppConfiguration(IConfigurationBuilder config) string appConfigurationUri = builtConfig["AzureAppConfigurationUri"]; string flightingAppConfigLabel = builtConfig["AppConfiguration:FeatureFlightsLabel"]; string configurationCommonLabel = builtConfig["AppConfiguration:ConfigurationCommonLabel"]; - string configurationEnvLabel = builtConfig["AppConfiguration:ConfigurationEnvLabel"]; + string configurationEnvLabel = builtConfig["AppConfiguration:ConfigurationEnvLabel"]; TokenCredential credential; - #if DEBUG - credential = new VisualStudioCredential(); - #else - credential = new ManagedIdentityCredential( - ManagedIdentityId.FromUserAssignedClientId(builtConfig["UserAssignedClientId"])); - #endif - + credential = ManagedIdentityHelper.GetTokenCredential(); config.AddAzureAppConfiguration(options => { options diff --git a/src/service/Common/Authentication/ITokenGenerator.cs b/src/service/Common/Authentication/ITokenGenerator.cs index 4e47a89..40e039e 100644 --- a/src/service/Common/Authentication/ITokenGenerator.cs +++ b/src/service/Common/Authentication/ITokenGenerator.cs @@ -12,9 +12,8 @@ public interface ITokenGenerator /// /// Authority to generate the token /// ID of the application for generating the token - /// Resource ID for which the token is generated - /// user Assigned Client Id + /// Resource ID for which the token is generated /// Bearer token - Task GenerateToken(string authority, string clientId, string resourceId, string userAssignedClientId); + Task GenerateToken(string authority, string clientId, string resourceId); } } diff --git a/src/service/Common/Authorization/IAuthorizationService.cs b/src/service/Common/Authorization/IAuthorizationService.cs index 30995ba..5fd2267 100644 --- a/src/service/Common/Authorization/IAuthorizationService.cs +++ b/src/service/Common/Authorization/IAuthorizationService.cs @@ -29,10 +29,9 @@ public interface IAuthorizationService /// /// IDP authority /// AAD Client ID - /// AAD Client ID against which the token is acquired - /// user Assigned Client Id + /// AAD Client ID against which the token is acquired /// Bearer token - Task GetAuthenticationToken(string authority, string clientId, string resourceId,string userAssignedClientId); + Task GetAuthenticationToken(string authority, string clientId, string resourceId); /// /// Augments the user identity with the required claims diff --git a/src/service/Common/ManagedIdentityHelper.cs b/src/service/Common/ManagedIdentityHelper.cs new file mode 100644 index 0000000..f96d46a --- /dev/null +++ b/src/service/Common/ManagedIdentityHelper.cs @@ -0,0 +1,30 @@ +using Azure.Core; +using Azure.Identity; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.FeatureFlighting.Common +{ + public class ManagedIdentityHelper + { + /// + /// Get the token credential based on the environment (Debug/Release). + /// + /// Token Credential + public static TokenCredential GetTokenCredential() + { + TokenCredential credential = null; + +#if DEBUG + credential = new VisualStudioCredential(); +#else + credential = new ManagedIdentityCredential(); +#endif + + return credential; + } + } +} diff --git a/src/service/Common/Microsoft.FeatureFlighting.Common.csproj b/src/service/Common/Microsoft.FeatureFlighting.Common.csproj index 90ed0ba..a9be514 100644 --- a/src/service/Common/Microsoft.FeatureFlighting.Common.csproj +++ b/src/service/Common/Microsoft.FeatureFlighting.Common.csproj @@ -8,6 +8,7 @@ + diff --git a/src/service/Domain/Microsoft.FeatureFlighting.Core.csproj b/src/service/Domain/Microsoft.FeatureFlighting.Core.csproj index 428de78..dd599d7 100644 --- a/src/service/Domain/Microsoft.FeatureFlighting.Core.csproj +++ b/src/service/Domain/Microsoft.FeatureFlighting.Core.csproj @@ -13,6 +13,7 @@ + diff --git a/src/service/Infrastructure/AppConfig/AzureConfigurationClientProvider.cs b/src/service/Infrastructure/AppConfig/AzureConfigurationClientProvider.cs index 25f2726..36678cb 100644 --- a/src/service/Infrastructure/AppConfig/AzureConfigurationClientProvider.cs +++ b/src/service/Infrastructure/AppConfig/AzureConfigurationClientProvider.cs @@ -3,6 +3,7 @@ using Azure.Data.AppConfiguration; using Azure.Identity; using Microsoft.Extensions.Configuration; +using Microsoft.FeatureFlighting.Common; using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication; namespace Microsoft.FeatureFlighting.Infrastructure.AppConfig @@ -33,12 +34,7 @@ public ConfigurationClient GetConfigurationClient() options.Retry.MaxRetries = 10; options.Retry.Delay = TimeSpan.FromSeconds(1); TokenCredential credential; - #if DEBUG - credential = new VisualStudioCredential(); - #else - credential = new ManagedIdentityCredential( - ManagedIdentityId.FromUserAssignedClientId(_configuration["UserAssignedClientId"])); - #endif + credential = ManagedIdentityHelper.GetTokenCredential(); string appConfigUri = _configuration["AzureAppConfigurationUri"]; _configurationClient = new ConfigurationClient(new Uri(appConfigUri), credential, options); return _configurationClient; diff --git a/src/service/Infrastructure/Authentication/AadTokenGenerator.cs b/src/service/Infrastructure/Authentication/AadTokenGenerator.cs index 4af72e3..4ea7a33 100644 --- a/src/service/Infrastructure/Authentication/AadTokenGenerator.cs +++ b/src/service/Infrastructure/Authentication/AadTokenGenerator.cs @@ -10,6 +10,7 @@ using Azure.Core; using Azure.Identity; using System.Threading; +using Microsoft.FeatureFlighting.Common; namespace Microsoft.FeatureFlighting.Infrastructure.Authentication { @@ -26,9 +27,9 @@ public AadTokenGenerator() } // - public async Task GenerateToken(string authority, string clientId, string resourceId, string userAssignedClientId) + public async Task GenerateToken(string authority, string clientId, string resourceId) { - IConfidentialClientApplication client = GetOrCreateConfidentialApp(authority, clientId, userAssignedClientId); + IConfidentialClientApplication client = GetOrCreateConfidentialApp(authority, clientId); var scopes = new string[] { resourceId }; AuthenticationResult authenticationResult = await client .AcquireTokenForClient(scopes) @@ -36,7 +37,7 @@ public async Task GenerateToken(string authority, string clientId, strin return authenticationResult.AccessToken; } - private IConfidentialClientApplication GetOrCreateConfidentialApp(string authority, string clientId, string userAssignedClientId) + private IConfidentialClientApplication GetOrCreateConfidentialApp(string authority, string clientId) { string confidentialAppCacheKey = CreateConfidentialAppCacheKey(authority, clientId); if (_cache.ContainsKey(confidentialAppCacheKey)) @@ -58,8 +59,7 @@ private IConfidentialClientApplication GetOrCreateConfidentialApp(string authori return client; #else - var credential = new ManagedIdentityCredential(userAssignedClientId); - + var credential = ManagedIdentityHelper.GetTokenCredential(); IConfidentialClientApplication client = ConfidentialClientApplicationBuilder .Create(clientId) diff --git a/src/service/Infrastructure/Authorization/AuthorizationService.cs b/src/service/Infrastructure/Authorization/AuthorizationService.cs index 2b88426..8021c00 100644 --- a/src/service/Infrastructure/Authorization/AuthorizationService.cs +++ b/src/service/Infrastructure/Authorization/AuthorizationService.cs @@ -15,6 +15,7 @@ using Azure.Identity; using Azure.Core; using System.Threading; +using Microsoft.FeatureFlighting.Common; [assembly: InternalsVisibleTo("Microsoft.FeatureFlighting.Infrastructure.Tests")] @@ -75,14 +76,14 @@ public bool IsAuthorized(string appName) return false; } - public async Task GetAuthenticationToken(string authority, string clientId, string resourceId,string userAssignedClientId) + public async Task GetAuthenticationToken(string authority, string clientId, string resourceId) { AuthenticationResult authenticationResult; const string MsalScopeSuffix = "/.default"; string bearerToken = null; try { - IConfidentialClientApplication app = GetOrCreateConfidentialApp(authority, clientId, userAssignedClientId); + IConfidentialClientApplication app = GetOrCreateConfidentialApp(authority, clientId); if (app != null) { var scopes = new[] { resourceId + MsalScopeSuffix }; @@ -97,7 +98,7 @@ public async Task GetAuthenticationToken(string authority, string client return bearerToken; } - private IConfidentialClientApplication GetOrCreateConfidentialApp(string authority, string clientId,string userAssignedClientId) + private IConfidentialClientApplication GetOrCreateConfidentialApp(string authority, string clientId) { string confidentialAppCacheKey = $"{authority}-{clientId}"; if (_confidentialApps.ContainsKey(confidentialAppCacheKey)) @@ -115,7 +116,7 @@ private IConfidentialClientApplication GetOrCreateConfidentialApp(string authori _confidentialApps.TryAdd(confidentialAppCacheKey, app); return app; #else - var credential = new ManagedIdentityCredential(userAssignedClientId); + var credential = ManagedIdentityHelper.GetTokenCredential(); IConfidentialClientApplication app = ConfidentialClientApplicationBuilder .Create(clientId) diff --git a/src/service/Infrastructure/Graph/GraphGroupVerificationService.cs b/src/service/Infrastructure/Graph/GraphGroupVerificationService.cs index e13e9e2..0ea44d5 100644 --- a/src/service/Infrastructure/Graph/GraphGroupVerificationService.cs +++ b/src/service/Infrastructure/Graph/GraphGroupVerificationService.cs @@ -147,7 +147,7 @@ private IGraphServiceClient CreateGraphClient(IConfiguration configuration) _cache.Add(confidentialAppCacheKey, client); #else - var credential = new ManagedIdentityCredential(configuration["UserAssignedClientId"]); + var credential = ManagedIdentityHelper.GetTokenCredential(); IConfidentialClientApplication client = ConfidentialClientApplicationBuilder .Create(configuration["Graph:ClientId"]) diff --git a/src/service/Infrastructure/Microsoft.FeatureFlighting.Infrastructure.csproj b/src/service/Infrastructure/Microsoft.FeatureFlighting.Infrastructure.csproj index 8d63f16..2e49800 100644 --- a/src/service/Infrastructure/Microsoft.FeatureFlighting.Infrastructure.csproj +++ b/src/service/Infrastructure/Microsoft.FeatureFlighting.Infrastructure.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/service/Infrastructure/Storage/BlobProviderFactory.cs b/src/service/Infrastructure/Storage/BlobProviderFactory.cs index 6ec0d1b..8476e02 100644 --- a/src/service/Infrastructure/Storage/BlobProviderFactory.cs +++ b/src/service/Infrastructure/Storage/BlobProviderFactory.cs @@ -30,12 +30,7 @@ public BlobProviderFactory(ITenantConfigurationProvider tenantConfigurationProvi _configuration = configuration; if (_defaultAzureCredential == null) { - #if DEBUG - _defaultAzureCredential = new VisualStudioCredential(); - #else - _defaultAzureCredential = new ManagedIdentityCredential( - ManagedIdentityId.FromUserAssignedClientId(_configuration["UserAssignedClientId"])); - #endif + _defaultAzureCredential = ManagedIdentityHelper.GetTokenCredential(); } } diff --git a/src/service/Infrastructure/Storage/CosmosDbRepository.cs b/src/service/Infrastructure/Storage/CosmosDbRepository.cs index 9b6c1d8..81f8426 100644 --- a/src/service/Infrastructure/Storage/CosmosDbRepository.cs +++ b/src/service/Infrastructure/Storage/CosmosDbRepository.cs @@ -42,13 +42,7 @@ public CosmosDbRepository(CosmosDbConfiguration cosmosConfiguration, IConfigurat MaxRetryAttemptsOnRateLimitedRequests = int.Parse(_configuration["CosmosDb:MaxRetryAttemptsOnRateLimitedRequests"]) }; TokenCredential credential; - #if DEBUG - credential = new VisualStudioCredential(); - #else - credential = new ManagedIdentityCredential( - ManagedIdentityId.FromUserAssignedClientId(_configuration["UserAssignedClientId"])); - #endif - + credential = ManagedIdentityHelper.GetTokenCredential(); CosmosClient client = new(cosmosConfiguration.Endpoint, credential, options); Database database = client.GetDatabase(cosmosConfiguration.DatabaseId); _container = database.GetContainer(cosmosConfiguration.ContainerId); diff --git a/src/service/Infrastructure/Webhook/WebhookTriggerManager.cs b/src/service/Infrastructure/Webhook/WebhookTriggerManager.cs index 85d5aec..890b4d7 100644 --- a/src/service/Infrastructure/Webhook/WebhookTriggerManager.cs +++ b/src/service/Infrastructure/Webhook/WebhookTriggerManager.cs @@ -16,7 +16,7 @@ using Microsoft.Extensions.Configuration; namespace Microsoft.FeatureFlighting.Infrastructure.Webhook -{ +{ // internal class WebhookTriggerManager: IWebhookTriggerManager { @@ -26,7 +26,7 @@ internal class WebhookTriggerManager: IWebhookTriggerManager public IConfiguration _configuration { get; } public WebhookTriggerManager(IHttpClientFactory httpClientFactory, ITokenGenerator tokenGenerator, ILogger logger, IConfiguration configuration) - { + { _httpClientFactory = httpClientFactory; _tokenGenerator = tokenGenerator; _logger= logger; @@ -49,7 +49,7 @@ public async Task Trigger(WebhookConfiguration webhook, string payload, DependencyContext dependency = CreateDependencyContext(webhook, trackingIds); HttpRequestMessage request = new(new HttpMethod(webhook.HttpMethod), webhook.Uri ?? ""); - string bearerToken = await _tokenGenerator.GenerateToken(webhook.AuthenticationAuthority, webhook.ClientId, webhook.ResourceId, _configuration["UserAssignedClientId"]); + string bearerToken = await _tokenGenerator.GenerateToken(webhook.AuthenticationAuthority, webhook.ClientId, webhook.ResourceId); request.Headers.Add("Authorization", $"Bearer {bearerToken}"); request.Headers.Add("x-correlationId", trackingIds.CorrelationId); request.Headers.Add("x-messageId", trackingIds.TransactionId); @@ -62,7 +62,7 @@ public async Task Trigger(WebhookConfiguration webhook, string payload, request.Headers.Add(header.Key, header.Value); } } - + request.Content = new StringContent(payload, Encoding.UTF8, "application/json"); dependency.RequestDetails = payload; diff --git a/src/service/Tests/Api.Tests/Microsoft.FeatureFlighting.API.Tests.csproj b/src/service/Tests/Api.Tests/Microsoft.FeatureFlighting.API.Tests.csproj index 85b819e..591d90f 100644 --- a/src/service/Tests/Api.Tests/Microsoft.FeatureFlighting.API.Tests.csproj +++ b/src/service/Tests/Api.Tests/Microsoft.FeatureFlighting.API.Tests.csproj @@ -7,6 +7,7 @@ + diff --git a/src/service/Tests/Common.Tests/Microsoft.FeatureFlighting.Common.Tests.csproj b/src/service/Tests/Common.Tests/Microsoft.FeatureFlighting.Common.Tests.csproj index f9d22bf..39c9352 100644 --- a/src/service/Tests/Common.Tests/Microsoft.FeatureFlighting.Common.Tests.csproj +++ b/src/service/Tests/Common.Tests/Microsoft.FeatureFlighting.Common.Tests.csproj @@ -6,6 +6,7 @@ + diff --git a/src/service/Tests/Domain.Tests/Microsoft.PS.FlightingService.Core.Tests.csproj b/src/service/Tests/Domain.Tests/Microsoft.PS.FlightingService.Core.Tests.csproj index cda8a01..9afd482 100644 --- a/src/service/Tests/Domain.Tests/Microsoft.PS.FlightingService.Core.Tests.csproj +++ b/src/service/Tests/Domain.Tests/Microsoft.PS.FlightingService.Core.Tests.csproj @@ -7,6 +7,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/service/Tests/Services.Tests/Microsoft.FeatureFlighting.Infrastructure.Tests.csproj b/src/service/Tests/Services.Tests/Microsoft.FeatureFlighting.Infrastructure.Tests.csproj index dc7782a..86edc68 100644 --- a/src/service/Tests/Services.Tests/Microsoft.FeatureFlighting.Infrastructure.Tests.csproj +++ b/src/service/Tests/Services.Tests/Microsoft.FeatureFlighting.Infrastructure.Tests.csproj @@ -19,6 +19,7 @@ +