-
Notifications
You must be signed in to change notification settings - Fork 413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added methods in JsonWebTokenHandler that allow custom JWT header claims to be added #1223
Conversation
src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
Outdated
Show resolved
Hide resolved
/// <summary> | ||
/// Encrypts a JWS. | ||
/// </summary> | ||
/// <param name="innerJwt">A 'JSON Web Token' (JWT) in JWS Compact Serialization Format.</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we modify this parameter name and comment, we don't really know or verify that the string is a JWS in Compact Serialization Format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the parameter name and comment should be changed, or perhaps maybe we should verify that the string is in JWS format?
In the RFC the value to be encrypted is referred to as 'plaintext', so we could call it that.
However, if something other than a JWS is passed into this method, the result produced by this method will no longer be something our library can verify. I feel like this may cause confusion.
The name of the method also happens to be 'EncryptToken', which may also get confusing.
/// will result in an exception being thrown. | ||
/// <remarks> These claims are only added to the outer header (in case of a JWE).</remarks> | ||
/// </summary> | ||
public IDictionary<string, object> AdditionalHeaderClaims { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property is only for JWT's. What will SAML handlers do with this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking this would be a property that's only used when creating JWT tokens. I could make the comment clearer with regards to this if you think that'll help.
On a related note, IDictionary<string, object> Claims
is currently not being used by the SAML handlers either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this captures the issue for SAML and the dictionary: #1155
6e43d3c
to
0f506ac
Compare
src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
Outdated
Show resolved
Hide resolved
I haven't looked at the API yet - but per our recent discussion, please make sure it is easily possible to set the |
src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
Outdated
Show resolved
Hide resolved
9696e13
to
ef50621
Compare
src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
Outdated
Show resolved
Hide resolved
{ | ||
var header = new JObject(); | ||
|
||
if (!string.IsNullOrEmpty(encryptingCredentials.Alg)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! Fixed.
var header = new JObject | ||
{ | ||
{ JwtHeaderParameterNames.Alg, signingCredentials.Algorithm }, | ||
{ JwtHeaderParameterNames.Kid, signingCredentials.Key.KeyId }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KeyId can be null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Also added in a test for this.
@@ -199,7 +269,7 @@ public virtual string CreateToken(SecurityTokenDescriptor tokenDescriptor) | |||
if (!payload.Any()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#1237 was opened as an empty payload should be allowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Also added in some tests.
/// <exception cref="ArgumentNullException">if <paramref name="compressionAlgorithm"/> is null.</exception> | ||
/// <exception cref="ArgumentNullException">if <paramref name="additionalHeaderClaims"/> is null.</exception> | ||
/// <returns>A JWE in compact serialization format.</returns> | ||
public virtual string CreateToken(string payload, SigningCredentials signingCredentials, EncryptingCredentials encryptingCredentials, string compressionAlgorithm, IDictionary<string, object> additionalHeaderClaims) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to add a comment to capture the SecurityTokenException thrown if any default header claims are found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I fixed this in all the relevant methods.
/// <exception cref="ArgumentNullException">if <paramref name="signingCredentials"/> is null.</exception> | ||
/// <exception cref="ArgumentNullException">if <paramref name="additionalHeaderClaims"/> is null.</exception> | ||
/// <returns>A JWS in Compact Serialization Format.</returns> | ||
public virtual string CreateToken(string payload, SigningCredentials signingCredentials, IDictionary<string, object> additionalHeaderClaims) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to add a comment to capture the SecurityTokenException thrown if any default header claims are found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
var rawHeader = Base64UrlEncodedUnsignedJWSHeader; | ||
if (signingCredentials != null && !JsonWebTokenManager.KeyToHeaderCache.TryGetValue(JsonWebTokenManager.GetHeaderCacheKey(signingCredentials), out rawHeader)) | ||
// If there's no additional header claims to be added to the header and the token will be signed, try to retrieve a header value from the cache. | ||
if (additionalHeaderClaims == null && signingCredentials != null && !JsonWebTokenManager.KeyToHeaderCache.TryGetValue(JsonWebTokenManager.GetHeaderCacheKey(signingCredentials), out rawHeader)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(nit) could add additionalHeaderClaims.Count > 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean that we should check for this before seeing if 'additionalHeaderClaims' intersects _defaultHeaderParameters? Or that we should check for this so that we still use the header cache if 'additionalHeaderClaims' is empty?
I added in a check in both places.
src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
Outdated
Show resolved
Hide resolved
1e3a6da
to
e5f426e
Compare
e5f426e
to
5a2deab
Compare
5a2deab
to
9df81a5
Compare
9df81a5
to
f9746b6
Compare
FYI, this currently isnt working with RSA-PSS support. |
Hi @steveoshima - It's not clear what exactly is not working. Can you provide more information or/and a small repro project? |
@steveoshima - Are you still hitting the issue when using RSA-PSS? |
I attempted to check different branches to get RSA-PSS with custom headers working last week. However, no branches worked that i tried. I spotted the cusom header test with RSA-PSS was incomplete. I messaged about this on the issue. See my comment here - #1210 You will see the test is missing additonal header setup data, if this is added im sure the error will occur. - Line 1347 in 1c16adc
|
Fixes #1210 and #1237.