Skip to content

Commit

Permalink
Updated audience matching method to remove allocations, return the ac…
Browse files Browse the repository at this point in the history
…tual audience that passed validation. Updated tests
  • Loading branch information
iNinja committed Jun 20, 2024
1 parent 64035fe commit 8bdc7f3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.IdentityModel.Abstractions;
using Microsoft.IdentityModel.Logging;

Expand Down Expand Up @@ -81,17 +79,7 @@ public static void ValidateAudience(IEnumerable<string> audiences, SecurityToken
new SecurityTokenInvalidAudienceException(LogHelper.FormatInvariant(LogMessages.IDX10206))
{ InvalidAudience = Utility.SerializeAsSingleCommaDelimitedString(audiences) });

// create enumeration of all valid audiences from validationParameters
IEnumerable<string> validationParametersAudiences;

if (validationParameters.ValidAudiences == null)
validationParametersAudiences = new[] { validationParameters.ValidAudience };
else if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience))
validationParametersAudiences = validationParameters.ValidAudiences;
else
validationParametersAudiences = validationParameters.ValidAudiences.Concat(new[] { validationParameters.ValidAudience });

if (AudienceIsValid(audiences, validationParameters, validationParametersAudiences))
if (AudienceIsValid(audiences, validationParameters))
return;

SecurityTokenInvalidAudienceException ex = new SecurityTokenInvalidAudienceException(
Expand Down Expand Up @@ -174,17 +162,7 @@ internal static AudienceValidationResult ValidateAudience(IEnumerable<string> au
typeof(SecurityTokenInvalidAudienceException),
new StackFrame(true)));

// create enumeration of all valid audiences from validationParameters
IEnumerable<string> validationParametersAudiences;

if (validationParameters.ValidAudiences == null)
validationParametersAudiences = new[] { validationParameters.ValidAudience };
else if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience))
validationParametersAudiences = validationParameters.ValidAudiences;
else
validationParametersAudiences = validationParameters.ValidAudiences.Concat(new[] { validationParameters.ValidAudience });

string? validAudience = AudienceIsValidReturning(audiences, validationParameters, validationParametersAudiences);
string? validAudience = AudienceIsValidReturning(audiences, validationParameters);
if (validAudience != null)
{
return new AudienceValidationResult(validAudience);
Expand All @@ -203,45 +181,72 @@ internal static AudienceValidationResult ValidateAudience(IEnumerable<string> au
new StackFrame(true)));
}

private static bool AudienceIsValid(IEnumerable<string> audiences, TokenValidationParameters validationParameters, IEnumerable<string> validationParametersAudiences)
private static bool AudienceIsValid(IEnumerable<string> audiences, TokenValidationParameters validationParameters)
{
return AudienceIsValidReturning(audiences, validationParameters) != null;
}

private static string? AudienceIsValidReturning(IEnumerable<string> audiences, TokenValidationParameters validationParameters)
{
return AudienceIsValidReturning(audiences, validationParameters, validationParametersAudiences) != null;
string? validAudience = null;
if (!string.IsNullOrWhiteSpace(validationParameters.ValidAudience))
validAudience = AudiencesMatchSingle(audiences, validationParameters.ValidAudience, validationParameters.IgnoreTrailingSlashWhenValidatingAudience);

if (validAudience == null && validationParameters.ValidAudiences != null)
validAudience = AudiencesMatchList(audiences, validationParameters.ValidAudiences, validationParameters.IgnoreTrailingSlashWhenValidatingAudience);

return validAudience;
}

private static string? AudiencesMatchSingle(IEnumerable<string> audiences, string validAudience, bool ignoreTrailingSlashWhenValidatingAudience)
{
foreach (string tokenAudience in audiences)
{
if (string.IsNullOrWhiteSpace(tokenAudience))
continue;

if (AudiencesMatch(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudience))
{
if (LogHelper.IsEnabled(EventLogLevel.Informational))
LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience));

return tokenAudience;
}
}

return null;
}

private static string? AudienceIsValidReturning(IEnumerable<string> audiences, TokenValidationParameters validationParameters, IEnumerable<string> validationParametersAudiences)
private static string? AudiencesMatchList(IEnumerable<string> audiences, IEnumerable<string> validAudiences, bool ignoreTrailingSlashWhenValidatingAudience)
{
foreach (string tokenAudience in audiences)
{
if (string.IsNullOrWhiteSpace(tokenAudience))
continue;

foreach (string validAudience in validationParametersAudiences)
foreach (string validAudience in validAudiences)
{
if (string.IsNullOrWhiteSpace(validAudience))
if (string.IsNullOrEmpty(validAudience))
continue;

if (AudiencesMatch(validationParameters, tokenAudience, validAudience))
if (AudiencesMatch(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudience))
{
if (LogHelper.IsEnabled(EventLogLevel.Informational))
LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience));

return validAudience;
return tokenAudience;
}
}
}

return null;
}
#nullable disable

private static bool AudiencesMatch(TokenValidationParameters validationParameters, string tokenAudience, string validAudience)
private static bool AudiencesMatch(bool ignoreTrailingSlashWhenValidatingAudience, string tokenAudience, string validAudience)
{
if (validAudience.Length == tokenAudience.Length)
{
if (string.Equals(validAudience, tokenAudience))
return true;
}
else if (validationParameters.IgnoreTrailingSlashWhenValidatingAudience && AudiencesMatchIgnoringTrailingSlash(tokenAudience, validAudience))
return string.Equals(validAudience, tokenAudience);
else if (ignoreTrailingSlashWhenValidatingAudience && AudiencesMatchIgnoringTrailingSlash(tokenAudience, validAudience))
return true;

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ public static TheoryData<AudienceValidationTheoryData> ValidateAudienceTheoryDat
Audiences = audiences1,
TestId = "ValidAudienceWithSlashTVPTrue",
ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 + "/" },
AudienceValidationResult = new AudienceValidationResult(audience1Slash)
AudienceValidationResult = new AudienceValidationResult(audience1)
},
new AudienceValidationTheoryData
{
Expand All @@ -407,7 +407,7 @@ public static TheoryData<AudienceValidationTheoryData> ValidateAudienceTheoryDat
Audiences = audiences1,
TestId = "ValidAudiencesWithSlashTVPTrue",
ValidationParameters = new TokenValidationParameters{ ValidAudiences = audiences1WithSlash },
AudienceValidationResult = new AudienceValidationResult(audience1Slash)
AudienceValidationResult = new AudienceValidationResult(audience1)
},
new AudienceValidationTheoryData
{
Expand Down Expand Up @@ -490,7 +490,7 @@ public static TheoryData<AudienceValidationTheoryData> ValidateAudienceTheoryDat
Audiences = audiences1WithSlash,
TestId = "TokenAudienceWithSlashTVPTrue",
ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 },
AudienceValidationResult = new AudienceValidationResult(audience1)
AudienceValidationResult = new AudienceValidationResult(audience1Slash)
},
new AudienceValidationTheoryData
{
Expand Down Expand Up @@ -535,7 +535,7 @@ public static TheoryData<AudienceValidationTheoryData> ValidateAudienceTheoryDat
Audiences = audiences1WithSlash,
TestId = "TokenAudiencesWithSlashTVPTrue",
ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 },
AudienceValidationResult = new AudienceValidationResult(audience1)
AudienceValidationResult = new AudienceValidationResult(audience1Slash)
},
new AudienceValidationTheoryData
{
Expand Down

0 comments on commit 8bdc7f3

Please sign in to comment.