33
44using System ;
55using System . Collections . Generic ;
6+ using System . Diagnostics ;
67using System . Text ;
78using Microsoft . IdentityModel . Logging ;
89using Microsoft . IdentityModel . Tokens ;
@@ -139,6 +140,10 @@ private static ValidationResult<SecurityKey, ValidationError> ValidateSignatureU
139140 StringBuilder ? exceptionStrings = null ;
140141 StringBuilder ? keysAttempted = null ;
141142
143+ // We want to keep track of all stack frames that were used during validation.
144+ // We capture the stack frames and add to the error.
145+ IList < StackFrame > ? stackFrames = null ;
146+
142147 foreach ( SecurityKey key in keys )
143148 {
144149 if ( key is null )
@@ -154,68 +159,92 @@ private static ValidationResult<SecurityKey, ValidationError> ValidateSignatureU
154159 callContext ) ;
155160
156161 if ( result . Succeeded )
162+ {
163+ jwtToken . SigningKey = key ;
157164 return result ;
165+ }
158166
159167 if ( result . Error is ValidationError validationError )
160168 {
169+ stackFrames ??= [ ] ;
170+
171+ foreach ( StackFrame stackFrame in validationError . StackFrames )
172+ stackFrames . Add ( stackFrame ) ;
173+
161174 exceptionStrings ??= new StringBuilder ( ) ;
162175 keysAttempted ??= new StringBuilder ( ) ;
163176 exceptionStrings . AppendLine ( validationError . MessageDetail . Message ) ;
164177 keysAttempted . AppendLine ( key . ToString ( ) ) ;
165178 }
166179 }
167180
181+ StackFrame currentStackFrame = ValidationError . GetCurrentStackFrame ( ) ;
182+ StackFrame firstStackFrame = ( stackFrames == null ) ? currentStackFrame ! : stackFrames [ 0 ] ;
183+ SignatureValidationError signatureValidationError ;
184+
168185 if ( keysTried )
169186 {
170187 if ( kidExists )
171188 {
172- return new SignatureValidationError (
189+ signatureValidationError = new SignatureValidationError (
173190 new MessageDetail (
174191 TokenLogMessages . IDX10522 ,
175192 LogHelper . MarkAsNonPII ( jwtToken . Kid ) ,
176193 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
177194 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
178195 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
179196 SignatureValidationFailure . SigningKeyNotFound ,
180- ValidationError . GetCurrentStackFrame ( ) ) ;
197+ firstStackFrame ) ;
181198 }
182199 else
183200 {
184- return new SignatureValidationError (
201+ signatureValidationError = new SignatureValidationError (
185202 new MessageDetail (
186203 TokenLogMessages . IDX10523 ,
187204 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
188205 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
189206 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
190207 SignatureValidationFailure . SigningKeyNotFound ,
191- ValidationError . GetCurrentStackFrame ( ) ) ;
208+ firstStackFrame ) ;
192209 }
193210 }
194-
195- if ( kidExists )
211+ else if ( kidExists )
196212 {
197- // No keys were attempted, return the error.
198- // This is the case where the user specified a kid, but no keys were found.
199- // This is not an error, but a warning that no keys were found for the specified kid.
200- return new SignatureValidationError (
213+ // There is a kid, but no keys were found.
214+ signatureValidationError = new SignatureValidationError (
201215 new MessageDetail (
202216 TokenLogMessages . IDX10524 ,
203217 LogHelper . MarkAsNonPII ( jwtToken . Kid ) ,
204218 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
205219 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
206220 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
207221 SignatureValidationFailure . SigningKeyNotFound ,
208- ValidationError . GetCurrentStackFrame ( ) ) ;
222+ firstStackFrame ) ;
223+ }
224+ else
225+ {
226+ signatureValidationError = new SignatureValidationError (
227+ new MessageDetail (
228+ TokenLogMessages . IDX10525 ,
229+ LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
230+ LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
231+ LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
232+ SignatureValidationFailure . SigningKeyNotFound ,
233+ firstStackFrame ) ;
209234 }
210235
211- return new SignatureValidationError (
212- new MessageDetail (
213- TokenLogMessages . IDX10525 ,
214- LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
215- LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
216- LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
217- SignatureValidationFailure . SigningKeyNotFound ,
218- ValidationError . GetCurrentStackFrame ( ) ) ;
236+ if ( stackFrames != null )
237+ {
238+ for ( int i = 1 ; i < stackFrames . Count ; i ++ )
239+ {
240+ if ( stackFrames [ i ] != null )
241+ signatureValidationError . StackFrames . Add ( stackFrames [ i ] ) ;
242+ }
243+
244+ signatureValidationError . StackFrames . Add ( currentStackFrame ) ;
245+ }
246+
247+ return signatureValidationError ;
219248 }
220249
221250 private static ValidationResult < SecurityKey , ValidationError > ValidateSignatureWithKey (
@@ -234,7 +263,7 @@ private static ValidationResult<SecurityKey, ValidationError> ValidateSignatureW
234263 TokenLogMessages . IDX10652 ,
235264 LogHelper . MarkAsNonPII ( jsonWebToken . Alg ) ,
236265 key ) ,
237- AlgorithmValidationFailure . AlgorithmIsNotSupported ,
266+ AlgorithmValidationFailure . NotSupported ,
238267 ValidationError . GetCurrentStackFrame ( ) ) ;
239268 }
240269
0 commit comments