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

Arrays are not getting populated in latest version of package #185

Open
TL-Onam opened this issue May 11, 2022 · 3 comments
Open

Arrays are not getting populated in latest version of package #185

TL-Onam opened this issue May 11, 2022 · 3 comments

Comments

@TL-Onam
Copy link

TL-Onam commented May 11, 2022

In version 3.1.1 I was able to create JWTs using the following object structure (see below) but in the latest release (both 3.2.0 and 4.0.0) this is failing. I get a JWT back but when I validate this at either jwt.io or jwt.ms the scopes array is empty (using latest version) however downgrade the package to 3.1.1 it works fine.

This is the expected output:

{
  "client_id": "faee211841724a53bd5775b6ce8b38b8",
  "scope": [
    "hello",
    "world",
    "foo",
    "bar",
    "john",
    "doe"
  ],
  "iat": 637879035209350400,
  "aud": "foobar",
  "auth_time": 637879035209350400,
  "iss": "http://foobar",
  "exp": 637879071209353000,
  "nbf": 637879034609354100
}

However with anything above 3.1.1 I get:

{
  "client_id": "faee211841724a53bd5775b6ce8b38b8",
  "scope": [
     [],
     [],
     [],
     [],
     [],
     []
  ],
  "iat": 637879035209350400,
  "aud": "foobar",
  "auth_time": 637879035209350400,
  "iss": "http://foobar",
  "exp": 637879071209353000,
  "nbf": 637879034609354100
}

Reproduce by copying and pasting this code:

  • .NET 6
  • jose-jwt 4.0.0
using System.Text.Json.Serialization;
using Jose;
using Newtonsoft.Json;

string[] defaultScopes = {
    "hello",
    "world",
    "foo",
    "bar",
    "john",
    "doe"
};
var token = new TokenDetails
{
    ClientId = Guid.NewGuid().ToString("N"),
    ClientScopes = defaultScopes
};
var claims = JsonConvert.DeserializeObject<Dictionary<string, object>>(System.Text.Json.JsonSerializer.Serialize(token));
var utcNow = DateTime.UtcNow.Ticks;

claims["iat"] = utcNow;
claims["aud"] = "foobar";
claims["auth_time"] = utcNow;
claims["iss"] = "http://foobar";
claims["exp"] = DateTime.UtcNow.AddHours(1).Ticks;
claims["nbf"] = DateTime.UtcNow.AddMinutes(-1).Ticks;

var secretKey = new byte[]{164,60,194,0,161,189,41,38,130,89,141,164,45,170,159,209,69,137,243,216,191,131,47,250,32,107,231,117,37,158,225,234};
var tokenString = JWT.Encode(claims /* */, secretKey, JwsAlgorithm.HS256);
Console.Write(tokenString);
Console.Read();


public class TokenDetails
{
    [JsonPropertyName("client_id")]
    public string ClientId { get; set; }

    [JsonPropertyName("scope")]
    public string[] ClientScopes { get; set; }
}

Am I doing something wrong here? Something has changed but perhaps I need to do something different..

@TL-Onam TL-Onam changed the title Arrays are not working in latest version of package Arrays are not getting populated in latest version of package May 11, 2022
@dvsekhvalnov
Copy link
Owner

Hi @TL-Onam ,

in v3.2 Newtonsoft.Json was dropped in favor of System.Text.Json for default serialization mechanism. That's probably what's causing issues if you want to use object payloads.

You can still continue using Newtonsoft if you prefer, the previous implementation still living in repo: https://github.com/dvsekhvalnov/jose-jwt/blob/master/jose-jwt/json/NewtonsoftMapper.cs

You can use it as an example and register as default one, see: https://github.com/dvsekhvalnov/jose-jwt#customizing-json---object-parsing--mapping

Jose.JWT.DefaultSettings.JsonMapper = new MyNewtonsoftMapper();

But also check carefully your example, you deserializing claims as Dictionary<string, object> and using both Newtonsoft and System.Text.Json in same line, can be some bug here as well.

Let me know if it doesn't work, i'll try to run your sample then.

@TL-Onam
Copy link
Author

TL-Onam commented May 12, 2022

The interesting thing about this is that if I were to do this (see below) it works fine.

claims["scope"] = scopes ?? DefaultScopes;

Changing the default settings does the job but does introduce a lot more code than the one liner I've done above. I did change the mix of deserialization, thanks for that spot.

@dvsekhvalnov
Copy link
Owner

But you just assigning "scope" key in claims dictionary. That's obviously will work :)

Little bit unclear do you want to use object models payload or just generic strings/dictionaries?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants