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 @@ -32,5 +32,6 @@ internal class AcquireTokenCommonParameters
public List<string> AdditionalCacheParameters { get; set; }
public SortedList<string, string> CacheKeyComponents { get; internal set; }
public string FmiPathSuffix { get; internal set; }
public string ClientAssertionFmiPath { get; internal set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Threading;

namespace Microsoft.Identity.Client
{
/// <summary>
Expand Down Expand Up @@ -38,5 +39,10 @@ public class AssertionRequestOptions {
/// (e.g. ManagedIdentityApplication or ConfidentialClientApplication), the same capabilities should be used there.
/// </summary>
public IEnumerable<string> ClientCapabilities { get; set; }

/// <summary>
/// FMI path to be used for client assertion. Tokens are assocaited with this path in the cache.
/// </summary>
public string ClientAssertionFmiPath { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.Identity.Client.OAuth2;

namespace Microsoft.Identity.Client.Extensibility
{
Expand Down Expand Up @@ -121,5 +122,79 @@ public static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheParamet
}
return builder;
}

/// <summary>
/// Specifies additional cache key components to use when caching and retrieving tokens.
/// </summary>
/// <param name="cacheKeyComponents">The list of additional cache key components.</param>
/// <param name="builder"></param>
/// <returns>The builder.</returns>
/// <remarks>
/// <list type="bullet">
/// <item><description>This api can be used to associate certificate key identifiers along with other keys with a particular token.</description></item>
/// <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>
/// </list>
/// </remarks>
internal static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheKeyComponents<T>(
this AbstractAcquireTokenParameterBuilder<T> builder,
IDictionary<string, string> cacheKeyComponents)
where T : AbstractAcquireTokenParameterBuilder<T>
{
if (cacheKeyComponents == null || cacheKeyComponents.Count == 0)
{
//no-op
return builder;
}

if (builder.CommonParameters.CacheKeyComponents == null)
{
builder.CommonParameters.CacheKeyComponents = new SortedList<string, string>(cacheKeyComponents);
}
else
{
foreach (var kvp in cacheKeyComponents)
{
// Key conflicts are not allowed, it is expected for this method to fail.
builder.CommonParameters.CacheKeyComponents.Add(kvp.Key, kvp.Value);
}
}

return builder;
}

/// <summary>
/// Specifies an FMI path to be used for the client assertion. This lets higher level APIs like Id.Web
/// provide credentials which are FMI sensitive.
/// Important: tokens are associated with the credential FMI path, which impacts cache lookups
/// This is an extensibility API and should not be used by applications.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="fmiPath">The FMI path to use for client assertion.</param>
/// <returns>The builder to chain the .With methods</returns>
/// <exception cref="ArgumentNullException">Thrown when fmiPath is null or whitespace.</exception>
public static AbstractAcquireTokenParameterBuilder<T> WithFmiPathForClientAssertion<T>(
this AbstractAcquireTokenParameterBuilder<T> builder,
string fmiPath)
where T : AbstractAcquireTokenParameterBuilder<T>
{
builder.ValidateUseOfExperimentalFeature();

if (string.IsNullOrWhiteSpace(fmiPath))
{
throw new ArgumentNullException(nameof(fmiPath));
}

builder.CommonParameters.ClientAssertionFmiPath = fmiPath;

// Add the fmi_path to the cache key so that it is used for cache lookups
var cacheKey = new SortedList<string, string>
{
{ "credential_fmi_path", fmiPath }
};

WithAdditionalCacheKeyComponents(builder, cacheKey);

return builder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Text;
using Microsoft.Identity.Client.Cache;
using Microsoft.Identity.Client.OAuth2;

namespace Microsoft.Identity.Client.Extensibility
{
Expand All @@ -15,42 +16,6 @@ namespace Microsoft.Identity.Client.Extensibility
/// </summary>
public static class AcquireTokenForClientBuilderExtensions
{
/// <summary>
/// Specifies additional cache key components to use when caching and retrieving tokens.
/// </summary>
/// <param name="cacheKeyComponents">The list of additional cache key components.</param>
/// <param name="builder"></param>
/// <returns>The builder.</returns>
/// <remarks>
/// <list type="bullet">
/// <item><description>This api can be used to associate certificate key identifiers along with other keys with a particular token.</description></item>
/// <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>
/// </list>
/// </remarks>
internal static AcquireTokenForClientParameterBuilder WithAdditionalCacheKeyComponents(this AcquireTokenForClientParameterBuilder builder,
IDictionary<string, string> cacheKeyComponents)
{
if (cacheKeyComponents == null || cacheKeyComponents.Count == 0)
{
//no-op
return builder;
}

if (builder.CommonParameters.CacheKeyComponents == null)
{
builder.CommonParameters.CacheKeyComponents = new SortedList<string, string>(cacheKeyComponents);
}
else
{
foreach (var kvp in cacheKeyComponents)
{
builder.CommonParameters.CacheKeyComponents.Add(kvp.Key, kvp.Value);
}
}

return builder;
}

/// <summary>
/// Binds the token to a key in the cache. L2 cache keys contain the key id.
/// No cryptographic operations is performed on the token.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Identity.Client.OAuth2;

namespace Microsoft.Identity.Client.Extensibility
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public async Task AddConfidentialClientParametersAsync(

//Set claims
assertionOptions.Claims = requestParameters.Claims;

//Set client assertion FMI path
assertionOptions.ClientAssertionFmiPath = requestParameters.ClientAssertionFmiPath;

// Delegate that uses AssertionRequestOptions
string signedAssertion = await _signedAssertionWithInfoDelegate(assertionOptions).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ public string LoginHint
public KeyValuePair<string, string>? CcsRoutingHint { get; set; }

public string FmiPathSuffix => _commonParameters.FmiPathSuffix;

public string ClientAssertionFmiPath => _commonParameters.ClientAssertionFmiPath;
#endregion

public void LogParameters()
Expand Down Expand Up @@ -206,6 +208,8 @@ public void LogParameters()
builder.AppendLine("UserAssertion set: " + (UserAssertion != null));
builder.AppendLine("LongRunningOboCacheKey set: " + !string.IsNullOrWhiteSpace(LongRunningOboCacheKey));
builder.AppendLine("Region configured: " + AppConfig.AzureRegion);
builder.AppendLine("FMI Path: " + FmiPathSuffix);
builder.AppendLine("Credential FMI Path: " + ClientAssertionFmiPath);

string messageWithPii = builder.ToString();

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

logger.InfoPii(messageWithPii, builder.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
Microsoft.Identity.Client.Utils.MacMainThreadScheduler
static Microsoft.Identity.Client.Extensibility.AbstractConfidentialClientAcquireTokenParameterBuilderExtension.WithFmiPathForClientAssertion<T>(this Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T> builder, string fmiPath) -> Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder<T>
static Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Instance() -> Microsoft.Identity.Client.Utils.MacMainThreadScheduler
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsCurrentlyOnMainThread() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func<System.Threading.Tasks.Task> asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.get -> string
Microsoft.Identity.Client.AssertionRequestOptions.ClientAssertionFmiPath.set -> void
Loading