Skip to content

Commit

Permalink
ciam fix, initial commit (#2194)
Browse files Browse the repository at this point in the history
  • Loading branch information
jennyf19 authored Apr 12, 2023
1 parent 14be044 commit a2638c8
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<MicrosoftGraphVersion>4.34.0</MicrosoftGraphVersion>
<MicrosoftGraphBetaVersion>4.50.0-preview</MicrosoftGraphBetaVersion>
<MicrosoftExtensionsHttpVersion>3.1.3</MicrosoftExtensionsHttpVersion>
<MicrosoftIdentityAbstractions>3.0.1</MicrosoftIdentityAbstractions>
<MicrosoftIdentityAbstractions>3.1.0</MicrosoftIdentityAbstractions>
<!--CVE-2021-24112-->
<SystemDrawingCommon>4.7.2</SystemDrawingCommon>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.Identity.Web.TokenAcquisition/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public static class Constants
internal const string InvalidClient = "invalid_client";
internal const string InvalidKeyError = "AADSTS700027";
internal const string CiamAuthoritySuffix = ".ciamlogin.com";
internal const string TestSlice = "dc";

// Blazor challenge URI
internal const string BlazorChallengeUri = "MicrosoftIdentity/Account/Challenge?redirectUri=";
Expand Down
11 changes: 11 additions & 0 deletions src/Microsoft.Identity.Web.TokenAcquisition/MergedOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ internal static void UpdateMergedOptionsFromMicrosoftIdentityOptions(MicrosoftId
mergedOptions.ClientCredentialsUsingManagedIdentity ??= microsoftIdentityOptions.ClientCredentialsUsingManagedIdentity;

mergedOptions._confidentialClientApplicationOptions = null;

if ((mergedOptions.ExtraQueryParameters == null || !mergedOptions.ExtraQueryParameters.Any()) && microsoftIdentityOptions.ExtraQueryParameters != null)
{
mergedOptions.ExtraQueryParameters = microsoftIdentityOptions.ExtraQueryParameters;
}
}

internal static void UpdateMergedOptionsFromConfidentialClientApplicationOptions(ConfidentialClientApplicationOptions confidentialClientApplicationOptions, MergedOptions mergedOptions)
Expand Down Expand Up @@ -518,6 +523,12 @@ public static void UpdateMergedOptionsFromMicrosoftIdentityApplicationOptions(Mi
{
mergedOptions.TokenDecryptionCredentials = microsoftIdentityApplicationOptions.TokenDecryptionCredentials;
}

if ((mergedOptions.ExtraQueryParameters == null || !mergedOptions.ExtraQueryParameters.Any()) && microsoftIdentityApplicationOptions.ExtraQueryParameters != null)
{
mergedOptions.ExtraQueryParameters = microsoftIdentityApplicationOptions.ExtraQueryParameters;
}

}

private static IEnumerable<CredentialDescription> ComputeFromLegacyClientCredentials(MicrosoftIdentityOptions microsoftIdentityOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,10 @@ internal bool HasClientCredentials
/// which is the value used by Microsoft.Identity.Web.UI.
/// </summary>
public PathString? ErrorPath { get; set; } = Constants.ErrorPath;

/// <summary>
/// Sets query parameters for the query string in the HTTP request to the IdP.
/// </summary>
public IDictionary<string, string>? ExtraQueryParameters { get; set; }
}
}
46 changes: 39 additions & 7 deletions src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public async Task<AcquireTokenResult> AddAccountToCacheFromAuthorizationCodeAsyn
.WithCcsRoutingHint(backUpAuthRoutingHint)
.WithSpaAuthorizationCode(mergedOptions.WithSpaAuthCode);

if (mergedOptions.ExtraQueryParameters != null)
{
builder.WithExtraQueryParameters((Dictionary<string, string>)mergedOptions.ExtraQueryParameters);
}

if (!string.IsNullOrEmpty(authCodeRedemptionParameters.Tenant))
{
builder.WithTenantId(authCodeRedemptionParameters.Tenant);
Expand Down Expand Up @@ -352,9 +357,11 @@ public Task<AuthenticationResult> GetAuthenticationResultForAppAsync(

if (tokenAcquisitionOptions != null)
{
if (tokenAcquisitionOptions.ExtraQueryParameters != null)
var dict = MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);

if (dict != null)
{
builder.WithExtraQueryParameters(new Dictionary<string, string>(tokenAcquisitionOptions.ExtraQueryParameters));
builder.WithExtraQueryParameters(dict);
}
if (tokenAcquisitionOptions.ExtraHeadersParameters != null)
{
Expand Down Expand Up @@ -597,7 +604,7 @@ private IConfidentialClientApplication BuildConfidentialClientApplication(Merged
{
builder.WithClientCredentials(
mergedOptions.ClientCredentials!,
_logger,
_logger,
_credentialsLoader,
new CredentialSourceLoaderParameters(mergedOptions.ClientId!, authority));
}
Expand Down Expand Up @@ -707,9 +714,11 @@ private IConfidentialClientApplication BuildConfidentialClientApplication(Merged
}
if (tokenAcquisitionOptions != null)
{
if (tokenAcquisitionOptions.ExtraQueryParameters != null)
var dict = MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);

if (dict != null)
{
builder.WithExtraQueryParameters(new Dictionary<string, string>(tokenAcquisitionOptions.ExtraQueryParameters));
builder.WithExtraQueryParameters(dict);
}
if (tokenAcquisitionOptions.ExtraHeadersParameters != null)
{
Expand Down Expand Up @@ -842,9 +851,11 @@ private Task<AuthenticationResult> GetAuthenticationResultForWebAppWithAccountFr

if (tokenAcquisitionOptions != null)
{
if (tokenAcquisitionOptions.ExtraQueryParameters != null)
var dict = MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);

if (dict != null)
{
builder.WithExtraQueryParameters(new Dictionary<string, string>(tokenAcquisitionOptions.ExtraQueryParameters));
builder.WithExtraQueryParameters(dict);
}
if (tokenAcquisitionOptions.ExtraHeadersParameters != null)
{
Expand Down Expand Up @@ -884,6 +895,27 @@ private Task<AuthenticationResult> GetAuthenticationResultForWebAppWithAccountFr
return builder.ExecuteAsync(tokenAcquisitionOptions != null ? tokenAcquisitionOptions.CancellationToken : CancellationToken.None);
}

internal static Dictionary<string, string>? MergeExtraQueryParameters(
MergedOptions mergedOptions,
TokenAcquisitionOptions tokenAcquisitionOptions)
{
if (tokenAcquisitionOptions.ExtraQueryParameters != null)
{
var mergedDict = new Dictionary<string, string>(tokenAcquisitionOptions.ExtraQueryParameters);
if (mergedOptions.ExtraQueryParameters != null)
{
foreach (var pair in mergedOptions!.ExtraQueryParameters)
{
if (!mergedDict!.ContainsKey(pair.Key))
mergedDict.Add(pair.Key, pair.Value);
}
}
return mergedDict;
}

return (Dictionary<string, string>?)mergedOptions.ExtraQueryParameters;
}

protected static bool AcceptedTokenVersionMismatch(MsalUiRequiredException msalServiceException)
{
// Normally app developers should not make decisions based on the internal AAD code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ private static void AddMicrosoftIdentityWebApiImplementation(
if (mergedOptions.Authority != null)
{
mergedOptions.Authority = AuthorityHelpers.BuildCiamAuthorityIfNeeded(mergedOptions.Authority);
if (mergedOptions.ExtraQueryParameters != null)
{
options.MetadataAddress = mergedOptions.Authority + "/.well-known/openid-configuration?" + string.Join("&", mergedOptions.ExtraQueryParameters.Select(p => $"{p.Key}={p.Value}"));
}
}

MergedOptionsValidation.Validate(mergedOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ private static void AddMicrosoftIdentityWebAppInternal(
{
builder.Services.AddSingleton<IPostConfigureOptions<MicrosoftIdentityOptions>, MicrosoftIdentityOptionsMerger>();
}

builder.Services.Configure(openIdConnectScheme, configureMicrosoftIdentityOptions);
builder.Services.AddSingleton<IMergedOptionsStore, MergedOptionsStore>();
builder.Services.AddHttpClient();
Expand Down Expand Up @@ -293,6 +293,10 @@ private static void AddMicrosoftIdentityWebAppInternal(
if (mergedOptions.Authority != null)
{
mergedOptions.Authority = AuthorityHelpers.BuildCiamAuthorityIfNeeded(mergedOptions.Authority);
if (mergedOptions.ExtraQueryParameters != null)
{
options.MetadataAddress = mergedOptions.Authority + "/.well-known/openid-configuration?" + string.Join("&", mergedOptions.ExtraQueryParameters.Select(p => $"{p.Key}={p.Value}"));
}
}

PopulateOpenIdOptionsFromMergedOptions(options, mergedOptions);
Expand Down Expand Up @@ -375,6 +379,14 @@ private static void AddMicrosoftIdentityWebAppInternal(
additionClaims);
}

if (mergedOptions.ExtraQueryParameters != null)
{
foreach (var ExtraQP in mergedOptions.ExtraQueryParameters)
{
context.ProtocolMessage.SetParameter(ExtraQP.Key, ExtraQP.Value);
}
}

if (mergedOptions.IsB2C)
{
// When a new Challenge is returned using any B2C user flow different than susi, we must change
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using Microsoft.AspNetCore.Authentication;
Expand Down Expand Up @@ -231,5 +232,82 @@ public void TestParseAuthorityIfNecessary()
Assert.Equal(TestConstants.AadInstance, mergedOptions.Instance);
Assert.Equal(TestConstants.TenantIdAsGuid, mergedOptions.TenantId);
}

[Fact]
public void MergeExtraQueryParametersTest()
{
// Arrange
var mergedOptions = new MergedOptions
{
ExtraQueryParameters = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
}
};
var tokenAcquisitionOptions = new TokenAcquisitionOptions
{
ExtraQueryParameters = new Dictionary<string, string>
{
{ "key1", "newvalue1" },
{ "key3", "value3" }
}
};

// Act
var mergedDict = TokenAcquisition.MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);


// Assert
Assert.Equal(3, mergedDict!.Count);
Assert.Equal("newvalue1", mergedDict["key1"]);
Assert.Equal("value2", mergedDict["key2"]);
Assert.Equal("value3", mergedDict["key3"]);
}

[Fact]
public void MergeExtraQueryParameters_TokenAcquisitionOptionsNull_Test()
{
// Arrange
var mergedOptions = new MergedOptions
{
ExtraQueryParameters = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
}
};
var tokenAcquisitionOptions = new TokenAcquisitionOptions
{
ExtraQueryParameters = null,
};

// Act
var mergedDict = TokenAcquisition.MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);

// Assert
Assert.Equal("value1", mergedDict!["key1"]);
Assert.Equal("value2", mergedDict["key2"]);
}

[Fact]
public void MergeExtraQueryParameters_MergedOptionsNull_Test()
{
// Arrange
var mergedOptions = new MergedOptions
{
ExtraQueryParameters = null,
};
var tokenAcquisitionOptions = new TokenAcquisitionOptions
{
ExtraQueryParameters = null,
};

// Act
var mergedDict = TokenAcquisition.MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);

// Assert
Assert.Null(mergedDict);
}
}
}

0 comments on commit a2638c8

Please sign in to comment.