Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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 @@ -143,7 +143,7 @@ public StorageCreationPropertiesBuilder CustomizeLockRetry(int lockRetryDelay, i
/// <param name="attribute2">Additional string attribute that will be used to decorate the secret</param>
/// <returns>The augmented builder</returns>
/// <remarks>
/// Attributes are used like scoping keys - their name and values must match the secrets in the KeyRing.
/// ExtraBodyParameters are used like scoping keys - their name and values must match the secrets in the KeyRing.
/// A suggested pattern is to use a product name (or a group of products) and a version. If you need to increment the version,
/// the secrets associated with the old version will be ignored.
/// </remarks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
using Microsoft.Identity.Client.Utils;
using Microsoft.Identity.Client.Extensibility;
using Microsoft.Identity.Client.OAuth2;
using System.Security.Cryptography;
using System.Text;

namespace Microsoft.Identity.Client
{
Expand Down Expand Up @@ -44,9 +46,9 @@ internal static AcquireTokenForClientParameterBuilder Create(

if (!string.IsNullOrEmpty(confidentialClientApplicationExecutor.ServiceBundle.Config.CertificateIdToAssociateWithToken))
{
builder.WithAdditionalCacheKeyComponents(new SortedList<string, string>
builder.WithAdditionalCacheKeyComponents(new SortedList<string, Func<CancellationToken, Task<string>>>
{
{ Constants.CertSerialNumber, confidentialClientApplicationExecutor.ServiceBundle.Config.CertificateIdToAssociateWithToken }
{ Constants.CertSerialNumber, (CancellationToken ct) => { return Task.FromResult(confidentialClientApplicationExecutor.ServiceBundle.Config.CertificateIdToAssociateWithToken); } }
});
}

Expand Down Expand Up @@ -113,6 +115,28 @@ public AcquireTokenForClientParameterBuilder WithMtlsProofOfPossession()
return this;
}

/// <summary>
/// Add extra body parameters to the token request. These parameters are added to the cache key to associate these parameters with the acquired token.
/// </summary>
/// <param name="extrabodyparams">List of additional body parameters</param>
/// <returns></returns>
public AcquireTokenForClientParameterBuilder WithExtraBodyParameters (Dictionary<string, Func<CancellationToken, Task<string>>> extrabodyparams)
{
this.OnBeforeTokenRequest(async (data) =>
{
foreach (var param in extrabodyparams)
{
if (param.Value != null)
{
data.BodyParameters.Add(param.Key, await param.Value(data.CancellationToken).ConfigureAwait(false));
}
}
});

this.WithAdditionalCacheKeyComponents(extrabodyparams);
return this;
}

/// <summary>
/// Please use WithAzureRegion on the ConfidentialClientApplicationBuilder object
/// </summary>
Expand Down Expand Up @@ -143,9 +167,9 @@ public AcquireTokenForClientParameterBuilder WithFmiPath(string pathSuffix)
throw new ArgumentNullException(nameof(pathSuffix));
}

var cacheKey = new SortedList<string, string>
var cacheKey = new SortedList<string, Func<CancellationToken, Task<string>>>
{
{ OAuth2Parameter.FmiPath, pathSuffix }
{ OAuth2Parameter.FmiPath, (CancellationToken ct) => {return Task.FromResult(pathSuffix);} }
};

this.WithAdditionalCacheKeyComponents(cacheKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
var requestParameters = await _clientApplicationBase.CreateRequestParametersAsync(
commonParameters,
requestContext,
_clientApplicationBase.UserTokenCacheInternal).ConfigureAwait(false);
_clientApplicationBase.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestParameters.SendX5C = silentParameters.SendX5C ?? false;

Expand All @@ -59,7 +60,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
var requestParameters = await _clientApplicationBase.CreateRequestParametersAsync(
commonParameters,
requestContext,
_clientApplicationBase.UserTokenCacheInternal).ConfigureAwait(false);
_clientApplicationBase.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestContext.Logger.Info(() => LogMessages.UsingXScopesForRefreshTokenRequest(commonParameters.Scopes.Count()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
AuthenticationRequestParameters requestParams = await _confidentialClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_confidentialClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_confidentialClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);
requestParams.SendX5C = authorizationCodeParameters.SendX5C ?? false;

var handler = new ConfidentialAuthCodeRequest(
Expand All @@ -60,7 +61,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
AuthenticationRequestParameters requestParams = await _confidentialClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_confidentialClientApplication.AppTokenCacheInternal).ConfigureAwait(false);
_confidentialClientApplication.AppTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestParams.SendX5C = clientParameters.SendX5C ?? false;

Expand All @@ -82,7 +84,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
AuthenticationRequestParameters requestParams = await _confidentialClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_confidentialClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_confidentialClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestParams.SendX5C = onBehalfOfParameters.SendX5C ?? false;
requestParams.UserAssertion = onBehalfOfParameters.UserAssertion;
Expand All @@ -106,7 +109,8 @@ public async Task<Uri> ExecuteAsync(
AuthenticationRequestParameters requestParameters = await _confidentialClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_confidentialClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_confidentialClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestParameters.Account = authorizationRequestUrlParameters.Account;
requestParameters.LoginHint = authorizationRequestUrlParameters.LoginHint;
Expand Down Expand Up @@ -142,7 +146,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
AuthenticationRequestParameters requestParams = await _confidentialClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_confidentialClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_confidentialClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestParams.SendX5C = usernamePasswordParameters.SendX5C ?? false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
var requestParams = await _managedIdentityApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_managedIdentityApplication.AppTokenCacheInternal).ConfigureAwait(false);
_managedIdentityApplication.AppTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

var handler = new ManagedIdentityAuthRequest(
ServiceBundle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
AuthenticationRequestParameters requestParams = await _publicClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_publicClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_publicClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

requestParams.LoginHint = interactiveParameters.LoginHint;
requestParams.Account = interactiveParameters.Account;
Expand All @@ -52,7 +53,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
var requestParams = await _publicClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_publicClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_publicClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

var handler = new DeviceCodeRequest(
ServiceBundle,
Expand All @@ -72,7 +74,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
var requestParams = await _publicClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_publicClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_publicClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

var handler = new IntegratedWindowsAuthRequest(
ServiceBundle,
Expand All @@ -92,7 +95,8 @@ public async Task<AuthenticationResult> ExecuteAsync(
var requestParams = await _publicClientApplication.CreateRequestParametersAsync(
commonParameters,
requestContext,
_publicClientApplication.UserTokenCacheInternal).ConfigureAwait(false);
_publicClientApplication.UserTokenCacheInternal,
cancellationToken).ConfigureAwait(false);

var handler = new UsernamePasswordRequest(
ServiceBundle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Identity.Client.AppConfig;
using Microsoft.Identity.Client.AuthScheme;
Expand All @@ -27,10 +28,10 @@ internal class AcquireTokenCommonParameters
public IAuthenticationOperation AuthenticationOperation { get; set; } = new BearerAuthenticationOperation();
public IDictionary<string, string> ExtraHttpHeaders { get; set; }
public PoPAuthenticationConfiguration PopAuthenticationConfiguration { get; set; }
public Func<OnBeforeTokenRequestData, Task> OnBeforeTokenRequestHandler { get; internal set; }
public IList<Func<OnBeforeTokenRequestData, Task>> OnBeforeTokenRequestHandler { get; internal set; }
public X509Certificate2 MtlsCertificate { get; internal set; }
public List<string> AdditionalCacheParameters { get; set; }
public SortedList<string, string> CacheKeyComponents { get; internal set; }
public SortedList<string, Func<CancellationToken, Task<string>>> CacheKeyComponents { get; internal set; }
public string FmiPathSuffix { get; internal set; }
public string ClientAssertionFmiPath { get; internal set; }
}
Expand Down
26 changes: 25 additions & 1 deletion src/client/Microsoft.Identity.Client/ApplicationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Identity.Client.ApiConfig.Parameters;
using Microsoft.Identity.Client.Internal;
Expand All @@ -27,12 +29,15 @@ internal ApplicationBase(ApplicationConfiguration config)
internal virtual async Task<AuthenticationRequestParameters> CreateRequestParametersAsync(
AcquireTokenCommonParameters commonParameters,
RequestContext requestContext,
ITokenCacheInternal cache)
ITokenCacheInternal cache,
CancellationToken cancellationToken)
{
Instance.Authority authority = await Instance.Authority.CreateAuthorityForRequestAsync(
requestContext,
commonParameters.AuthorityOverride).ConfigureAwait(false);

await InitializeCacheKeyComponentsAsync(cancellationToken, commonParameters.CacheKeyComponents).ConfigureAwait(false);

return new AuthenticationRequestParameters(
ServiceBundle,
cache,
Expand All @@ -41,6 +46,25 @@ internal virtual async Task<AuthenticationRequestParameters> CreateRequestParame
authority);
}

internal async Task<SortedList<string, string>> InitializeCacheKeyComponentsAsync(CancellationToken cancellationToken, SortedList<string, Func<CancellationToken, Task<string>>> cacheKeyComponents)
{
if (cacheKeyComponents != null && cacheKeyComponents.Count > 0)
{
var initializedCacheKeyComponents = new SortedList<string, string>();

foreach (var kvp in cacheKeyComponents)
{
if (kvp.Value != null)
{
initializedCacheKeyComponents.Add(kvp.Key, await kvp.Value.Invoke(cancellationToken).ConfigureAwait(false));
}
}
return initializedCacheKeyComponents;
}

return null;
}

internal static void GuardMobileFrameworks()
{
#if ANDROID || iOS || MAC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,10 @@ AcquireTokenByRefreshTokenParameterBuilder IByRefreshToken.AcquireTokenByRefresh
internal override async Task<AuthenticationRequestParameters> CreateRequestParametersAsync(
AcquireTokenCommonParameters commonParameters,
RequestContext requestContext,
ITokenCacheInternal cache)
ITokenCacheInternal cache,
CancellationToken cancellationToken)
{
AuthenticationRequestParameters requestParams = await base.CreateRequestParametersAsync(commonParameters, requestContext, cache).ConfigureAwait(false);
AuthenticationRequestParameters requestParams = await base.CreateRequestParametersAsync(commonParameters, requestContext, cache, cancellationToken).ConfigureAwait(false);
return requestParams;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Identity.Client.OAuth2;

Expand Down Expand Up @@ -34,7 +35,14 @@ public static AbstractAcquireTokenParameterBuilder<T> OnBeforeTokenRequest<T>(
throw new InvalidOperationException("Cannot set OnBeforeTokenRequest handler twice.");
}

builder.CommonParameters.OnBeforeTokenRequestHandler = onBeforeTokenRequestHandler;
if (builder.CommonParameters.OnBeforeTokenRequestHandler == null)
{
builder.CommonParameters.OnBeforeTokenRequestHandler = new List<Func<OnBeforeTokenRequestData, Task>> { onBeforeTokenRequestHandler };
}
else
{
builder.CommonParameters.OnBeforeTokenRequestHandler.Add(onBeforeTokenRequestHandler);
}

return builder;
}
Expand Down Expand Up @@ -80,7 +88,14 @@ public static AbstractAcquireTokenParameterBuilder<T> WithAuthenticationExtensio
throw new InvalidOperationException("Cannot set both an AuthenticaitonOperation and an OnBeforeTokenRequestHandler");
}

builder.CommonParameters.OnBeforeTokenRequestHandler = authenticationExtension.OnBeforeTokenRequestHandler;
if (builder.CommonParameters.OnBeforeTokenRequestHandler == null)
{
builder.CommonParameters.OnBeforeTokenRequestHandler = new List<Func<OnBeforeTokenRequestData, Task>> { authenticationExtension.OnBeforeTokenRequestHandler };
}
else
{
builder.CommonParameters.OnBeforeTokenRequestHandler.Add(authenticationExtension.OnBeforeTokenRequestHandler);
}

if (authenticationExtension.AuthenticationOperation != null)
builder.WithAuthenticationOperation(authenticationExtension.AuthenticationOperation);
Expand Down Expand Up @@ -137,7 +152,7 @@ public static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheParamet
/// </remarks>
internal static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheKeyComponents<T>(
this AbstractAcquireTokenParameterBuilder<T> builder,
IDictionary<string, string> cacheKeyComponents)
IDictionary<string, Func<CancellationToken, Task<string>>> cacheKeyComponents)
where T : AbstractAcquireTokenParameterBuilder<T>
{
if (cacheKeyComponents == null || cacheKeyComponents.Count == 0)
Expand All @@ -148,7 +163,7 @@ internal static AbstractAcquireTokenParameterBuilder<T> WithAdditionalCacheKeyCo

if (builder.CommonParameters.CacheKeyComponents == null)
{
builder.CommonParameters.CacheKeyComponents = new SortedList<string, string>(cacheKeyComponents);
builder.CommonParameters.CacheKeyComponents = new SortedList<string, Func<CancellationToken, Task<string>>>(cacheKeyComponents);
}
else
{
Expand Down Expand Up @@ -187,9 +202,9 @@ public static AbstractAcquireTokenParameterBuilder<T> WithFmiPathForClientAssert
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>
var cacheKey = new SortedList<string, Func<CancellationToken, Task<string>>>
{
{ "credential_fmi_path", fmiPath }
{ "credential_fmi_path", (CancellationToken ct) => Task.FromResult(fmiPath) }
};

WithAdditionalCacheKeyComponents(builder, cacheKey);
Expand Down
Loading