Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my code think a value is Microsoft.IdentityModel.Json.Linq.JObject when it is actually supposed to be Newtonsoft.Json.Linq.JObject?

I am having a lot of difficulty with a failing unit test. Specifically,

JwtRequestAuthorizeTests.authorize_should_accept_complex_objects_in_request_object()

The test attempts to add an Object parameter to the Claims array, and it is failing because after the request goes through the pipeline, an expected parameter called "someObj" is missing.

For the record, someObj is simply a json object defined as:

{{
    "foo": {
        "bar": "bar"
    },
    "baz": "baz"
}}

Also for the record, when I pull the latest IdentityServer code from GitHub the test passes.

I've discovered that the reason it's failing is because in the method JwtRequestValidator.ProcessPayloadAsync(JwtSecurityToken token), the variable value is of a type different than what's expected. Specifically, the code thinks it's Microsoft.IdentityModel.Json.Linq.JObject when it should be Newtonsoft.Json.Linq.JObject. I can't for the life of me figure out how or why this is the case.

I've included this image to show you that I'm not crazy (or at least, why I don't think I'm crazy). You can see that the cast from value to JObject fails, as jobj = null, and you can also see that value.GetType() returns Microsoft.IdentityModel.Json.Linq.JObject.

enter image description here

So can StackOverflow please tell me why this is happening, and perhaps how I can fix it?

Also, I think it's worth noting that I'm referencing Newtonsoft.Json as it should be:

enter image description here

like image 612
DaveDev Avatar asked Jun 15 '20 23:06

DaveDev


People also ask

What is Newtonsoft JSON LINQ?

The Newtonsoft. Json. Linq namespace provides classes that are used to implement LINQ to JSON. Classes. Class.

What is JToken and JObject?

The JToken hierarchy looks like this: JToken - abstract base class JContainer - abstract base class of JTokens that can contain other JTokens JArray - represents a JSON array (contains an ordered list of JTokens) JObject - represents a JSON object (contains a collection of JProperties) JProperty - represents a JSON ...


2 Answers

After migrating from .Netframework WebAPI to dotnetcore3.1, I ran into the exact same issue. I can't believe I searched all over the internet, and was only able to find this question as the only related result.

Apparently JWT payload type is no longer NewtonSoft.Json.Linq.JObject. It is Microsoft.IdentityModel.Json.Linq.JObject now and is inaccessible outside of its namespace.

My guess is Microsoft has changed the definition and didn't expect people to use the type outside of its namespace.

What I ended up doing is getting rid of the type check, and just parse directly in a try{} catch{} block. parse-payload-directly

Hope this will help someone else in the future.

like image 63
chy600 Avatar answered Oct 18 '22 02:10

chy600


Microsoft decided to port in a copy of JSON.NET so that it can maintain a chain of trust. You can find where it's defined: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/1251

like image 25
Daniel A. White Avatar answered Oct 18 '22 02:10

Daniel A. White