3

Is it possible to pass a JSON object as a claim of JWT Token or list of objects (like shown on below example)?

{
  "nickname": [
    {
      "external_nickname": "tomas",
      "internal_nickname": "t_omas"
    }, 
    {
      "external_nickname": "malex",
      "internal_nickname": "alexander014"
    } 
  ]
}

So far I can only pass one nickname in token

"nickname" : "tomas"

Or I can pass an array

"nickname" : ["nickname1","nickname2"]

But none of these satisfies me.

EDIT:

Using Avin Kavish approach I got extra slashes in JSON Object. I don't want them. How to get rid of them?

 "nickname": "[{\"external_nickname\":\"tomas\",\"internal_nickname\":\"t_omas\"}]"
justme
  • 316
  • 3
  • 13

4 Answers4

3

If you look at the underlying structures you will find that the JWTPayload class inherits from Dictionary<string,object>. Once we know that, the rest is easy:

// Build the claims list somehow, may contain nested objects
// NOTE: any nested data must be JSON-serializable!
Dictionary<string,object> claims = BuildMeThatClaimsList();

// Add all claims manually because the CTORs only accept string values
var token = new JwtSecurityToken(issuer, audience, Array.Empty<Claim>(), notBefore, expires, signingCreds);
foreach (var pair in claims)
  token.Payload.Add(pair.Key, pair.Value);
return token;
JensG
  • 13,148
  • 4
  • 45
  • 55
2

Yes, serialize it first.

var claim = new Claim("nickname", JsonConvert.SerializeObject(nicknames));

In order to use the nicknames, you need to deserialize from a string back to a plain old object.

In javascript,

const nicknames = JSON.Parse(value)

In C#,

var nicknames = JsonConvert.DeserializeObject<T>(value) // <-- where T is your type
Avin Kavish
  • 8,317
  • 1
  • 21
  • 36
  • There are slashes present i JWT Token using your approach. Do you know how to fix it? – justme Jun 11 '19 at 17:14
  • I think the slashes are great for escaping the double quotes in the serialized object, can't you remove them when you use the claims eg. from your client? –  Jun 11 '19 at 17:20
2

I use JWT NuGet package.

Install-Package JWT 

the code:

        var payload = new
        {
            nickname = new[]
            {
                new {external_nickname = "tomas", internal_nickname = "t_omas"},
                new {external_nickname = "malex", internal_nickname = "alexander014"}
            }
        };
        
        var encoder = new JwtEncoder(new HMACSHA256Algorithm(), new JsonNetSerializer(), new JwtBase64UrlEncoder());
        var token = encoder.Encode(payload, "your_secret");
2

For those using asp.net core, this is really simple. The claim object has an additional parameter.

new Claim("json", "{\"sample\":{\"sample\":\"value\"}}", JsonClaimValueTypes.Json)

The JsonClaimValueTypes is part of System.IdentityModel.Tokens.Jwt

Sachin
  • 47
  • 2
  • 5