Skip to content
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

ValidateTokenAsync - New Path: Refactor result types #2794

Merged
merged 35 commits into from
Aug 28, 2024

Conversation

iNinja
Copy link
Contributor

@iNinja iNinja commented Aug 23, 2024

ValidateTokenAsync - New Path: Refactor result types

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • If any gains or losses in performance are possible, you've included benchmarks for your changes. More info
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Refactored Result types to reduce allocations and improve performance.

Description

  • Added Result type (before making this public we may want to rename it to avoid clashes with a future .NET result type)
  • Removed all token validation result types (IssuerValidationResult, AudienceValidationResult, ...)
  • Repurposed ValidationResult as a new result type for the new path.
  • Added extra stack frames when returning validation results. Added basic caching for a single path to validate.
  • Return Result<ValidationResult, ExceptionDetail> from TokenValidationAsync to limit ValidationResult to only success scenarios, simplifying scenarios like creating and accessing the ClaimsIdentity.
  • Removed ValidateTokenAsyncInternal since we now return the same Result from all methods, it is no longer required.
  • Added ValidationFailureType to ExceptionDetail
  • Updated tests

Next steps after this:

  • Possibly rename it to something more generic for an Error type that can create exceptions.
  • Add capabilities to ExceptionDetail to pass extra data to the exception when being created (invalid issuer, audience)
  • Re-implement Activator to create the exception from Details in a AOT compliant way (was removed time ago to restore AOT compatibility)

Benchmarks for this work:

Method Mean Error StdDev P90 P95 P100 Ratio RatioSD Gen0 Gen1 Allocated Alloc Ratio
JsonWebTokenHandler_ValidateTokenAsyncWithTVP_CreateClaims 38.81 us 0.130 us 0.284 us 39.17 us 39.26 us 39.85 us 1.00 0.00 0.6104 - 16.48 KB 1.00
JsonWebTokenHandler_ValidateTokenAsyncWithVP_CreateClaims 38.13 us 0.097 us 0.209 us 38.39 us 38.45 us 38.61 us 0.98 0.01 0.6104 - 16.02 KB 0.97
JsonWebTokenHandler_ValidateTokenAsyncWithTVP_SucceedOnFifthAttempt 102.50 us 0.773 us 1.698 us 105.37 us 106.85 us 107.95 us 1.00 0.00 1.4648 - 37.13 KB 1.00
JsonWebTokenHandler_ValidateTokenAsyncWithTVPUsingClone_SucceedOnFifthAttempt 103.07 us 0.250 us 0.544 us 103.90 us 104.00 us 104.43 us 1.01 0.02 1.5869 - 38.89 KB 1.05
JsonWebTokenHandler_ValidateTokenAsyncWithVP_SucceedOnFifthAttempt 69.09 us 0.266 us 0.572 us 69.73 us 70.15 us 70.46 us 0.67 0.01 1.2207 - 32.7 KB 0.88
JsonWebTokenHandler_ValidateTokenAsyncWithTVP_SucceedOnThirdAttempt 68.77 us 0.186 us 0.397 us 69.33 us 69.52 us 69.95 us 1.00 0.00 0.8545 - 22.18 KB 1.00
JsonWebTokenHandler_ValidateTokenAsyncWithTVPUsingClone_SucceedOnThirdAttempt 68.80 us 0.132 us 0.288 us 69.16 us 69.25 us 69.80 us 1.00 0.00 0.8545 - 23.23 KB 1.05
JsonWebTokenHandler_ValidateTokenAsyncWithVP_SucceedOnThirdAttempt 51.37 us 0.122 us 0.268 us 51.68 us 51.70 us 51.95 us 0.75 0.00 0.7935 - 19.7 KB 0.89
JsonWebTokenHandler_ValidateTokenAsyncWithTVP 34.25 us 0.131 us 0.279 us 34.66 us 34.80 us 35.42 us 1.00 0.00 0.2441 - 7.23 KB 1.00
JsonWebTokenHandler_ValidateTokenAsyncWithTVPUsingModifiedClone 50.68 us 0.085 us 0.175 us 50.91 us 50.93 us 51.00 us 1.48 0.01 0.3662 - 9.66 KB 1.34
JsonWebTokenHandler_ValidateTokenAsyncWithVP 33.80 us 0.032 us 0.070 us 33.90 us 33.92 us 33.93 us 0.99 0.01 0.2441 - 6.7 KB 0.93
JwtSecurityTokenHandler_ValidateTokenAsync 41.49 us 0.087 us 0.184 us 41.70 us 41.81 us 42.07 us 1.21 0.01 1.0376 0.0610 25.58 KB 3.54

Sample exception message + stack trace generated with the new stack frames:

IDX10500: Signature validation failed. No security keys were provided to validate the signature.
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateSignature(JsonWebToken jwtToken, ValidationParameters validationParameters, BaseConfiguration configuration, CallContext callContext) in C:\git\wilson\src\Microsoft.IdentityModel.JsonWebTokens\JsonWebTokenHandler.ValidateSignature.cs:line 99
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWSAsync(JsonWebToken jsonWebToken, ValidationParameters validationParameters, BaseConfiguration configuration, CallContext callContext, CancellationToken cancellationToken) in C:\git\wilson\src\Microsoft.IdentityModel.JsonWebTokens\JsonWebTokenHandler.ValidateToken.Internal.cs:line 339
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(SecurityToken token, ValidationParameters validationParameters, CallContext callContext, CancellationToken cancellationToken) in C:\git\wilson\src\Microsoft.IdentityModel.JsonWebTokens\JsonWebTokenHandler.ValidateToken.Internal.cs:line 139
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(String token, ValidationParameters validationParameters, CallContext callContext, CancellationToken cancellationToken) in C:\git\wilson\src\Microsoft.IdentityModel.JsonWebTokens\JsonWebTokenHandler.ValidateToken.Internal.cs:line 86

Part of #2711

Franco Fung and others added 20 commits August 13, 2024 09:16
Adding Result and Unit type. Experiment around allocations and performance.
…sult return values to use implicit initialisation
…dated tests for Algorithm and Audience validation
…es to failures, added initial cache experiment for stack frames
@iNinja iNinja requested a review from a team as a code owner August 23, 2024 17:59
iNinja added 3 commits August 27, 2024 17:54
# Conflicts:
#	test/Microsoft.IdentityModel.Tokens.Tests/Validation/AsyncValidatorsTests.cs
#	test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs
Copy link
Contributor

@FuPingFranco FuPingFranco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a couple of minor things like removing the additional imports, flaky test and a couple of questions.

@brentschmaltz brentschmaltz merged commit ff63778 into dev Aug 28, 2024
6 checks passed
brentschmaltz pushed a commit that referenced this pull request Sep 8, 2024
* Adding benchmark for new ValidateTokenAsync model vs old.

* Update benchmark/Microsoft.IdentityModel.Benchmarks/ValidateTokenAsyncWithVPTests.cs

* Removed IdentityComparer methods relating to removed result types. Updated tests for Algorithm and Audience validation

* Removed ITokenValidationError interface. Updated tests

* Replaced TokenValidationError with ExceptionDetails. Added stack frames to failures, added initial cache experiment for stack frames

* Removed optionality from CancellationToken parameter

* Updated tests

* Added ClaimsIdentity to ValidationResult

* Updated benchmarks to match the result types and added CancellationToken

* Removed test consoleapp, re-grouped benchmarks for better comparison

* Removed unit type

* Removed TokenValidationError since it is no longer used

* Restored ExceptionType type name

* Restored ExceptionFromType method in ExceptionDetail

* Override Result's empty initialiser and annotate it to prevent wrong initialisation

* Removed commented code.

* Commented empty if statement

* Added cached stack frames and nullability annotations for ValidateTokenAsync
Changed return type to use Result and removed error information from ValidationResult
Added method to add StackFrames to ExceptionDetail

* Added stack frames for ReadToken and DecryptToken

* Added ValidationFailureType to ExceptionDetail

* Updated tests to use ValidationFailureType

* Update src/Microsoft.IdentityModel.Abstractions/Result.cs

Co-authored-by: Keegan Caruso <[email protected]>

* Moved Result to Tokens project, made it internal. Reverted TargetFrameworks change to LoggingExtensions

* Addressed PR feedback around argument null exceptions

* Addressed PR comments. Removed unused imports. Increased epsilon for datetime comparison in tests.

---------

Co-authored-by: Franco Fung <[email protected]>
Co-authored-by: Franco Fung <[email protected]>
Co-authored-by: Keegan Caruso <[email protected]>

Add benchmark to test validation with an issuer delegate using string vs bytes issuer.

Add a class with profiler methods.
brentschmaltz pushed a commit that referenced this pull request Sep 9, 2024
* Adding benchmark for new ValidateTokenAsync model vs old.

* Update benchmark/Microsoft.IdentityModel.Benchmarks/ValidateTokenAsyncWithVPTests.cs

* Removed IdentityComparer methods relating to removed result types. Updated tests for Algorithm and Audience validation

* Removed ITokenValidationError interface. Updated tests

* Replaced TokenValidationError with ExceptionDetails. Added stack frames to failures, added initial cache experiment for stack frames

* Removed optionality from CancellationToken parameter

* Updated tests

* Added ClaimsIdentity to ValidationResult

* Updated benchmarks to match the result types and added CancellationToken

* Removed test consoleapp, re-grouped benchmarks for better comparison

* Removed unit type

* Removed TokenValidationError since it is no longer used

* Restored ExceptionType type name

* Restored ExceptionFromType method in ExceptionDetail

* Override Result's empty initialiser and annotate it to prevent wrong initialisation

* Removed commented code.

* Commented empty if statement

* Added cached stack frames and nullability annotations for ValidateTokenAsync
Changed return type to use Result and removed error information from ValidationResult
Added method to add StackFrames to ExceptionDetail

* Added stack frames for ReadToken and DecryptToken

* Added ValidationFailureType to ExceptionDetail

* Updated tests to use ValidationFailureType

* Update src/Microsoft.IdentityModel.Abstractions/Result.cs

Co-authored-by: Keegan Caruso <[email protected]>

* Moved Result to Tokens project, made it internal. Reverted TargetFrameworks change to LoggingExtensions

* Addressed PR feedback around argument null exceptions

* Addressed PR comments. Removed unused imports. Increased epsilon for datetime comparison in tests.

---------

Co-authored-by: Franco Fung <[email protected]>
Co-authored-by: Franco Fung <[email protected]>
Co-authored-by: Keegan Caruso <[email protected]>

Add benchmark to test validation with an issuer delegate using string vs bytes issuer.

Add a class with profiler methods.
@jennyf19 jennyf19 added this to the 8.0.3 milestone Sep 20, 2024
@iNinja iNinja deleted the iinglese/refactor-results branch November 15, 2024 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants