Skip to content

Commit

Permalink
fixed null ref, claim as string was null
Browse files Browse the repository at this point in the history
fixed miscount when formating error on payload
  • Loading branch information
Brent Schmaltz committed Sep 28, 2023
1 parent 002b197 commit 694f992
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,12 @@ internal Claim GetClaim(string key, string issuer)
internal string GetStringValue(string key)
{
if (_jsonClaims.TryGetValue(key, out object obj))
{
if (obj == null)
return null;

return obj.ToString();
}

return string.Empty;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ internal void ReadToken(string encodedJson)
}
catch (Exception ex)
{
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX14101, encodedJson.Substring(Dot2, Dot2 - Dot1)), ex));
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX14101, encodedJson.Substring(Dot1 + 1, Dot2 - Dot1 - 1)), ex));
}
}
else
Expand Down
197 changes: 193 additions & 4 deletions test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
using Newtonsoft.Json.Linq;
using Xunit;

using JsonReaderException = System.Text.Json.JsonException;

namespace Microsoft.IdentityModel.JsonWebTokens.Tests
{
public class JsonWebTokenTests
Expand Down Expand Up @@ -361,6 +359,198 @@ public static TheoryData<GetPayloadValueTheoryData> CheckAudienceValuesTheoryDat
}
}

// Checks that null values are processed properly for strings, type mismatches throw expected exception.
[Theory, MemberData(nameof(GetTokenPropertyTheoryData), DisableDiscoveryEnumeration = true)]
public void GetTokenProperty(GetPayloadValueTheoryData theoryData)
{
CompareContext context = TestUtilities.WriteHeader($"{this}.GetTokenProperty", theoryData);
try
{
JsonWebToken jsonWebToken = new JsonWebToken(theoryData.Json);
string payload = Base64UrlEncoder.Decode(jsonWebToken.EncodedPayload);
PropertyInfo property = typeof(JsonWebToken).GetProperty(theoryData.PropertyName, theoryData.PropertyType);
MethodInfo method = property.GetGetMethod();
var retVal = method.Invoke(jsonWebToken, null);

theoryData.ExpectedException.ProcessNoException(context);
IdentityComparer.AreEqual(retVal, theoryData.PropertyValue, context);
}
catch (Exception ex)
{
theoryData.ExpectedException.ProcessException(ex.InnerException, context);
}

TestUtilities.AssertFailIfErrors(context);
}

public static TheoryData<GetPayloadValueTheoryData> GetTokenPropertyTheoryData
{
get
{
var theoryData = new TheoryData<GetPayloadValueTheoryData>();

#region header
theoryData.Add(new GetPayloadValueTheoryData("Alg")
{
PropertyName = "Alg",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("alg", null, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("Alg_Int")
{
ExpectedException = new ExpectedException(typeof(System.Text.Json.JsonException), "IDX11020:"),
PropertyName = "Alg",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("alg", 1, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("Cty")
{
PropertyName = "Cty",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("cty", null, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("Enc")
{
PropertyName = "Enc",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("enc", null, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("Kid")
{
PropertyName = "Kid",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("kid", null, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("Typ")
{
PropertyName = "Typ",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("typ", null, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("X5t")
{
PropertyName = "X5t",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("x5t", null, "iss", "issuer")
});

theoryData.Add(new GetPayloadValueTheoryData("Zip")
{
PropertyName = "Zip",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("zip", null, "iss", "issuer")
});
#endregion

#region payload
theoryData.Add(new GetPayloadValueTheoryData("Actor")
{
PropertyName = "Actor",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("actort", null)
});

theoryData.Add(new GetPayloadValueTheoryData("Audiences")
{
PropertyName = "Audiences",
PropertyType = typeof(IEnumerable<string>),
PropertyValue = new List<string>(),
Json = JsonUtilities.CreateUnsignedToken("aud", null)
});

theoryData.Add(new GetPayloadValueTheoryData("Azp")
{
PropertyName = "Azp",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("azp", null)
});

theoryData.Add(new GetPayloadValueTheoryData("Azp_Int")
{
ExpectedException = new ExpectedException(typeof(System.Text.Json.JsonException), "IDX11020:"),
PropertyName = "Azp",
PropertyType = typeof(string),
Json = JsonUtilities.CreateUnsignedToken("azp", 1)
});


theoryData.Add(new GetPayloadValueTheoryData("Issuer")
{
PropertyName = "Issuer",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("iss", null)
});

theoryData.Add(new GetPayloadValueTheoryData("IssuedAt")
{
ExpectedException = new ExpectedException(typeof(System.Text.Json.JsonException), "IDX11020:"),
PropertyName = "IssuedAt",
PropertyType = typeof(DateTime),
Json = JsonUtilities.CreateUnsignedToken("iat", null)
});

theoryData.Add(new GetPayloadValueTheoryData("IssuedAt_String")
{
ExpectedException = new ExpectedException(typeof(System.Text.Json.JsonException), "IDX11020:"),
PropertyName = "IssuedAt",
PropertyType = typeof(DateTime),
Json = JsonUtilities.CreateUnsignedToken("iat", "apple")
});

theoryData.Add(new GetPayloadValueTheoryData("Id")
{
PropertyName = "Id",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("jti", null)
});

theoryData.Add(new GetPayloadValueTheoryData("Subject")
{
PropertyName = "Subject",
PropertyType = typeof(string),
PropertyValue = null,
Json = JsonUtilities.CreateUnsignedToken("sub", null)
});

theoryData.Add(new GetPayloadValueTheoryData("ValidFrom")
{
ExpectedException = new ExpectedException(typeof(System.Text.Json.JsonException), "IDX11020:"),
PropertyName = "ValidFrom",
PropertyType = typeof(DateTime),
Json = JsonUtilities.CreateUnsignedToken("nbf", null)
});

theoryData.Add(new GetPayloadValueTheoryData("ValidTo")
{
ExpectedException = new ExpectedException(typeof(System.Text.Json.JsonException), "IDX11020:"),
PropertyName = "ValidTo",
PropertyType = typeof(DateTime),
Json = JsonUtilities.CreateUnsignedToken("exp", null)
});
#endregion

return theoryData;
}
}

// This test ensures that TryGetPayloadValue does not throw
// No need to check for equal as GetPayloadValue does that
[Theory, MemberData(nameof(GetPayloadValueTheoryData), DisableDiscoveryEnumeration = true)]
Expand All @@ -385,7 +575,7 @@ public void TryGetPayloadValue(GetPayloadValueTheoryData theoryData)
TestUtilities.AssertFailIfErrors(context);
}

// This test ensures that our roundtripping works as expected.
// This test ensures that accessing claims from the payload works as expected.
[Theory, MemberData(nameof(GetPayloadValueTheoryData), DisableDiscoveryEnumeration = true)]
public void GetPayloadValue(GetPayloadValueTheoryData theoryData)
{
Expand Down Expand Up @@ -418,7 +608,6 @@ public static TheoryData<GetPayloadValueTheoryData> GetPayloadValueTheoryData
DateTime dateTime = DateTime.UtcNow;

#region simple types from string

theoryData.Add(new GetPayloadValueTheoryData("stringFromDateTime")
{
PropertyName = "stringFromDateTime",
Expand Down
12 changes: 11 additions & 1 deletion test/Microsoft.IdentityModel.Tokens.Tests/Json/JsonUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ public static void SetAdditionalDataValues(IDictionary<string, object> dictionar
}

public static string CreateUnsignedToken(string key, object value)
{
return EmptyHeader + "." + CreateEncodedJson(key, value) + ".";
}

public static string CreateUnsignedToken(string headerKey, object headerValue, string payloadKey, object payloadValue)
{
return CreateEncodedJson(headerKey, headerValue) + "." + CreateEncodedJson(payloadKey, payloadValue) + ".";
}

public static string CreateEncodedJson(string key, object value)
{
Utf8JsonWriter writer = null;
using (MemoryStream memoryStream = new MemoryStream())
Expand All @@ -183,7 +193,7 @@ public static string CreateUnsignedToken(string key, object value)
writer.WriteEndObject();
writer.Flush();

return EmptyHeader + "." + Base64UrlEncoder.Encode(memoryStream.GetBuffer(), 0, (int)memoryStream.Length) + ".";
return Base64UrlEncoder.Encode(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}
finally
{
Expand Down

0 comments on commit 694f992

Please sign in to comment.