azure-activedirectory-identitymodel-extensions-for-dotnet
azure-activedirectory-identitymodel-extensions-for-dotnet copied to clipboard
[Documentation] JwtPayload serialisation seems to invoke ToString for complex object claim
Documentation related to component
IdentityModel 7x releases notes.
Please check all that apply
- [ ] typo
- [ ] documentation doesn't exist
- [ ] documentation needs clarification
- [ ] error(s) in the example
- [x] needs an example
Description of the issue
Hi, I noticed the JWT additional claim serialisation behaviour has changed after upgrading System.IdentityModel.Tokens.Jwt
from version 6.x to 7.x. More specifically, when serialising a claim represented by a list of objects, JsonSecurityTokenHandler.WriteToken
seems to invoke the object's ToString()
method instead of serialising it. The following sample code:
public static string GenerateJwt()
{
var listClaim = new MyClass[] { new() { Name = "test" } };
var payload = new JwtPayload()
{
{ "claim", 1.0 },
{ "listClaim", listClaim }
};
var securityKey = new RsaSecurityKey(RSA.Create());
var signingCredentials = new SigningCredentials(securityKey, "RS256");
var token = new JwtSecurityToken(new JwtHeader(signingCredentials), payload);
return new JwtSecurityTokenHandler().WriteToken(token);
}
Generates this JWT payload:
{
"claim": 1,
"listClaim": [
"test_jwt.MyClass"
]
}
Previously, the payload was serialised as:
{
"claim": 1,
"listClaim": [
{
"Name": "test"
}
]
}
The behaviour described above only happens if instantiating JwtPayload
with the additional claims dictionary (Dictionary<string, object>
). A possible workaround is to instantiate JsonPayload
with a list of Claim
objects as follows:
var payload = new JwtPayload(
new Claim[]
{
new("claim", "1.0"),
new("listClaim", JsonSerializer.Serialize(listClaim), JsonClaimValueTypes.Json),
});
I noticed this behaviour was introduced here. The 7.x releases notes mention some changes to the serialisation behaviour, but doesn't specify the one described above. Logging as a documentation issue as I am not sure if this behaviour change is expected (and not documented) or a bug.
Thanks.