33using System ;
44using System . Collections . Generic ;
55using System . Diagnostics . CodeAnalysis ;
6- using System . IdentityModel . Tokens . Jwt ;
76using System . Linq ;
87using System . Reflection ;
98using System . Security . Claims ;
9+ using Microsoft . IdentityModel . JsonWebTokens ;
1010using Microsoft . IdentityModel . Tokens ;
1111
1212namespace Devlooped . Sponsors ;
@@ -85,12 +85,12 @@ public static bool TryRead([NotNullWhen(true)] out ClaimsPrincipal? principal, I
8585 if ( string . IsNullOrWhiteSpace ( value . jwt ) || string . IsNullOrEmpty ( value . jwk ) )
8686 continue ;
8787
88- if ( Validate ( value . jwt , value . jwk , out var token , out var claims , false ) == ManifestStatus . Valid && claims != null )
88+ if ( Validate ( value . jwt , value . jwk , out var token , out var identity , false ) == ManifestStatus . Valid && identity != null )
8989 {
9090 if ( principal == null )
91- principal = claims ;
91+ principal = new ( identity ) ;
9292 else
93- principal . AddIdentities ( claims . Identities ) ;
93+ principal . AddIdentity ( identity ) ;
9494 }
9595 }
9696
@@ -103,13 +103,13 @@ public static bool TryRead([NotNullWhen(true)] out ClaimsPrincipal? principal, I
103103 /// <param name="jwt">The JWT to validate.</param>
104104 /// <param name="jwk">The key to validate the manifest signature with.</param>
105105 /// <param name="token">Except when returning <see cref="Status.Unknown"/>, returns the security token read from the JWT, even if signature check failed.</param>
106- /// <param name="principal ">The associated claims, only when return value is not <see cref="Status.Unknown"/>.</param>
106+ /// <param name="identity ">The associated claims, only when return value is not <see cref="Status.Unknown"/>.</param>
107107 /// <param name="requireExpiration">Whether to check for expiration.</param>
108108 /// <returns>The status of the validation.</returns>
109- public static ManifestStatus Validate ( string jwt , string jwk , out SecurityToken ? token , out ClaimsPrincipal ? principal , bool validateExpiration )
109+ public static ManifestStatus Validate ( string jwt , string jwk , out SecurityToken ? token , out ClaimsIdentity ? identity , bool validateExpiration )
110110 {
111111 token = default ;
112- principal = default ;
112+ identity = default ;
113113
114114 SecurityKey key ;
115115 try
@@ -121,7 +121,7 @@ public static ManifestStatus Validate(string jwt, string jwk, out SecurityToken?
121121 return ManifestStatus . Unknown ;
122122 }
123123
124- var handler = new JwtSecurityTokenHandler { MapInboundClaims = false } ;
124+ var handler = new JsonWebTokenHandler { MapInboundClaims = false } ;
125125
126126 if ( ! handler . CanReadToken ( jwt ) )
127127 return ManifestStatus . Unknown ;
@@ -138,32 +138,35 @@ public static ManifestStatus Validate(string jwt, string jwk, out SecurityToken?
138138 NameClaimType = "sub" ,
139139 } ;
140140
141- try
141+ var result = handler . ValidateTokenAsync ( jwt , validation ) . Result ;
142+ if ( result . Exception != null )
142143 {
143- principal = handler . ValidateToken ( jwt , validation , out token ) ;
144- if ( validateExpiration && token . ValidTo == DateTime . MinValue )
144+ if ( result . Exception is SecurityTokenInvalidSignatureException )
145+ {
146+ var jwtToken = handler . ReadJsonWebToken ( jwt ) ;
147+ token = jwtToken ;
148+ identity = new ClaimsIdentity ( jwtToken . Claims ) ;
149+ return ManifestStatus . Invalid ;
150+ }
151+ else
152+ {
153+ var jwtToken = handler . ReadJsonWebToken ( jwt ) ;
154+ token = jwtToken ;
155+ identity = new ClaimsIdentity ( jwtToken . Claims ) ;
145156 return ManifestStatus . Invalid ;
157+ }
158+ }
146159
147- // The sponsorable manifest does not have an expiration time.
148- if ( validateExpiration && token . ValidTo < DateTimeOffset . UtcNow )
149- return ManifestStatus . Expired ;
160+ token = result . SecurityToken ;
161+ identity = new ClaimsIdentity ( result . ClaimsIdentity . Claims ) ;
150162
151- return ManifestStatus . Valid ;
152- }
153- catch ( SecurityTokenInvalidSignatureException )
154- {
155- var jwtToken = handler . ReadJwtToken ( jwt ) ;
156- token = jwtToken ;
157- principal = new ClaimsPrincipal ( new ClaimsIdentity ( jwtToken . Claims ) ) ;
158- return ManifestStatus . Invalid ;
159- }
160- catch ( SecurityTokenException )
161- {
162- var jwtToken = handler . ReadJwtToken ( jwt ) ;
163- token = jwtToken ;
164- principal = new ClaimsPrincipal ( new ClaimsIdentity ( jwtToken . Claims ) ) ;
163+ if ( validateExpiration && token . ValidTo == DateTime . MinValue )
165164 return ManifestStatus . Invalid ;
166- }
167- }
168165
166+ // The sponsorable manifest does not have an expiration time.
167+ if ( validateExpiration && token . ValidTo < DateTimeOffset . UtcNow )
168+ return ManifestStatus . Expired ;
169+
170+ return ManifestStatus . Valid ;
171+ }
169172}
0 commit comments