Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="CQRS.Mediatr.Lite" Version="1.0.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ public class AadAuthenticator : IAuthenticator
private readonly string _clientId;
private readonly ConcurrentDictionary<string, IConfidentialClientApplication> confidentialApps = new ConcurrentDictionary<string, IConfidentialClientApplication>();
private readonly string _certificateThumprint;
public AadAuthenticator(string authority, string clientId, string certificateThumbprint)
private readonly string _userAssignedClientId;
public AadAuthenticator(string authority, string clientId, string certificateThumbprint,string userAssignedClientId)
{
_authority = authority;
_clientId = clientId;
_certificateThumprint = certificateThumbprint;
_userAssignedClientId= userAssignedClientId;
}

public async Task<string> GenerateToken(string resourceId, Dictionary<string, string> additionalClaims)
Expand Down Expand Up @@ -51,11 +53,12 @@ private IConfidentialClientApplication GetOrCreateConfidentialApp(string authori
confidentialApps.TryAdd(confidentialAppCacheKey, confidentialClientApplication);
return confidentialClientApplication;
#else

var managedIdentityId = ManagedIdentityId.FromUserAssignedClientId(_userAssignedClientId);
var credential = new ManagedIdentityCredential(managedIdentityId);
IConfidentialClientApplication clientApplicationWithMI = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority(new Uri(authority))
.WithClientAssertion((AssertionRequestOptions options) =>
{
var accessToken = new DefaultAzureCredential().GetToken(new TokenRequestContext(new string[] { $"api://AzureADTokenExchange/.default" }), CancellationToken.None);
var accessToken = credential.GetToken(new TokenRequestContext(new string[] { $"api://AzureADTokenExchange/.default" }), CancellationToken.None);
return Task.FromResult(accessToken.Token);
}).Build();
confidentialApps.TryAdd(confidentialAppCacheKey, clientApplicationWithMI);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.60.3" />
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
<PackageReference Include="Microsoft.Identity.Web" Version="2.18.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.35.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.35.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.8" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

<ItemGroup>
<PackageReference Include="AppInsights.EnterpriseTelemetry" Version="1.0.2" />
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
<PackageReference Include="StackExchange.Redis" Version="2.0.601" />

</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Microsoft.UnifiedPlatform.Service.Common.AppExceptions;
Expand All @@ -8,11 +9,12 @@
using System;
using System.Net;
using System.Threading.Tasks;
using ManagedIdentityId = Azure.Identity.ManagedIdentityId;

/// <summary>
/// Provides application secrets from Azure Key Vault
/// </summary>
public class KeyVaultProvider: ISecretsProvider
public class KeyVaultProvider : ISecretsProvider
{
public const string KEY_VAULT_URI_FORMAT = "https://{0}.vault.azure.net";

Expand All @@ -24,11 +26,19 @@ public class KeyVaultProvider: ISecretsProvider
/// </summary>
/// <param name="configuration" cref="KeyvaultConfiguration">Configuration for connecting to Azure Key Vault</param>
/// <param name="cacheService" cref="ICacheService">Service for caching data</param>
public KeyVaultProvider(string keyVaultName, ICacheService cacheService)
public KeyVaultProvider(string keyVaultName, string userAssignedClientId, ICacheService cacheService)
{
var keyVaultUri = string.Format(KEY_VAULT_URI_FORMAT, keyVaultName);
_cacheService = cacheService;
var credential = new DefaultAzureCredential();

TokenCredential credential;
#if DEBUG
credential = new VisualStudioCredential();
#else
var managedIdentityId = ManagedIdentityId.FromUserAssignedClientId(userAssignedClientId);
credential = new ManagedIdentityCredential(managedIdentityId);
#endif

var secretClient = new SecretClient(new Uri(keyVaultUri), credential);

_keyVaultClientWrapper = new KeyVaultClientWrapper(keyVaultUri, secretClient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.6.0" />
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.6.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

<ItemGroup>
<PackageReference Include="Azure.Data.Tables" Version="12.8.3" />
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.3.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using GeoCoordinatePortable;
using Microsoft.AzureRegion.Models;
using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
Expand Down Expand Up @@ -31,6 +30,7 @@ public class AzureRegionUtility : IAzureRegionUtility
private static DateTime _cachedUntil = DateTime.UtcNow;
private readonly ConcurrentDictionary<string, IConfidentialClientApplication> confidentialApps = new ConcurrentDictionary<string, IConfidentialClientApplication>();
private readonly string CertificateThumbprint;
private readonly string UserAssignedClientId;

public AzureRegionUtility(string certificateThumbprint)
: this(azureSubscriptionId: "05a315f7-744f-4692-b9dd-1aed7c6cee64",
Expand All @@ -39,16 +39,17 @@ public AzureRegionUtility(string certificateThumbprint)
aadAuthority: "https://login.microsoftonline.com/microsoft.onmicrosoft.com",
aadClientId: "1601a33e-356e-4570-8325-eefe6116eadb",
cacheDurationInMins: 43200,
certificateThumbprint: certificateThumbprint
certificateThumbprint: certificateThumbprint,
userAssignedClientId: "ddcbb4aa-01a9-46aa-8c11-03e1b789d9cd"
)
{ }

public AzureRegionUtility(string azureSubscriptionId, string azureManagementEndpoint, string azureAadResourceId, string aadAuthority, string aadClientId, int cacheDurationInMins, string certificateThumbprint)
: this(azureSubscriptionId, azureManagementEndpoint, azureAadResourceId, aadAuthority, aadClientId, cacheDurationInMins, certificateThumbprint, new HttpClientFactory())
public AzureRegionUtility(string azureSubscriptionId, string azureManagementEndpoint, string azureAadResourceId, string aadAuthority, string aadClientId, int cacheDurationInMins, string certificateThumbprint, string userAssignedClientId)
: this(azureSubscriptionId, azureManagementEndpoint, azureAadResourceId, aadAuthority, aadClientId, cacheDurationInMins, certificateThumbprint, userAssignedClientId, new HttpClientFactory())
{
}

internal AzureRegionUtility(string azureSubscriptionId, string azureManagementEndpoint, string azureAadResourceId, string aadAuthority, string aadClientId, int cacheDurationInMins, string certificateThumbprint, IHttpClientFactory clientFactory)
internal AzureRegionUtility(string azureSubscriptionId, string azureManagementEndpoint, string azureAadResourceId, string aadAuthority, string aadClientId, int cacheDurationInMins, string certificateThumbprint, string userAssignedClientId, IHttpClientFactory clientFactory)
{
AzureSubscriptionId = azureSubscriptionId;
AzureManagementEndpoint = azureManagementEndpoint;
Expand All @@ -57,6 +58,7 @@ internal AzureRegionUtility(string azureSubscriptionId, string azureManagementEn
AadClientId = aadClientId;
CacheDurationInMins = cacheDurationInMins;
CertificateThumbprint = certificateThumbprint;
UserAssignedClientId = userAssignedClientId;
_httpClientFactory = clientFactory;
}

Expand Down Expand Up @@ -138,7 +140,7 @@ private async Task<string> GenerateAuthToken()
{
try
{
IConfidentialClientApplication app = GetOrCreateConfidentialApp(AadAuthority, AadClientId);
IConfidentialClientApplication app = GetOrCreateConfidentialApp(AadAuthority, AadClientId, UserAssignedClientId);

var authResult = await app.AcquireTokenForClient(new[] { $"{AzureManagementAadResourceId}/.default" }).ExecuteAsync();
return authResult.AccessToken;
Expand All @@ -149,7 +151,7 @@ private async Task<string> GenerateAuthToken()
}
}

private IConfidentialClientApplication GetOrCreateConfidentialApp(string authority, string clientId)
private IConfidentialClientApplication GetOrCreateConfidentialApp(string authority, string clientId, string userAssignedClientId)
{
try
{
Expand All @@ -169,10 +171,13 @@ private IConfidentialClientApplication GetOrCreateConfidentialApp(string authori
return confidentialClientApplication;
#else

var managedIdentityId = ManagedIdentityId.FromUserAssignedClientId(userAssignedClientId);
var credential = new ManagedIdentityCredential(managedIdentityId);

IConfidentialClientApplication clientApplicationWithMI = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority(new Uri(authority))
.WithClientAssertion((AssertionRequestOptions options) =>
{
var accessToken = new DefaultAzureCredential().GetToken(new TokenRequestContext(new string[] { $"api://AzureADTokenExchange/.default" }), CancellationToken.None);
var accessToken = credential.GetToken(new TokenRequestContext(new string[] { $"api://AzureADTokenExchange/.default" }), CancellationToken.None);
return Task.FromResult(accessToken.Token);
}).Build();
confidentialApps.TryAdd(confidentialAppCacheKey, clientApplicationWithMI);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="GeoCoordinate.NetCore" Version="1.0.0.1" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.60.3" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
<PackageReference Include="Microsoft.Identity.Web" Version="2.18.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.9.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Azure.Identity;
using Azure.Core;
using Azure.Identity;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.UnifiedPlatform.Service.Common.Helpers
{
[ExcludeFromCodeCoverage]
public class DefaultAzureCredentialProvider : IDefaultAzureCredentialProvider
{
public DefaultAzureCredential GetDefaultAzureCredential()
public TokenCredential GetDefaultAzureCredential(string userManagedIdentity)
{
return new DefaultAzureCredential();
return new VisualStudioCredential();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Azure.Identity;
using Azure.Core;
using Azure.Identity;

namespace Microsoft.UnifiedPlatform.Service.Common.Helpers
{
public interface IDefaultAzureCredentialProvider
{
DefaultAzureCredential GetDefaultAzureCredential();
TokenCredential GetDefaultAzureCredential(string userAssignedClientId="");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Azure.Core;
using Azure.Identity;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.UnifiedPlatform.Service.Common.Helpers
{
[ExcludeFromCodeCoverage]
public class UserAssignedIdentityCredentialProvider : IDefaultAzureCredentialProvider
{
public TokenCredential GetDefaultAzureCredential(string userAssignedClientId)
{
return new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(userAssignedClientId));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<ItemGroup>
<PackageReference Include="AppInsights.EnterpriseTelemetry" Version="1.0.2" />
<PackageReference Include="AppInsights.EnterpriseTelemetry.AspNetCore.Extension" Version="1.0.3" />
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Azure.Identity" Version="1.14.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.30" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.72.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="StackExchange.Redis" Version="2.0.601" />
<PackageReference Include="Azure.Data.Tables" Version="12.8.3" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
{
var secretProvider = new KeyVaultProvider(
Configuration["KeyVault:Name"],
new InMemoryCache(new MemoryCache(new MemoryCacheOptions())));
Configuration["Authentication:UserAssignedClientId"],
new InMemoryCache(new MemoryCache(new MemoryCacheOptions())));
var signingKey = secretProvider.GetSecret("Authentication-RedisCluster-Secret").Result;

options.TokenValidationParameters = new TokenValidationParameters()
Expand All @@ -63,7 +64,7 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
{
options.Audience = Configuration["Authentication:AAD:Audience"];
options.Authority = Configuration["Authentication:AAD:Authority"];

});

services.AddAuthorization(options =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
},
"LocalDebugging": {
"CertificateThumbprint": "27d6d3122675fcc4fe11e4977a540fc74169e1f1"
}
},
"UserAssignedClientId": "ddcbb4aa-01a9-46aa-8c11-03e1b789d9cd"
},
"Storage": {
"Name": "fxpstorageprodeus",
Expand Down
Loading
Loading