Skip to content

Improve performance of ClaimsIdentity #58793

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

Open
pmaytak opened this issue Nov 5, 2024 · 3 comments
Open

Improve performance of ClaimsIdentity #58793

pmaytak opened this issue Nov 5, 2024 · 3 comments
Assignees
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-identity Includes: Identity and providers Perf

Comments

@pmaytak
Copy link

pmaytak commented Nov 5, 2024

Background and Motivation

.NET 4.5 introduced ClaimsIdentity, ClaimsPrincipal, and Claim as a standard way to represent the claims in a SecurityToken. Since then there are performance and consistency improvements that can be made.

ASP.NET Core uses Microsoft.IdentityModel.* 7.x packages. In this version, when IdentityModel reads an incoming token, it parses it into a JsonWebToken instance and the claims are stored in a dictionary. The JsonWebToken.Claims collection is lazily created by iterating through that dictionary and creating and adding a new Claim instance for each claim value. When ClaimsIdentity is requested and IdentityModel creates one, it iterates through a collection of JsonWebToken.Claims, creates a new Claim, and adds it to an instance of ClaimsIdentity to be returned. When ClaimsIdentity methods like HasClaim and FindFirst are called, they operate on the IEnumerable<Claim> in that ClaimsIdentity instance. The full Claim collection is created even if only one claim is needed. Methods like HasClaim have to iterate through the whole Claim collection.

Proposed API

IdentityModel introduces a new type, SecurityTokenClaimsIdentity, which will derive from ClaimsIdentity. When ASP.NET uses IdentityModel an instance of this new type will be returned. SecurityTokenClaimsIdentity holds a backing instance of JsonWebToken (it's of more general type SecurityToken, but currently only JsonWebToken supported). Operations like HasClaim and FindFirst will now look in the claims dictionary. Claim collection will be generated only when all claims are requested and only once.

This PR shows initial in-progress proposal. The initial performance results show ~65% reduction in latency and ~40% reduction in allocations for FindFirst and HasClaim.

This change does mean that the ClaimsIdentity is now case-sensitive. IdentityModel 8 already introduced CaseSensitiveClaimsIdentity and uses it by default. The goal is for the behavior of SecurityTokenClaimsIdentity operations to match the behavior of ClaimsIdentity (except the case-sensitivity).

Once SecurityTokenClaimsIdentity is generally available, ASP.NET can upgrade the IdentityModel package and use that type internally. IdentityModel will provide a flag to enable or disable the use of this new type by default.

ASP.NET can also expose a flag, like UseSecurityTokenClaimsIdentity in an options class like JwtBearerOptions, OpenIdConnectOptions.

Usage Examples

ASP.NET can still use ClaimsIdentity as a return type in methods, only the implementation and case sensitive behavior will change as stated above. The users can use the new ASP.NET version without any changes in their code.

Alternative Designs

ASP.NET can make this new ClaimsIdentity behavior opt-in and expose an options flag to enable it.

Risks

  • The new ClaimsIdentity type will be case-sensitive, which is a breaking change.
  • JsonWebToken doesn't support adding and removing claims; ClaimsIdentity does. Also for these operations, ClaimsIdentity does a comparison by Claim reference while JsonWebToken compares by claim type and claim value. Work will need to be done to make sure SecurityTokenClaimsIdentity behavior is on par with ClaimsIdentity in these cases.
@pmaytak pmaytak added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Nov 5, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-identity Includes: Identity and providers label Nov 5, 2024
@javiercn
Copy link
Member

javiercn commented Nov 5, 2024

@pmaytak thanks for letting us know.

In general, if IdentityModel provides a better implementation we will likely adopt it provided there are no drawbacks.

@MackinnonBuck
Copy link
Member

@pmaytak, does Microsoft.IdentityModel still plan to add the new SecurityTokenClaimsIdentity type?

@pmaytak
Copy link
Author

pmaytak commented Apr 19, 2025

@pmaytak, does Microsoft.IdentityModel still plan to add the new SecurityTokenClaimsIdentity type?

That work is postponed for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-identity Includes: Identity and providers Perf
Projects
None yet
Development

No branches or pull requests

4 participants