Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with 6x for bool claims #2367

Merged
merged 2 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 9 additions & 3 deletions src/Microsoft.IdentityModel.JsonWebTokens/Json/JsonClaimSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ internal static void CreateClaimFromObject(List<Claim> claims, string claimType,
else if (value is long l)
claims.Add(new Claim(claimType, l.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer64, issuer, issuer));
else if (value is bool b)
claims.Add(new Claim(claimType, b.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Boolean, issuer, issuer));
{
// Can't just use ToString or bools will get encoded as True/False instead of true/false.
if (b)
claims.Add(new Claim(claimType, "true", ClaimValueTypes.Boolean, issuer, issuer));
else
claims.Add(new Claim(claimType, "false", ClaimValueTypes.Boolean, issuer, issuer));
}
else if (value is double d)
claims.Add(new Claim(claimType, d.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Double, issuer, issuer));
else if (value is DateTime dt)
Expand Down Expand Up @@ -108,9 +114,9 @@ internal static Claim CreateClaimFromJsonElement(string claimType, string issuer
else if (jsonElement.ValueKind == JsonValueKind.Object)
return new Claim(claimType, jsonElement.ToString(), JsonClaimValueTypes.Json, issuer, issuer);
else if (jsonElement.ValueKind == JsonValueKind.False)
return new Claim(claimType, "False", ClaimValueTypes.Boolean, issuer, issuer);
return new Claim(claimType, "false", ClaimValueTypes.Boolean, issuer, issuer);
else if (jsonElement.ValueKind == JsonValueKind.True)
return new Claim(claimType, "True", ClaimValueTypes.Boolean, issuer, issuer);
return new Claim(claimType, "true", ClaimValueTypes.Boolean, issuer, issuer);
else if (jsonElement.ValueKind == JsonValueKind.Number)
{
if (jsonElement.TryGetInt32(out int i))
Expand Down
15 changes: 15 additions & 0 deletions src/System.IdentityModel.Tokens.Jwt/JwtPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,14 @@ public virtual IEnumerable<Claim> Claims
}
else if (keyValuePair.Value is DateTime dateTime)
claims.Add(new Claim(keyValuePair.Key, dateTime.ToString("o", CultureInfo.InvariantCulture), ClaimValueTypes.DateTime, issuer, issuer));
else if (keyValuePair.Value is bool boolValue)
{
// Can't just use ToString or bools will get encoded as True/False instead of true/false.
if (boolValue)
claims.Add(new Claim(keyValuePair.Key, "true", ClaimValueTypes.Boolean, issuer, issuer));
else
claims.Add(new Claim(keyValuePair.Key, "false", ClaimValueTypes.Boolean, issuer, issuer));
}
else if (keyValuePair.Value != null)
claims.Add(new Claim(keyValuePair.Key, keyValuePair.Value.ToString(), GetClaimValueType(keyValuePair.Value), issuer, issuer));
}
Expand All @@ -557,6 +565,13 @@ private void AddListofObjects(string key, IEnumerable<object> objects, List<Clai
{
if (obj is string claimValue)
claims.Add(new Claim(key, claimValue, ClaimValueTypes.String, issuer, issuer));
else if (obj is bool boolValue)
{
if (boolValue)
claims.Add(new Claim(key, "true", ClaimValueTypes.Boolean, issuer, issuer));
else
claims.Add(new Claim(key, "false", ClaimValueTypes.Boolean, issuer, issuer));
}
else if (obj is DateTime dateTimeValue)
claims.Add(new Claim(key, dateTimeValue.ToString("o", CultureInfo.InvariantCulture), ClaimValueTypes.DateTime, issuer, issuer));
else if (obj is JsonElement jsonElement)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,39 @@ public class JsonWebTokenTests
new Claim("float", "42", ClaimValueTypes.Integer32, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
new Claim("integer", "42", ClaimValueTypes.Integer32, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
new Claim("nill", "", JsonClaimValueTypes.JsonNull, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
new Claim("bool", "True", ClaimValueTypes.Boolean, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
new Claim("bool", "true", ClaimValueTypes.Boolean, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
new Claim("dateTime", dateTime.ToString(), ClaimValueTypes.String, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
new Claim("dateTimeIso8061", dateTime.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture), ClaimValueTypes.DateTime, "LOCAL AUTHORITY", "LOCAL AUTHORITY"),
};

[Fact]
public void BoolClaimsEncodedAsExpected()
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(new string('a', 128)));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var claims = new[] { new Claim("testClaim", "true", ClaimValueTypes.Boolean), new Claim("testClaim2", "True", ClaimValueTypes.Boolean) };
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
{
SigningCredentials = creds,
Subject = new ClaimsIdentity(claims),
Expires = (new DateTime(2038, 1, 20)).ToUniversalTime(),
};

JsonWebTokenHandler handler = new();
string jwt = handler.CreateToken(tokenDescriptor);
JsonWebToken jsonWebToken = new JsonWebToken(jwt);

var claimSet = jsonWebToken.Claims;

// Will throw if can't find.
var testClaim = claimSet.First(c => c.Type == "testClaim");
Assert.Equal("true", testClaim.Value);

var testClaim2 = claimSet.First(c => c.Type == "testClaim2");
Assert.Equal("true", testClaim2.Value);
}

[Fact]
public void DateTime2038Issue()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ public static TheoryData<string, List<Claim>, JwtPayload, JwtPayload> PayloadDat
new List<Claim>
{
new Claim("ClaimValueTypes.String", "ClaimValueTypes.String.Value", ClaimValueTypes.String),
new Claim("ClaimValueTypes.Boolean.true", "True", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes.Boolean.false", "False", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes.Boolean.true", "true", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes.Boolean.false", "false", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes.Double", "123.4", ClaimValueTypes.Double),
new Claim("ClaimValueTypes.int.MaxValue", intMaxValue, ClaimValueTypes.Integer32),
new Claim("ClaimValueTypes.int.MinValue", intMinValue, ClaimValueTypes.Integer32),
Expand Down Expand Up @@ -300,8 +300,8 @@ public static TheoryData<string, List<Claim>, JwtPayload, JwtPayload> PayloadDat
new Claim("ClaimValueTypes", longValue, ClaimValueTypes.Integer64),
new Claim("ClaimValueTypes", "132.64", ClaimValueTypes.Double),
new Claim("ClaimValueTypes", "-132.64", ClaimValueTypes.Double),
new Claim("ClaimValueTypes", "True", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes", "False", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes", "true", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes", "false", ClaimValueTypes.Boolean),
new Claim("ClaimValueTypes", "2019-11-15T14:31:21.6101326Z", ClaimValueTypes.DateTime),
new Claim("ClaimValueTypes", "2019-11-15", ClaimValueTypes.String),
new Claim("ClaimValueTypes", @"{""name3.1"":""value3.1""}", JsonClaimValueTypes.Json),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Logging;
Expand All @@ -13,6 +14,30 @@ namespace System.IdentityModel.Tokens.Jwt.Tests
{
public class JwtSecurityTokenTests
{
[Fact]
public void BoolClaimsEncodedAsExpected()
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(new string('a', 128)));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var claims = new[] { new Claim("testClaim", "true", ClaimValueTypes.Boolean), new Claim("testClaim2", "True", ClaimValueTypes.Boolean) };
var token = new JwtSecurityToken(
issuer: "issuer.contoso.com",
audience: "audience.contoso.com",
claims: claims,
expires: (new DateTime(2038, 1, 20)).ToUniversalTime(),
signingCredentials: creds);

var claimSet = token.Claims;

// Will throw if can't find.
var testClaim = claimSet.First(c => c.Type == "testClaim");
Assert.Equal("true", testClaim.Value);

var testClaim2 = claimSet.First(c => c.Type == "testClaim2");
Assert.Equal("true", testClaim2.Value);
}

[Fact]
public void DateTime2038Issue()
{
Expand Down
Loading