Skip to content

Commit

Permalink
remove check for empty payload
Browse files Browse the repository at this point in the history
  • Loading branch information
HP712 committed Jul 25, 2024
1 parent 2cde86c commit ba2ac83
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ internal JsonClaimSet CreatePayloadClaimSet(byte[] bytes, int length)

internal JsonClaimSet CreatePayloadClaimSet(ReadOnlySpan<byte> byteSpan)
{
if (byteSpan.Length == 0)
return new JsonClaimSet([]);

Utf8JsonReader reader = new(byteSpan);
if (!JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.StartObject, true))
throw LogHelper.LogExceptionMessage(
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 @@ -130,7 +130,7 @@ public JsonWebToken(string header, string payload)
if (string.IsNullOrEmpty(header))
throw LogHelper.LogArgumentNullException(nameof(header));

if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

var encodedHeader = Base64UrlEncoder.Encode(header);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public partial class JsonWebTokenHandler : TokenHandler
/// <returns>A JWS in Compact Serialization format.</returns>
public virtual string CreateToken(string payload)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

return CreateToken(
Expand All @@ -59,7 +59,7 @@ public virtual string CreateToken(
string payload,
IDictionary<string, object> additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = additionalHeaderClaims ?? throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
Expand All @@ -85,7 +85,7 @@ public virtual string CreateToken(
string payload,
SigningCredentials signingCredentials)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = signingCredentials ?? throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
Expand Down Expand Up @@ -118,7 +118,7 @@ public virtual string CreateToken(
SigningCredentials signingCredentials,
IDictionary<string, object> additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = signingCredentials ?? throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
Expand Down Expand Up @@ -296,7 +296,7 @@ public virtual string CreateToken(
string payload,
EncryptingCredentials encryptingCredentials)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = encryptingCredentials ?? throw LogHelper.LogArgumentNullException(nameof(encryptingCredentials));
Expand Down Expand Up @@ -329,7 +329,7 @@ public virtual string CreateToken(
EncryptingCredentials encryptingCredentials,
IDictionary<string, object> additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = encryptingCredentials ?? throw LogHelper.LogArgumentNullException(nameof(encryptingCredentials));
Expand Down Expand Up @@ -360,7 +360,7 @@ public virtual string CreateToken(
SigningCredentials signingCredentials,
EncryptingCredentials encryptingCredentials)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = signingCredentials ?? throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
Expand Down Expand Up @@ -397,7 +397,7 @@ public virtual string CreateToken(
EncryptingCredentials encryptingCredentials,
IDictionary<string, object> additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

_ = signingCredentials ?? throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
Expand Down Expand Up @@ -426,7 +426,7 @@ public virtual string CreateToken(
EncryptingCredentials encryptingCredentials,
string compressionAlgorithm)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

if (string.IsNullOrEmpty(compressionAlgorithm))
Expand Down Expand Up @@ -462,7 +462,7 @@ public virtual string CreateToken(
EncryptingCredentials encryptingCredentials,
string compressionAlgorithm)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

if (string.IsNullOrEmpty(compressionAlgorithm))
Expand Down Expand Up @@ -507,7 +507,7 @@ public virtual string CreateToken(
IDictionary<string, object> additionalHeaderClaims,
IDictionary<string, object> additionalInnerHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

if (string.IsNullOrEmpty(compressionAlgorithm))
Expand Down Expand Up @@ -552,7 +552,7 @@ public virtual string CreateToken(
string compressionAlgorithm,
IDictionary<string, object> additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
if (payload == null)
throw LogHelper.LogArgumentNullException(nameof(payload));

if (string.IsNullOrEmpty(compressionAlgorithm))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1626,7 +1626,6 @@ public static TheoryData<CreateTokenTheoryData> CreateJWEWithPayloadStringTheory
{
new CreateTokenTheoryData
{
First = true,
TestId = "JsonPayload",
Payload = Default.PayloadString,
TokenDescriptor = new SecurityTokenDescriptor
Expand All @@ -1637,8 +1636,7 @@ public static TheoryData<CreateTokenTheoryData> CreateJWEWithPayloadStringTheory
},
new CreateTokenTheoryData
{
First = true,
TestId = "JsonPayload",
TestId = "JsonPayload_No_Cty",
Payload = Default.PayloadString,
TokenDescriptor = new SecurityTokenDescriptor
{
Expand Down Expand Up @@ -2022,32 +2020,6 @@ public static TheoryData<CreateTokenTheoryData> CreateJWSUsingSecurityTokenDescr
new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(Default.Expires).ToString(), ClaimValueTypes.String, Default.Issuer, Default.Issuer),
}, "AuthenticationTypes.Federation")
},
TokenDescriptor6x = new SecurityTokenDescriptor
{
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
Claims = new Dictionary<string, object>()
{
{ JwtRegisteredClaimNames.Email, "[email protected]" },
{ JwtRegisteredClaimNames.GivenName, "Bob" },
{ JwtRegisteredClaimNames.Iss, Default.Issuer },
{ JwtRegisteredClaimNames.Aud, JArray.FromObject(Default.Audiences) },
{ JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(Default.IssueInstant).ToString() },
{ JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(Default.NotBefore).ToString()},
{ JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(Default.Expires).ToString() },
},
Subject = new CaseSensitiveClaimsIdentity(new List<Claim>()
{
new Claim(JwtRegisteredClaimNames.Email, "[email protected]", ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.GivenName, "Bob", ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.Iss, "Issuer", ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.Aud.ToUpper(), "Audience1", ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.Aud.ToUpper(), "Audience2", ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(Default.IssueInstant).ToString(), ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(Default.NotBefore).ToString(), ClaimValueTypes.String, Default.Issuer, Default.Issuer),
new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(Default.Expires).ToString(), ClaimValueTypes.String, Default.Issuer, Default.Issuer),
}, "AuthenticationTypes.Federation")
},

JsonWebTokenHandler = new JsonWebTokenHandler(),
ValidationParameters = new TokenValidationParameters
{
Expand Down Expand Up @@ -2472,8 +2444,8 @@ public async Task AdditionalHeaderValues()
public void RoundTripJWS()
{
TestUtilities.WriteHeader($"{this}.RoundTripToken");
var context = new CompareContext();

var context = new CompareContext();
var tokenHandler = new JsonWebTokenHandler();
var tokenValidationParameters = new TokenValidationParameters()
{
Expand All @@ -2486,12 +2458,158 @@ public void RoundTripJWS()
string jwtString = tokenHandler.CreateToken(Default.PayloadString, KeyingMaterial.JsonWebKeyRsa256SigningCredentials);
var tokenValidationResult = tokenHandler.ValidateTokenAsync(jwtString, tokenValidationParameters).Result;
var validatedToken = tokenValidationResult.SecurityToken as JsonWebToken;
var claimsIdentity = tokenValidationResult.ClaimsIdentity;
IdentityComparer.AreEqual(Default.PayloadClaimsIdentity, claimsIdentity, context);
IdentityComparer.AreEqual(Default.PayloadClaimsIdentity, tokenValidationResult.ClaimsIdentity, context);
IdentityComparer.AreEqual(Default.PayloadString, Base64UrlEncoder.Decode(validatedToken.EncodedPayload), context);

TestUtilities.AssertFailIfErrors(context);
}

// Test ensure paths to creating a token with an empty payload are successful.
[Theory, MemberData(nameof(RoundTripWithEmptyPayloadTestCases))]
public void RoundTripWithEmptyPayload(CreateTokenTheoryData theoryData)
{
TestUtilities.WriteHeader($"{this}.RoundTripWithEmptyPayload");

var context = new CompareContext();
var jwtString = JsonWebTokenHandler.CreateToken(
theoryData.Payload,
theoryData.SigningCredentials,
theoryData.EncryptingCredentials,
theoryData.CompressionAlgorithm,
theoryData.AdditionalHeaderClaims,
theoryData.AdditionalInnerHeaderClaims,
"JWT");

var tokenValidationResult = theoryData.JsonWebTokenHandler.ValidateTokenAsync(jwtString, theoryData.ValidationParameters).Result;
var validatedToken = tokenValidationResult.SecurityToken as JsonWebToken;
var claimsIdentity = tokenValidationResult.ClaimsIdentity;
IdentityComparer.AreEqual(new ClaimsIdentity("AuthenticationTypes.Federation"), claimsIdentity, context);
IdentityComparer.AreEqual("", Base64UrlEncoder.Decode(validatedToken.EncodedPayload), context);

TestUtilities.AssertFailIfErrors(context);
}

public static TheoryData<CreateTokenTheoryData> RoundTripWithEmptyPayloadTestCases
{
get
{
TheoryData<CreateTokenTheoryData> theoryData = new TheoryData<CreateTokenTheoryData>();

Dictionary<string, object> additionalInnerHeaderClaims = new Dictionary<string, object>()
{
{ "intInnerHeader", 1233 },
{ "stringInnerHeader", "stringInnerHeader" }
};

Dictionary<string, object> additionalHeaderClaims = new Dictionary<string, object>()
{
{ "int", 123 },
{ "string", "string" }
};

EncryptingCredentials encryptingCredentials = new EncryptingCredentials(KeyingMaterial.DefaultX509Key_2048, SecurityAlgorithms.RsaPKCS1, SecurityAlgorithms.Aes128CbcHmacSha256);

TokenValidationParameters validationParameters = new TokenValidationParameters
{
IssuerSigningKey = KeyingMaterial.JsonWebKeyRsa256SigningCredentials.Key,
RequireSignedTokens = false,
TokenDecryptionKey = KeyingMaterial.DefaultX509Key_2048,
ValidateAudience = false,
ValidateLifetime = false,
ValidateIssuer = false
};

theoryData.Add(new CreateTokenTheoryData("EmptyPayload")
{
Payload = "",
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("additionalHeaderClaims")
{
AdditionalHeaderClaims = additionalHeaderClaims,
Payload = "",
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentials")
{
EncryptingCredentials = encryptingCredentials,
Payload = "",
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentialsAdditionalHeaderClaims")
{
EncryptingCredentials = encryptingCredentials,
Payload = "",
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentialsCompression")
{
CompressionAlgorithm = CompressionAlgorithms.Deflate,
EncryptingCredentials = encryptingCredentials,
Payload = "",
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentialsSigningCredentials")
{
EncryptingCredentials = encryptingCredentials,
Payload = "",
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentialsSigningCredentialsAdditionalHeaderClaims")
{
AdditionalHeaderClaims = additionalHeaderClaims,
EncryptingCredentials = encryptingCredentials,
Payload = "",
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentialsSigningCredentialsCompression")
{
CompressionAlgorithm = CompressionAlgorithms.Deflate,
EncryptingCredentials = encryptingCredentials,
Payload = "",
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("encryptingCredentialsSigningCredentialsCompressionAddionalHeaderClaimsAdditionalInnerHeaderClaims")
{
AdditionalInnerHeaderClaims = additionalInnerHeaderClaims,
AdditionalHeaderClaims = additionalHeaderClaims,
CompressionAlgorithm = CompressionAlgorithms.Deflate,
EncryptingCredentials = encryptingCredentials,
Payload = "",
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("signingCredentials")
{
Payload = "",
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
ValidationParameters = validationParameters
});

theoryData.Add(new CreateTokenTheoryData("signingCredentialsAdditionalHeaderClaims")
{
AdditionalHeaderClaims = additionalHeaderClaims,
Payload = "",
SigningCredentials = KeyingMaterial.JsonWebKeyRsa256SigningCredentials,
ValidationParameters = validationParameters
});

return theoryData;
}
}

[Theory, MemberData(nameof(RoundTripJWEDirectTestCases))]
public void RoundTripJWEInnerJWSDirect(CreateTokenTheoryData theoryData)
{
Expand Down Expand Up @@ -4276,6 +4394,8 @@ public CreateTokenTheoryData(string testId) : base(testId)

public Dictionary<string, object> AdditionalHeaderClaims { get; set; }

public Dictionary<string, object> AdditionalInnerHeaderClaims { get; set; }

public string Payload { get; set; }

public string CompressionAlgorithm { get; set; }
Expand All @@ -4292,9 +4412,7 @@ public CreateTokenTheoryData(string testId) : base(testId)

public SecurityTokenDescriptor TokenDescriptor { get; set; }

public SecurityTokenDescriptor TokenDescriptor6x { get; set; }

public JsonWebTokenHandler JsonWebTokenHandler { get; set; }
public JsonWebTokenHandler JsonWebTokenHandler { get; set; } = new JsonWebTokenHandler();

public JwtSecurityTokenHandler JwtSecurityTokenHandler { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1599,12 +1599,6 @@ public static TheoryData<JwtTheoryData> ParseTokenTheoryData
ExpectedException = new ExpectedException(typeof(ArgumentException), "IDX14102:", typeof(JsonReaderException), true),
});

theoryData.Add(new JwtTheoryData(nameof(EncodedJwts.JWSEmptyPayload))
{
Token = EncodedJwts.JWSEmptyPayload,
ExpectedException = new ExpectedException(typeof(ArgumentException), "IDX14101:", typeof(JsonReaderException), true),
});

theoryData.Add(new JwtTheoryData(nameof(EncodedJwts.JWEEmptyHeader))
{
Token = EncodedJwts.JWEEmptyHeader,
Expand Down

0 comments on commit ba2ac83

Please sign in to comment.