From cf29ae49d9c7a71dae26e96b441545aabe0fcc91 Mon Sep 17 00:00:00 2001 From: Keegan Caruso Date: Tue, 22 Aug 2023 11:38:46 -0700 Subject: [PATCH 1/2] Handle claims with multiple values --- .../TokenUtilities.cs | 4 +++ .../JsonWebTokenHandlerTests.cs | 34 +++++++++++++++++++ .../JwtSecurityTokenHandlerTests.cs | 34 +++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs b/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs index 8f75b45125..af38dffb7b 100644 --- a/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs +++ b/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs @@ -136,6 +136,10 @@ internal static IDictionary CreateDictionaryFromClaims( jsonClaimValue }; } + else if (existingValue is IList existingList) + { + existingList.Add(jsonClaimValue); + } } else { diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs index 6f65c78403..6f83496fa8 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerTests.cs @@ -28,6 +28,40 @@ namespace Microsoft.IdentityModel.JsonWebTokens.Tests { public class JsonWebTokenHandlerTests { + [Fact] + public void JsonWebTokenHandler_CreateToken_SameTypeMultipleValues() + { + var identity = new ClaimsIdentity("Test"); + + var claimValues = new List { "value1", "value2", "value3", "value4" }; + + foreach (var value in claimValues) + identity.AddClaim(new Claim("a", value)); + + var descriptor = new SecurityTokenDescriptor + { + SigningCredentials = new SigningCredentials(Default.AsymmetricSigningKey, SecurityAlgorithms.RsaSsaPssSha256), + Subject = identity + }; + + var handler = new JsonWebTokenHandler(); + + var token = handler.CreateToken(descriptor); + + var jwt = new JsonWebToken(token); + var claims = jwt.Claims.ToList(); + + int defaultClaimsCount = 3; + + Assert.Equal(defaultClaimsCount + claimValues.Count, claims.Count); + + var aTypeClaims = claims.Where(c => c.Type == "a").ToList(); + + Assert.Equal(4, aTypeClaims.Count); + + foreach (var value in claimValues) + Assert.NotNull(aTypeClaims.SingleOrDefault(c => c.Value == value)); + } // This test checks to make sure that the value of JsonWebTokenHandler.Base64UrlEncodedUnsignedJWSHeader has remained unchanged. [Fact] diff --git a/test/System.IdentityModel.Tokens.Jwt.Tests/JwtSecurityTokenHandlerTests.cs b/test/System.IdentityModel.Tokens.Jwt.Tests/JwtSecurityTokenHandlerTests.cs index f591bda0ab..02068e30d9 100644 --- a/test/System.IdentityModel.Tokens.Jwt.Tests/JwtSecurityTokenHandlerTests.cs +++ b/test/System.IdentityModel.Tokens.Jwt.Tests/JwtSecurityTokenHandlerTests.cs @@ -20,6 +20,40 @@ namespace System.IdentityModel.Tokens.Jwt.Tests public class JwtSecurityTokenHandlerTests { + [Fact] + public void JwtSecurityTokenHandler_CreateToken_SameTypeMultipleValues() + { + var identity = new ClaimsIdentity("Test"); + + var claimValues = new List { "value1", "value2", "value3", "value4" }; + + foreach (var value in claimValues) + identity.AddClaim(new Claim("a", value)); + + var descriptor = new SecurityTokenDescriptor + { + SigningCredentials = new SigningCredentials(Default.AsymmetricSigningKey, SecurityAlgorithms.RsaSsaPssSha256), + Subject = identity + }; + + var handler = new JwtSecurityTokenHandler(); + + var jwt = (JwtSecurityToken)handler.CreateToken(descriptor); + + var claims = jwt.Claims.ToList(); + + int defaultClaimsCount = 3; + + Assert.Equal(defaultClaimsCount + claimValues.Count, claims.Count); + + var aTypeClaims = claims.Where(c => c.Type == "a").ToList(); + + Assert.Equal(4, aTypeClaims.Count); + + foreach (var value in claimValues) + Assert.NotNull(aTypeClaims.SingleOrDefault(c => c.Value == value)); + } + [Theory, MemberData(nameof(CreateJWEWithPayloadStringTheoryData))] public void CreateJWEWithAdditionalHeaderClaims(CreateTokenTheoryData theoryData) { From 886277ac849a7fbe1800d229405729000c057f02 Mon Sep 17 00:00:00 2001 From: Keegan Caruso Date: Tue, 22 Aug 2023 13:21:23 -0700 Subject: [PATCH 2/2] refactor --- src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs b/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs index af38dffb7b..5007884972 100644 --- a/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs +++ b/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs @@ -128,17 +128,17 @@ internal static IDictionary CreateDictionaryFromClaims( // When the creating the JWT and a list is found, a JsonArray will be created. if (payload.TryGetValue(claim.Type, out object existingValue)) { - if (existingValue is not IList) + if (existingValue is IList existingList) + { + existingList.Add(jsonClaimValue); + } + else { payload[claim.Type] = new List { existingValue, jsonClaimValue - }; - } - else if (existingValue is IList existingList) - { - existingList.Add(jsonClaimValue); + }; } } else