-
Notifications
You must be signed in to change notification settings - Fork 432
Add ReadOnlyMemory based overload for CanReadToken #3222
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
base: dev
Are you sure you want to change the base?
Add ReadOnlyMemory based overload for CanReadToken #3222
Conversation
|
@microsoft-github-policy-service agree |
|
I did not add benchmarks, even though this is a performance improvement. The reason being that the string based API calls the span based one. |
Change to ReadOnlyMemory to reduce allocations when calling ToString
|
Thanks for your contribution @henrikwidlund . Are you planning to add unit tests? |
|
@kllysng I was thinking that the regular string based ones would cover it since the string based method calls the memory based one. Let me know if you want explicit tests. |
|
I've added tests now either way. Also added the method to |
| // more segments than the maximum we know how to handle. | ||
| int segmentCount = JwtTokenUtilities.CountJwtTokenPart(token.Span, JwtConstants.MaxJwtSegmentCount + 1); | ||
|
|
||
| switch (segmentCount) |
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 code (switch (segmentCount)) can be shared between JsonWebTokenHandler and JwtSecurityTokenHandler.
When you think about it, most of this code could be shared between JsonWebTokenHandler and JwtSecurityTokenHandler.
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.
@brentschmaltz please resolve if you're satisfied with the solution :)
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.
refactor and share common code between JsonWebTokenHandler and JwtSecurityTokenHandler.
|
Good points @brentschmaltz, I've applied your suggestions. |
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.
LGTM, thank you for taking the suggestions and making the contribution @henrikwidlund.
|
I see that a few unit tests are failing because of accessibility. I'll make the method internal again tomorrow |
|
@sruke fixed the compiler error |
|
@henrikwidlund, a few unit tests are still failing. We’re planning to release IdentityModel today—would it be okay to include this PR in the next release (in a month) instead? |
|
@sruke I believe I've fixed the test (was a real bug). I leave it up to you if it's getting to tight for your deadline (although, it would be nice to have it :)) |
|
I noticed that the PR build is still failing, but I don't understand if it's related to my code changes? |
The failure (Resource not accessible by integration) appears unrelated to recent changes. All tests passed. I’m rerunning the build to check if the issue resolves. This change wasn’t included in the previous IdentityModel release but will be part of the upcoming one. |
Notice that it didn't help 😕 |
|
@sruke @brentschmaltz ping, any ideas what the problem is and when this can be merged? |
…ndler_memory # Conflicts: # src/Microsoft.IdentityModel.JsonWebTokens/PublicAPI.Unshipped.txt
|
@sruke @brentschmaltz ping again :/ |
| /// <param name="maxCount">The maximum number of segments to count up to.</param> | ||
| /// <returns>The number of segments up to <paramref name="maxCount"/>.</returns> | ||
| internal static int CountJwtTokenPart(string token, int maxCount) | ||
| internal static int CountJwtTokenPart(ReadOnlySpan<char> token, int maxCount) |
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.
Why do we need this as ReadOnlySpan?
We don't like to remove the old method as that can cause issues when mixed versions are used.
We end up with a MethodNotFound exception
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.
We need it because without it the PR would not make sense as we'd need to work with strings again. If you want I can create a method that takes string and calls this one.
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.
@henrikwidlund i was thinking why ReadOnlySpan and not ReadOnlyMemory?
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.
Only reasons are passing a smaller object and that that's what the method works with. If that's what you're thinking about I don't understand your comment about method not found as that would happen regardless.
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.
@brentschmaltz I believe older versions of .NET does not support regular expressions for ReadOnlySpan, and this library targets older versions of .NET. This is the reason ReadOnlyMemory is used in the CanReadToken method.
ReadOnlySpan is more efficient and what libraries should use/support whenever possible.
I agreee that supporting string would be useful, even if it is basically just a wrapper for the new method.
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.
So what's your suggestion, add back the string based one and have that one call the span one, or close the PR?
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.
So what's your suggestion, add back the string based one and have that one call the span one, or close the PR?
Yes, that is what we are thinking.
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.
Which of them? I can do both, but it would be a bit of a waste 😅
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.
add back the string based one and have that one call the span one,
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.
Okay, done :)
|
Is this PR still wanted? It's been open for four months now. @brentschmaltz @sruke @jennyf19 |
|
@henrikwidlund Sorry about the delay. I'm on holiday next week. I'll bring this up with the team, if there's available bandwidth; otherwise, I'll follow up on this after I'm back. |
Add Memory based overload for CanReadToken
Description
Added an overload for the
CanReadTokeninJsonWebTokenHandlerandJwtSecurityTokenHandlerwithReadOnlyMemory<char>to reduce allocations and adjusted thestringbased overload to call the new method.New overload is only available on dotnet 8 and above as the span based regex methods used to match JWS/JWE isn't available in dotnet 6.
Fixes #3221