Improve performance of ClaimsIdentity #58793
Labels
api-suggestion
Early API idea and discussion, it is NOT ready for implementation
area-identity
Includes: Identity and providers
Perf
Milestone
Background and Motivation
.NET 4.5 introduced
ClaimsIdentity
,ClaimsPrincipal
, andClaim
as a standard way to represent the claims in aSecurityToken
. 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. TheJsonWebToken.Claims
collection is lazily created by iterating through that dictionary and creating and adding a newClaim
instance for each claim value. WhenClaimsIdentity
is requested and IdentityModel creates one, it iterates through a collection of JsonWebToken.Claims, creates a newClaim
, and adds it to an instance ofClaimsIdentity
to be returned. WhenClaimsIdentity
methods likeHasClaim
andFindFirst
are called, they operate on theIEnumerable<Claim>
in thatClaimsIdentity
instance. The fullClaim
collection is created even if only one claim is needed. Methods likeHasClaim
have to iterate through the wholeClaim
collection.Proposed API
IdentityModel introduces a new type,
SecurityTokenClaimsIdentity
, which will derive fromClaimsIdentity
. When ASP.NET uses IdentityModel an instance of this new type will be returned.SecurityTokenClaimsIdentity
holds a backing instance ofJsonWebToken
(it's of more general typeSecurityToken
, but currently onlyJsonWebToken
supported). Operations likeHasClaim
andFindFirst
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
andHasClaim
.This change does mean that the
ClaimsIdentity
is now case-sensitive. IdentityModel 8 already introducedCaseSensitiveClaimsIdentity
and uses it by default. The goal is for the behavior ofSecurityTokenClaimsIdentity
operations to match the behavior ofClaimsIdentity
(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 likeJwtBearerOptions
,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
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 byClaim
reference whileJsonWebToken
compares by claim type and claim value. Work will need to be done to make sureSecurityTokenClaimsIdentity
behavior is on par withClaimsIdentity
in these cases.The text was updated successfully, but these errors were encountered: