dotnet / linker

387 stars 127 forks source link

Blazor client side Unable to find a default constructor to use for type System.IdentityModel.Tokens.Jwt.JwtPayload. #870

Open mkArtakMSFT opened 4 years ago

mkArtakMSFT commented 4 years ago

From @partyelite on Tuesday, December 17, 2019 12:31:24 PM

Describe the bug

I'm using blazor client side and System.IdentityModel.Tokens.Jwt package v5.6.0. When calling ReadJwtToken method on JwtSecurityTokenHandler I get the following exception

Newtonsoft.Json.JsonSerializationException: Unable to find a default constructor to use for type System.IdentityModel.Tokens.Jwt.JwtPayload.

I believe it has something to do with linker because if I add a redundant call to new System.IdentityModel.Tokens.Jwt.JwtPayload() in App.razor OnInitialized method it works.

I have tried adding

<assembly fullname="System.IdentityModel.Tokens.Jwt"/>

to my Linker.xml file but that didn't help.

Copied from original issue: aspnet/AspNetCore#17920

Schwascho commented 4 years ago

Because its the first time for me taking part of such a discussion i'm not sure if this issue is solved or not. I ran exactly into the same problem when a calling the JwtSecurityTokenHandler.ReadJwtToken(...) Method client side. I would be happy if someone could help me.

Safirion commented 4 years ago

Same here. Don't know what to do with that...

 Newtonsoft.Json.JsonSerializationException: Unable to find a default constructor to use for type System.IdentityModel.Tokens.Jwt.JwtPayload. Path 'unique_name', line 1, position 15.
blazor.webassembly.js:1 

  at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewDictionary (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonDictionaryContract contract, System.Boolean& createdFromNonDefaultCreator) <0x3177e08 + 0x0018e> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) <0x2f62640 + 0x003a4> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) <0x2c82428 + 0x000a4> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) <0x2b468b0 + 0x001ac> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

 at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) <0x2b3e898 + 0x000a4> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

 at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) <0x2b3e318 + 0x0000e> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

   at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) <0x2b931d8 + 0x00066> in <2073514815234917a5e8f91b0b239405>:0 
blazor.webassembly.js:1 

at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type) <0x3171068 + 0x0000a> in <2073514815234917a5e8f91b0b239405>:0 

[Edit] Workaround:

After creating an instance of JwtPayload in my Startup.cs, deserialization works... I think that the linker optimization is too strong... Not very reassuring 😕

In "ConfigureServices" in my Startup.cs : _ = new JwtPayload();

Spaceman1861 commented 4 years ago

I had something very similar with JwtHeader.

Original Error:

System.ArgumentException: IDX12729: Unable to decode the header '[PII is hidden. For more details, see

It was hidden behind pii filtering. I added the following to my Program.Main.

IdentityModelEventSource.ShowPII = true;

That then resulted in this trace.

System.ArgumentException: IDX12729: Unable to decode the header 'REDACTED' as Base64Url encoded string. jwtEncodedString: 'REDACTED. ---> Newtonsoft.Json.JsonSerializationException: Unable to find a default constructor to use for type System.IdentityModel.Tokens.Jwt.JwtHeader. Path 'typ',

I saw this thread and added the following to my Program.Main.

_ = new JwtHeader();
_ = new JwtPayload();

And everything worked.

Note: I removed this after testing.

IdentityModelEventSource.ShowPII = true;

Hopefully this helps someone.

mores commented 4 years ago
_ = new JwtHeader();
_ = new JwtPayload();

Can anyone explain how the above code works around the issue ?

Safirion commented 4 years ago

It think that it prevents the linker from optimizing the dependencies too much.