From e4959c24dc090a8aee29bb88d5e223264e5c192d Mon Sep 17 00:00:00 2001 From: Kelly Song Date: Tue, 16 Apr 2024 16:37:41 -0700 Subject: [PATCH 1/5] initial commit adding configurable token exchange url --- ...gnedAssertionFromManagedIdentityCredentialLoader.cs | 10 +++------- .../ManagedIdentityClientAssertion.cs | 7 +++++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs b/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs index 1067e1af4..7f54e2e0a 100644 --- a/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs +++ b/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs @@ -1,14 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Collections.Generic; -using System.Net; -using System.Text; -using Azure.Identity; using System.Threading; -using Microsoft.Identity.Abstractions; using System.Threading.Tasks; +using Azure.Identity; +using Microsoft.Identity.Abstractions; namespace Microsoft.Identity.Web { @@ -23,7 +19,7 @@ public async Task LoadIfNeededAsync(CredentialDescription credentialDescription, ManagedIdentityClientAssertion? managedIdentityClientAssertion = credentialDescription.CachedValue as ManagedIdentityClientAssertion; if (credentialDescription.CachedValue == null) { - managedIdentityClientAssertion = new ManagedIdentityClientAssertion(credentialDescription.ManagedIdentityClientId); + managedIdentityClientAssertion = new ManagedIdentityClientAssertion(credentialDescription.ManagedIdentityClientId/*, credentialDescription.tokenExchangeUrl*/); // TODO: update value upon abstractions release } try { diff --git a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs index 80fea702b..d32a151e7 100644 --- a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs +++ b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs @@ -14,12 +14,14 @@ namespace Microsoft.Identity.Web public class ManagedIdentityClientAssertion : ClientAssertionProviderBase { private readonly TokenCredential _credential; + private readonly string _tokenExchangeUrl; /// /// See https://aka.ms/ms-id-web/certificateless. /// /// Optional ClientId of the Managed Identity or Workload Identity - public ManagedIdentityClientAssertion(string? managedIdentityClientId) + /// Optional token exchange resource url. Default value is "api://AzureADTokenExchange/.default". + public ManagedIdentityClientAssertion(string? managedIdentityClientId, string tokenExchangeUrl = "api://AzureADTokenExchange/.default") { _credential = new DefaultAzureCredential( new DefaultAzureCredentialOptions @@ -34,6 +36,7 @@ public ManagedIdentityClientAssertion(string? managedIdentityClientId) ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = true }); + _tokenExchangeUrl = tokenExchangeUrl; } /// @@ -44,7 +47,7 @@ public ManagedIdentityClientAssertion(string? managedIdentityClientId) protected override async Task GetClientAssertion(CancellationToken cancellationToken) { var result = await _credential.GetTokenAsync( - new TokenRequestContext(["api://AzureADTokenExchange/.default"], null), + new TokenRequestContext([_tokenExchangeUrl], null), cancellationToken).ConfigureAwait(false); return new ClientAssertion(result.Token, result.ExpiresOn); } From 5f144f330d66128cd2e30c6a4296e70bd73d19ea Mon Sep 17 00:00:00 2001 From: kellyyangsong <69649063+kellyyangsong@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:17:29 -0700 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Jean-Marc Prieur --- .../ManagedIdentityClientAssertion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs index d32a151e7..df08efb31 100644 --- a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs +++ b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs @@ -21,7 +21,7 @@ public class ManagedIdentityClientAssertion : ClientAssertionProviderBase /// /// Optional ClientId of the Managed Identity or Workload Identity /// Optional token exchange resource url. Default value is "api://AzureADTokenExchange/.default". - public ManagedIdentityClientAssertion(string? managedIdentityClientId, string tokenExchangeUrl = "api://AzureADTokenExchange/.default") + public ManagedIdentityClientAssertion(string? managedIdentityClientId, string tokenExchangeUrl = "api://AzureADTokenExchange") { _credential = new DefaultAzureCredential( new DefaultAzureCredentialOptions @@ -47,7 +47,7 @@ public ManagedIdentityClientAssertion(string? managedIdentityClientId, string to protected override async Task GetClientAssertion(CancellationToken cancellationToken) { var result = await _credential.GetTokenAsync( - new TokenRequestContext([_tokenExchangeUrl], null), + new TokenRequestContext([_tokenExchangeUrl+"./default"], null), cancellationToken).ConfigureAwait(false); return new ClientAssertion(result.Token, result.ExpiresOn); } From 238adadd634d64553d9d21549140f9b07f80293a Mon Sep 17 00:00:00 2001 From: Kelly Song Date: Thu, 18 Apr 2024 11:48:51 -0700 Subject: [PATCH 3/5] use abstractions 5.2.0 --- Directory.Build.props | 2 +- changelog.md | 4 ++++ ...nedAssertionFromManagedIdentityCredentialLoader.cs | 2 +- .../CertificatelessConstants.cs | 11 +++++++++++ .../ManagedIdentityClientAssertion.cs | 5 +++-- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 src/Microsoft.Identity.Web.Certificateless/CertificatelessConstants.cs diff --git a/Directory.Build.props b/Directory.Build.props index e5e2d4ac7..be8e3cfb5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -87,7 +87,7 @@ 4.36.0 4.57.0-preview 3.1.3 - 5.1.0 + 5.2.0 9.0.0-preview.2.24128.5 9.0.0-preview.2.24128.4 diff --git a/changelog.md b/changelog.md index 316d8c7d1..ff9e003e2 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +Pending Next Release +========= +- Update to Microsoft.Identity.Abstractions 5.2.0 + 2.17.2 ========= diff --git a/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs b/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs index 7f54e2e0a..84dad53af 100644 --- a/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs +++ b/src/Microsoft.Identity.Web.Certificate/SignedAssertionFromManagedIdentityCredentialLoader.cs @@ -19,7 +19,7 @@ public async Task LoadIfNeededAsync(CredentialDescription credentialDescription, ManagedIdentityClientAssertion? managedIdentityClientAssertion = credentialDescription.CachedValue as ManagedIdentityClientAssertion; if (credentialDescription.CachedValue == null) { - managedIdentityClientAssertion = new ManagedIdentityClientAssertion(credentialDescription.ManagedIdentityClientId/*, credentialDescription.tokenExchangeUrl*/); // TODO: update value upon abstractions release + managedIdentityClientAssertion = new ManagedIdentityClientAssertion(credentialDescription.ManagedIdentityClientId, credentialDescription.TokenExchangeUrl); } try { diff --git a/src/Microsoft.Identity.Web.Certificateless/CertificatelessConstants.cs b/src/Microsoft.Identity.Web.Certificateless/CertificatelessConstants.cs new file mode 100644 index 000000000..15b0e749b --- /dev/null +++ b/src/Microsoft.Identity.Web.Certificateless/CertificatelessConstants.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Identity.Web.Certificateless +{ + internal class CertificatelessConstants + { + // Managed Identity Federated Identity Credential + internal const string DefaultTokenExchangeUrl = "api://AzureADTokenExchange"; + } +} diff --git a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs index df08efb31..2187f41e8 100644 --- a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs +++ b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Azure.Core; using Azure.Identity; +using Microsoft.Identity.Web.Certificateless; namespace Microsoft.Identity.Web { @@ -21,7 +22,7 @@ public class ManagedIdentityClientAssertion : ClientAssertionProviderBase /// /// Optional ClientId of the Managed Identity or Workload Identity /// Optional token exchange resource url. Default value is "api://AzureADTokenExchange/.default". - public ManagedIdentityClientAssertion(string? managedIdentityClientId, string tokenExchangeUrl = "api://AzureADTokenExchange") + public ManagedIdentityClientAssertion(string? managedIdentityClientId, string tokenExchangeUrl = CertificatelessConstants.DefaultTokenExchangeUrl) { _credential = new DefaultAzureCredential( new DefaultAzureCredentialOptions @@ -36,7 +37,7 @@ public ManagedIdentityClientAssertion(string? managedIdentityClientId, string to ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = true }); - _tokenExchangeUrl = tokenExchangeUrl; + _tokenExchangeUrl = tokenExchangeUrl ?? CertificatelessConstants.DefaultTokenExchangeUrl; } /// From 2eead72fdc6fce0247d8ee850f5d02ebd63b5797 Mon Sep 17 00:00:00 2001 From: Kelly Song Date: Thu, 18 Apr 2024 13:07:58 -0700 Subject: [PATCH 4/5] separate ctor overload --- .../ManagedIdentityClientAssertion.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs index 2187f41e8..2aad3fa0a 100644 --- a/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs +++ b/src/Microsoft.Identity.Web.Certificateless/ManagedIdentityClientAssertion.cs @@ -21,8 +21,7 @@ public class ManagedIdentityClientAssertion : ClientAssertionProviderBase /// See https://aka.ms/ms-id-web/certificateless. /// /// Optional ClientId of the Managed Identity or Workload Identity - /// Optional token exchange resource url. Default value is "api://AzureADTokenExchange/.default". - public ManagedIdentityClientAssertion(string? managedIdentityClientId, string tokenExchangeUrl = CertificatelessConstants.DefaultTokenExchangeUrl) + public ManagedIdentityClientAssertion(string? managedIdentityClientId) { _credential = new DefaultAzureCredential( new DefaultAzureCredentialOptions @@ -37,6 +36,16 @@ public ManagedIdentityClientAssertion(string? managedIdentityClientId, string to ExcludeVisualStudioCodeCredential = true, ExcludeVisualStudioCredential = true }); + _tokenExchangeUrl = CertificatelessConstants.DefaultTokenExchangeUrl; + } + + /// + /// See https://aka.ms/ms-id-web/certificateless. + /// + /// Optional ClientId of the Managed Identity or Workload Identity + /// Optional token exchange resource url. Default value is "api://AzureADTokenExchange/.default". + public ManagedIdentityClientAssertion(string? managedIdentityClientId, string? tokenExchangeUrl) : this (managedIdentityClientId) + { _tokenExchangeUrl = tokenExchangeUrl ?? CertificatelessConstants.DefaultTokenExchangeUrl; } From e0b2d5926ad5bb87fabfe69e2ebc6e406301b613 Mon Sep 17 00:00:00 2001 From: Kelly Song Date: Thu, 18 Apr 2024 14:04:50 -0700 Subject: [PATCH 5/5] add msi fic support to changelog --- changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog.md b/changelog.md index ff9e003e2..8f537ed89 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,9 @@ Pending Next Release ========= - Update to Microsoft.Identity.Abstractions 5.2.0 +### New features +- Added support for Managed Identity Federated Identity Credential. See issue [2749](https://github.com/AzureAD/microsoft-identity-web/issues/2749) for details. + 2.17.2 =========