Skip to content

Commit

Permalink
Change requests
Browse files Browse the repository at this point in the history
  • Loading branch information
kllysng committed Jun 4, 2024
1 parent 52da7cd commit 27d0708
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -382,54 +382,34 @@ private ConfigurationManager<OpenIdConnectConfiguration> CreateConfigManager(
}
}

private static bool IsValidIssuer(string validIssuerTemplate, string tenantId, string actualIssuer)
internal static bool IsValidIssuer(string validIssuerTemplate, string tenantId, string actualIssuer)
{
if (string.IsNullOrEmpty(validIssuerTemplate))
return false;

ReadOnlySpan<char> validIssuerTemplateSpan = validIssuerTemplate.AsSpan();
ReadOnlySpan<char> actualIssuerSpan = actualIssuer.AsSpan();
int indexOfTenantIdTemplate = validIssuerTemplate.IndexOf(TenantIdTemplate, StringComparison.Ordinal);
if (indexOfTenantIdTemplate >= 0)

if (indexOfTenantIdTemplate >= 0 && actualIssuer.Length > indexOfTenantIdTemplate)
{
return IssuersWithTemplatesAreEqual(validIssuerTemplate.AsSpan(), TenantIdTemplate.AsSpan(), indexOfTenantIdTemplate, actualIssuer.AsSpan(), tenantId.AsSpan());
// ensure the first part of the validIssuerTemplate matches the first part of actualIssuer
if (!validIssuerTemplateSpan.Slice(0, indexOfTenantIdTemplate).SequenceEqual(actualIssuerSpan.Slice(0, indexOfTenantIdTemplate)))
return false;

// ensure that actualIssuer contains the tenantId from indexOfTenantIdTemplate for the length of tenantId.Length
if (!actualIssuerSpan.Slice(indexOfTenantIdTemplate, tenantId.Length).SequenceEqual(tenantId.AsSpan()))
return false;

// ensure the second halves are equal
return validIssuerTemplateSpan.Slice(indexOfTenantIdTemplate + TenantIdTemplate.Length).SequenceEqual(actualIssuerSpan.Slice(indexOfTenantIdTemplate + tenantId.Length));
}
else
{
return validIssuerTemplate == actualIssuer;
return validIssuerTemplateSpan.SequenceEqual(actualIssuerSpan);
}
}

/// <summary>
/// Compare two Issuers with templates without string allocations.
/// This function replaces: issuer1.Replace(issuer1Template, tenantId) == issuer2
/// Example:
/// issuer1 = "https://login.microsoftonline.com/{tenantid}/v2.0"
/// issuer1Template = "{tenantid}"
/// issuer2 = "https://login.microsoftonline.com/12345678/v2.0"
/// tenantId = "12345678"
/// </summary>
internal static bool IssuersWithTemplatesAreEqual(ReadOnlySpan<char> issuer1, ReadOnlySpan<char> issuer1Template, int templateStartIndex, ReadOnlySpan<char> issuer2, ReadOnlySpan<char> tenantId)
{
if (templateStartIndex == -1)
return false;

// ensure the first part of the issuer1 matches the first part of issuer2
if (!issuer1.Slice(0, templateStartIndex).SequenceEqual(issuer2.Slice(0, templateStartIndex)))
return false;

// ensure that issuer2 contains the tenantId from templateStartIndex for the length of tenantId.Length
if (!issuer2.Slice(templateStartIndex, tenantId.Length).SequenceEqual(tenantId))
return false;

int secondHalfIssuer1StartIndex = templateStartIndex + issuer1Template.Length;
int secondHalfIssuer2StartIndex = templateStartIndex + tenantId.Length;

// ensure the second halves are equal
if (!issuer1.Slice(secondHalfIssuer1StartIndex).SequenceEqual(issuer2.Slice(secondHalfIssuer2StartIndex)))
return false;

return true;
}

private void SetEffectiveLKGIssuer(string aadIssuer, ProtocolVersion protocolVersion, TimeSpan lastKnownGoodLifetime)
{
var issuerLKG = new IssuerLastKnownGood
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ internal static bool ValidateIssuerSigningKey(SecurityKey securityKey, SecurityT
// 3. signing key issuers will never match sts.windows.net as v1 endpoint doesn't have issuers attached to keys
// v2TokenIssuer is the representation of Token.Issuer (if it was a v2 issuer)
int templateStartIndex = signingKeyIssuer.IndexOf(AadIssuerValidator.TenantIdTemplate, StringComparison.Ordinal);
if (!AadIssuerValidator.IssuersWithTemplatesAreEqual(signingKeyIssuer.AsSpan(), AadIssuerValidator.TenantIdTemplate.AsSpan(), templateStartIndex, tokenIssuer.AsSpan(), tenantIdFromToken.AsSpan())
&& !AadIssuerValidator.IssuersWithTemplatesAreEqual(signingKeyIssuer.AsSpan(), AadIssuerValidator.TenantIdTemplate.AsSpan(), templateStartIndex, openIdConnectConfiguration.Issuer == null ? [] : openIdConnectConfiguration.Issuer.AsSpan(), tenantIdFromToken.AsSpan()))
if (!AadIssuerValidator.IsValidIssuer(signingKeyIssuer, tenantIdFromToken, tokenIssuer)
&& !AadIssuerValidator.IsValidIssuer(signingKeyIssuer, tenantIdFromToken, openIdConnectConfiguration.Issuer == null ? string.Empty : openIdConnectConfiguration.Issuer))
{
string effectiveSigningKeyIssuer = templateStartIndex > -1 ? CreateIssuer(signingKeyIssuer, AadIssuerValidator.TenantIdTemplate, tenantIdFromToken, templateStartIndex) : signingKeyIssuer;
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogHelper.FormatInvariant(LogMessages.IDX40005, LogHelper.MarkAsNonPII(tokenIssuer), LogHelper.MarkAsNonPII(effectiveSigningKeyIssuer))));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using Xunit;

namespace Microsoft.IdentityModel.Validators.Tests
{
public class AadIssuerValidatorTests
{
[Fact]
public static void IssuersWithTemplatesAreEqualTests_EqualIssuers()
{
// arrange
var issuer1Template = "{tenantId}";
var issuer1 = ValidatorConstants.AadInstance + issuer1Template;
var issuer2Template = ValidatorConstants.TenantIdAsGuid;
var issuer2 = ValidatorConstants.AadInstance + issuer2Template;
int templateStartIndex = issuer1.IndexOf(issuer1Template);

// act
var result = AadIssuerValidator.IssuersWithTemplatesAreEqual(
issuer1.AsSpan(), issuer1Template.AsSpan(), templateStartIndex, issuer2.AsSpan(), issuer2Template.AsSpan());

// assert
Assert.True(result);
}

[Fact]
public static void IssuersWithTemplatesAreEqualTests_UnequalIssuers()
[Theory]
[InlineData(ValidatorConstants.AadInstance + AadIssuerValidator.TenantIdTemplate, ValidatorConstants.AadInstance + ValidatorConstants.TenantIdAsGuid, true)]
[InlineData(ValidatorConstants.AadInstancePPE + AadIssuerValidator.TenantIdTemplate, ValidatorConstants.AadInstance + ValidatorConstants.TenantIdAsGuid, false)]
[InlineData("", ValidatorConstants.AadInstance + ValidatorConstants.TenantIdAsGuid, false)]
[InlineData(ValidatorConstants.AadInstance + AadIssuerValidator.TenantIdTemplate, "", false)]
public static void IsValidIssuer_CanValidateTemplatedIssuers(string templatedIssuer, string issuer, bool expectedResult)
{
// arrange
var issuer1Template = "{tenantId}";
var issuer1 = ValidatorConstants.AadInstancePPE + issuer1Template;
var issuer2Template = ValidatorConstants.TenantIdAsGuid;
var issuer2 = ValidatorConstants.AadInstance + issuer2Template;
int templateStartIndex = issuer1.IndexOf(issuer1Template);

// act
var result = AadIssuerValidator.IssuersWithTemplatesAreEqual(
issuer1.AsSpan(), issuer1Template.AsSpan(), templateStartIndex, issuer2.AsSpan(), issuer2Template.AsSpan());
var result = AadIssuerValidator.IsValidIssuer(templatedIssuer, ValidatorConstants.TenantIdAsGuid, issuer);

// assert
Assert.False(result);
Assert.Equal(expectedResult, result);
}
}
}

0 comments on commit 27d0708

Please sign in to comment.