33
44using System ;
55using System . Collections . Generic ;
6+ using System . Diagnostics ;
67using System . Text ;
78using Microsoft . IdentityModel . Logging ;
89using Microsoft . IdentityModel . Tokens ;
@@ -139,10 +140,14 @@ private static ValidationResult<SecurityKey, ValidationError> ValidateSignatureU
139140 StringBuilder ? exceptionStrings = null ;
140141 StringBuilder ? keysAttempted = null ;
141142
143+ // We want to capture all stack frames that were involved with faults.
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 )
145- continue ; // skip null keys
150+ continue ;
146151
147152 keysTried = true ;
148153
@@ -154,68 +159,94 @@ 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+ foreach ( StackFrame stackFrame in validationError . StackFrames )
171+ stackFrames . Add ( stackFrame ) ;
172+
161173 exceptionStrings ??= new StringBuilder ( ) ;
162174 keysAttempted ??= new StringBuilder ( ) ;
163175 exceptionStrings . AppendLine ( validationError . MessageDetail . Message ) ;
164176 keysAttempted . AppendLine ( key . ToString ( ) ) ;
165177 }
166178 }
167179
180+ // This method tries a number of different keys, for each failure we add a stack frame to the stackFrames collection.
181+ // We want to add the current stack frame to the end of the list, to keep the order of the stack frames.
182+ // If for some reason stackFrames is null or empty, we add the current stack frame as the first and only entry.
183+ StackFrame currentStackFrame = ValidationError . GetCurrentStackFrame ( ) ;
184+ StackFrame firstStackFrame = ( stackFrames == null || stackFrames . Count == 0 ) ? currentStackFrame : stackFrames [ 0 ] ;
185+ SignatureValidationError signatureValidationError ;
186+
168187 if ( keysTried )
169188 {
170189 if ( kidExists )
171190 {
172- return new SignatureValidationError (
191+ signatureValidationError = new SignatureValidationError (
173192 new MessageDetail (
174193 TokenLogMessages . IDX10522 ,
175194 LogHelper . MarkAsNonPII ( jwtToken . Kid ) ,
176195 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
177196 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
178197 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
179198 SignatureValidationFailure . SigningKeyNotFound ,
180- ValidationError . GetCurrentStackFrame ( ) ) ;
199+ firstStackFrame ) ;
181200 }
182201 else
183202 {
184- return new SignatureValidationError (
203+ signatureValidationError = new SignatureValidationError (
185204 new MessageDetail (
186205 TokenLogMessages . IDX10523 ,
187206 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
188207 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
189208 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
190209 SignatureValidationFailure . SigningKeyNotFound ,
191- ValidationError . GetCurrentStackFrame ( ) ) ;
210+ firstStackFrame ) ;
192211 }
193212 }
194-
195- if ( kidExists )
213+ else if ( kidExists )
196214 {
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 (
215+ // There is a kid, but no keys were found.
216+ signatureValidationError = new SignatureValidationError (
201217 new MessageDetail (
202218 TokenLogMessages . IDX10524 ,
203219 LogHelper . MarkAsNonPII ( jwtToken . Kid ) ,
204220 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
205221 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
206222 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
207223 SignatureValidationFailure . SigningKeyNotFound ,
208- ValidationError . GetCurrentStackFrame ( ) ) ;
224+ firstStackFrame ) ;
225+ }
226+ else
227+ {
228+ signatureValidationError = new SignatureValidationError (
229+ new MessageDetail (
230+ TokenLogMessages . IDX10525 ,
231+ LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
232+ LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
233+ LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
234+ SignatureValidationFailure . SigningKeyNotFound ,
235+ firstStackFrame ) ;
209236 }
210237
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 ( ) ) ;
238+ if ( stackFrames != null )
239+ {
240+ for ( int i = 1 ; i < stackFrames . Count ; i ++ )
241+ {
242+ if ( stackFrames [ i ] != null )
243+ signatureValidationError . StackFrames . Add ( stackFrames [ i ] ) ;
244+ }
245+
246+ signatureValidationError . StackFrames . Add ( currentStackFrame ) ;
247+ }
248+
249+ return signatureValidationError ;
219250 }
220251
221252 private static ValidationResult < SecurityKey , ValidationError > ValidateSignatureWithKey (
@@ -234,7 +265,7 @@ private static ValidationResult<SecurityKey, ValidationError> ValidateSignatureW
234265 TokenLogMessages . IDX10652 ,
235266 LogHelper . MarkAsNonPII ( jsonWebToken . Alg ) ,
236267 key ) ,
237- AlgorithmValidationFailure . AlgorithmIsNotSupported ,
268+ AlgorithmValidationFailure . NotSupported ,
238269 ValidationError . GetCurrentStackFrame ( ) ) ;
239270 }
240271
0 commit comments