From e4ffac5e0914f08224889289010909ce9c3b9cdd Mon Sep 17 00:00:00 2001 From: Markus Hartung Date: Tue, 24 Jan 2023 23:22:32 +0100 Subject: [PATCH] Fix for when encoding Json.NET decorated payload #456 --- src/JWT/Builder/JwtBuilder.cs | 17 +++++++++++++- .../Builder/JwtBuilderDecodeTests.cs | 23 +++++++++++++++++++ .../Builder/JwtBuilderEncodeTests.cs | 2 +- tests/JWT.Tests.Common/Models/TestData.cs | 6 +++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/JWT/Builder/JwtBuilder.cs b/src/JWT/Builder/JwtBuilder.cs index 36f6c61f4..ca116d590 100644 --- a/src/JWT/Builder/JwtBuilder.cs +++ b/src/JWT/Builder/JwtBuilder.cs @@ -3,6 +3,7 @@ using System.Reflection; using JWT.Algorithms; using JWT.Serializers; +using Newtonsoft.Json; using static JWT.Internal.EncodingHelper; namespace JWT.Builder @@ -276,7 +277,7 @@ public string Encode(Type payloadType, object payload) EnsureCanEncode(); var dic = payloadType.GetProperties(BindingFlags.Instance | BindingFlags.Public) - .ToDictionary(prop => prop.Name, prop => prop.GetValue(payload, null)); + .ToDictionary(GetPropName, prop => prop.GetValue(payload, null)); foreach (var pair in dic) { @@ -286,6 +287,20 @@ public string Encode(Type payloadType, object payload) return Encode(); } + private static string GetPropName(MemberInfo prop) + { + var customAttributes = prop.GetCustomAttributes(true); + foreach (var attribute in customAttributes) + { + if (attribute is JsonPropertyAttribute jsonNetProperty) + { + return jsonNetProperty.PropertyName; + } + } + + return prop.Name; + } + /// /// Decodes a token using the supplied dependencies. /// diff --git a/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs b/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs index dbafb02cf..26e0770c6 100644 --- a/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs +++ b/tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs @@ -433,5 +433,28 @@ public void Decode_ToDictionary_Without_Serializer_Should_Throw_Exception() action.Should() .Throw(); } + + [TestMethod] + public void Encode_Decode_ToJsonNetDecoratedType_Should_UseDecoratedName() + { + var token = JwtBuilder.Create() + .WithAlgorithm(new NoneAlgorithm()) + .WithJsonSerializer(new JsonNetSerializer()); + + var model = new TestData.TestDataJsonNetDecorated + { + AccessToken = "abc123", + }; + + var encoded = token.Encode(model); + Assert.IsNotNull(encoded); + + token = JwtBuilder.Create() + .WithAlgorithm(new NoneAlgorithm()) + .WithJsonSerializer(new JsonNetSerializer()); + + var payloadDecoded = token.Decode(encoded); + Assert.AreEqual(model.AccessToken, payloadDecoded.AccessToken); + } } } diff --git a/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs b/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs index 79cc821c9..9a77a4aed 100644 --- a/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs +++ b/tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs @@ -381,7 +381,7 @@ public void Encode_With_Secret_Should_Return_Valid_Token_Using_Json_Net() .HaveCount(3, "because the token should consist of three parts"); } -#if NETSTANDARD2_0 || NET6_0 +#if NETSTANDARD2_0 || NET6_0 || NET7_0 [TestMethod] public void Encode_Test_Bug438() { diff --git a/tests/JWT.Tests.Common/Models/TestData.cs b/tests/JWT.Tests.Common/Models/TestData.cs index 94da079e8..082263a8a 100644 --- a/tests/JWT.Tests.Common/Models/TestData.cs +++ b/tests/JWT.Tests.Common/Models/TestData.cs @@ -17,6 +17,12 @@ public static class TestData Age = 33 }; + public class TestDataJsonNetDecorated + { + [Newtonsoft.Json.JsonProperty("AT")] + public string AccessToken { get; set; } + } + public const string Secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk"; public const string Secret2 = "QWORIJkmQWEDIHbjhOIHAUSDFOYnUGWEYT";