Skip to content

Commit 6eb49ca

Browse files
authored
Fix #5342 - add an extensibility API - WithFmiPathForClientAssertion … (#5347)
Fix for #5342 - add WithClientAssertionFmiPath
1 parent 97879bf commit 6eb49ca

15 files changed

+453
-101
lines changed

src/client/Microsoft.Identity.Client/ApiConfig/Parameters/AcquireTokenCommonParameters.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ internal class AcquireTokenCommonParameters
3232
public List<string> AdditionalCacheParameters { get; set; }
3333
public SortedList<string, string> CacheKeyComponents { get; internal set; }
3434
public string FmiPathSuffix { get; internal set; }
35+
public string ClientAssertionFmiPath { get; internal set; }
3536
}
3637
}

src/client/Microsoft.Identity.Client/AppConfig/AssertionRequestOptions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.Threading;
6+
67
namespace Microsoft.Identity.Client
78
{
89
/// <summary>
@@ -38,5 +39,10 @@ public class AssertionRequestOptions {
3839
/// (e.g. ManagedIdentityApplication or ConfidentialClientApplication), the same capabilities should be used there.
3940
/// </summary>
4041
public IEnumerable<string> ClientCapabilities { get; set; }
42+
43+
/// <summary>
44+
/// FMI path to be used for client assertion. Tokens are assocaited with this path in the cache.
45+
/// </summary>
46+
public string ClientAssertionFmiPath { get; set; }
4147
}
4248
}

src/client/Microsoft.Identity.Client/Extensibility/AbstractConfidentialClientAcquireTokenParameterBuilderExtension.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Runtime.CompilerServices;
88
using System.Threading.Tasks;
9+
using Microsoft.Identity.Client.OAuth2;
910

1011
namespace Microsoft.Identity.Client.Extensibility
1112
{
@@ -121,5 +122,79 @@ public static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheParamet
121122
}
122123
return builder;
123124
}
125+
126+
/// <summary>
127+
/// Specifies additional cache key components to use when caching and retrieving tokens.
128+
/// </summary>
129+
/// <param name="cacheKeyComponents">The list of additional cache key components.</param>
130+
/// <param name="builder"></param>
131+
/// <returns>The builder.</returns>
132+
/// <remarks>
133+
/// <list type="bullet">
134+
/// <item><description>This api can be used to associate certificate key identifiers along with other keys with a particular token.</description></item>
135+
/// <item><description>In order for the tokens to be successfully retrieved from the cache, all components used to cache the token must be provided.</description></item>
136+
/// </list>
137+
/// </remarks>
138+
internal static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheKeyComponents<T>(
139+
this AbstractAcquireTokenParameterBuilder<T> builder,
140+
IDictionary<string, string> cacheKeyComponents)
141+
where T : AbstractAcquireTokenParameterBuilder<T>
142+
{
143+
if (cacheKeyComponents == null || cacheKeyComponents.Count == 0)
144+
{
145+
//no-op
146+
return builder;
147+
}
148+
149+
if (builder.CommonParameters.CacheKeyComponents == null)
150+
{
151+
builder.CommonParameters.CacheKeyComponents = new SortedList<string, string>(cacheKeyComponents);
152+
}
153+
else
154+
{
155+
foreach (var kvp in cacheKeyComponents)
156+
{
157+
// Key conflicts are not allowed, it is expected for this method to fail.
158+
builder.CommonParameters.CacheKeyComponents.Add(kvp.Key, kvp.Value);
159+
}
160+
}
161+
162+
return builder;
163+
}
164+
165+
/// <summary>
166+
/// Specifies an FMI path to be used for the client assertion. This lets higher level APIs like Id.Web
167+
/// provide credentials which are FMI sensitive.
168+
/// Important: tokens are associated with the credential FMI path, which impacts cache lookups
169+
/// This is an extensibility API and should not be used by applications.
170+
/// </summary>
171+
/// <param name="builder">The builder.</param>
172+
/// <param name="fmiPath">The FMI path to use for client assertion.</param>
173+
/// <returns>The builder to chain the .With methods</returns>
174+
/// <exception cref="ArgumentNullException">Thrown when fmiPath is null or whitespace.</exception>
175+
public static AbstractAcquireTokenParameterBuilder<T> WithFmiPathForClientAssertion<T>(
176+
this AbstractAcquireTokenParameterBuilder<T> builder,
177+
string fmiPath)
178+
where T : AbstractAcquireTokenParameterBuilder<T>
179+
{
180+
builder.ValidateUseOfExperimentalFeature();
181+
182+
if (string.IsNullOrWhiteSpace(fmiPath))
183+
{
184+
throw new ArgumentNullException(nameof(fmiPath));
185+
}
186+
187+
builder.CommonParameters.ClientAssertionFmiPath = fmiPath;
188+
189+
// Add the fmi_path to the cache key so that it is used for cache lookups
190+
var cacheKey = new SortedList<string, string>
191+
{
192+
{ "credential_fmi_path", fmiPath }
193+
};
194+
195+
WithAdditionalCacheKeyComponents(builder, cacheKey);
196+
197+
return builder;
198+
}
124199
}
125200
}

src/client/Microsoft.Identity.Client/Extensibility/AcquireTokenForClientBuilderExtensions.cs

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Diagnostics.CodeAnalysis;
88
using System.Text;
99
using Microsoft.Identity.Client.Cache;
10+
using Microsoft.Identity.Client.OAuth2;
1011

1112
namespace Microsoft.Identity.Client.Extensibility
1213
{
@@ -15,42 +16,6 @@ namespace Microsoft.Identity.Client.Extensibility
1516
/// </summary>
1617
public static class AcquireTokenForClientBuilderExtensions
1718
{
18-
/// <summary>
19-
/// Specifies additional cache key components to use when caching and retrieving tokens.
20-
/// </summary>
21-
/// <param name="cacheKeyComponents">The list of additional cache key components.</param>
22-
/// <param name="builder"></param>
23-
/// <returns>The builder.</returns>
24-
/// <remarks>
25-
/// <list type="bullet">
26-
/// <item><description>This api can be used to associate certificate key identifiers along with other keys with a particular token.</description></item>
27-
/// <item><description>In order for the tokens to be successfully retrieved from the cache, all components used to cache the token must be provided.</description></item>
28-
/// </list>
29-
/// </remarks>
30-
internal static AcquireTokenForClientParameterBuilder WithAdditionalCacheKeyComponents(this AcquireTokenForClientParameterBuilder builder,
31-
IDictionary<string, string> cacheKeyComponents)
32-
{
33-
if (cacheKeyComponents == null || cacheKeyComponents.Count == 0)
34-
{
35-
//no-op
36-
return builder;
37-
}
38-
39-
if (builder.CommonParameters.CacheKeyComponents == null)
40-
{
41-
builder.CommonParameters.CacheKeyComponents = new SortedList<string, string>(cacheKeyComponents);
42-
}
43-
else
44-
{
45-
foreach (var kvp in cacheKeyComponents)
46-
{
47-
builder.CommonParameters.CacheKeyComponents.Add(kvp.Key, kvp.Value);
48-
}
49-
}
50-
51-
return builder;
52-
}
53-
5419
/// <summary>
5520
/// Binds the token to a key in the cache. L2 cache keys contain the key id.
5621
/// No cryptographic operations is performed on the token.

src/client/Microsoft.Identity.Client/Extensibility/AcquireTokenOnBehalfOfParameterBuilderExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
using System;
45
using System.Collections.Generic;
56
using System.ComponentModel;
7+
using Microsoft.Identity.Client.OAuth2;
68

79
namespace Microsoft.Identity.Client.Extensibility
810
{

src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionDelegateClientCredential.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ public async Task AddConfidentialClientParametersAsync(
6666

6767
//Set claims
6868
assertionOptions.Claims = requestParameters.Claims;
69+
70+
//Set client assertion FMI path
71+
assertionOptions.ClientAssertionFmiPath = requestParameters.ClientAssertionFmiPath;
6972

7073
// Delegate that uses AssertionRequestOptions
7174
string signedAssertion = await _signedAssertionWithInfoDelegate(assertionOptions).ConfigureAwait(false);

src/client/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ public string LoginHint
177177
public KeyValuePair<string, string>? CcsRoutingHint { get; set; }
178178

179179
public string FmiPathSuffix => _commonParameters.FmiPathSuffix;
180+
181+
public string ClientAssertionFmiPath => _commonParameters.ClientAssertionFmiPath;
180182
#endregion
181183

182184
public void LogParameters()
@@ -206,6 +208,8 @@ public void LogParameters()
206208
builder.AppendLine("UserAssertion set: " + (UserAssertion != null));
207209
builder.AppendLine("LongRunningOboCacheKey set: " + !string.IsNullOrWhiteSpace(LongRunningOboCacheKey));
208210
builder.AppendLine("Region configured: " + AppConfig.AzureRegion);
211+
builder.AppendLine("FMI Path: " + FmiPathSuffix);
212+
builder.AppendLine("Credential FMI Path: " + ClientAssertionFmiPath);
209213

210214
string messageWithPii = builder.ToString();
211215

@@ -226,6 +230,8 @@ public void LogParameters()
226230
builder.AppendLine("UserAssertion set: " + (UserAssertion != null));
227231
builder.AppendLine("LongRunningOboCacheKey set: " + !string.IsNullOrWhiteSpace(LongRunningOboCacheKey));
228232
builder.AppendLine("Region configured: " + AppConfig.AzureRegion);
233+
builder.AppendLine("FMI Path: " + FmiPathSuffix);
234+
builder.AppendLine("Credential FMI Path: " + ClientAssertionFmiPath);
229235

230236
logger.InfoPii(messageWithPii, builder.ToString());
231237
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
2+
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
23
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
34
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
45
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
56
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
67
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
78
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
89
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
9-
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
10+
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
11+
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
12+
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
2+
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
23
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
34
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
45
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
56
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
67
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
78
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
89
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
9-
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
10+
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
11+
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
12+
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
2+
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
23
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
34
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
45
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
56
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
67
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
78
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
89
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
9-
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
10+
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
11+
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
12+
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void

0 commit comments

Comments
 (0)