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,91 @@ 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+ StackFrame currentStackFrame = ValidationError . GetCurrentStackFrame ( ) ;
181+ StackFrame firstStackFrame = ( stackFrames == null ) ? currentStackFrame ! : stackFrames [ 0 ] ;
182+ SignatureValidationError signatureValidationError ;
183+
168184 if ( keysTried )
169185 {
170186 if ( kidExists )
171187 {
172- return new SignatureValidationError (
188+ signatureValidationError = new SignatureValidationError (
173189 new MessageDetail (
174190 TokenLogMessages . IDX10522 ,
175191 LogHelper . MarkAsNonPII ( jwtToken . Kid ) ,
176192 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
177193 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
178194 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
179195 SignatureValidationFailure . SigningKeyNotFound ,
180- ValidationError . GetCurrentStackFrame ( ) ) ;
196+ firstStackFrame ) ;
181197 }
182198 else
183199 {
184- return new SignatureValidationError (
200+ signatureValidationError = new SignatureValidationError (
185201 new MessageDetail (
186202 TokenLogMessages . IDX10523 ,
187203 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
188204 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
189205 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
190206 SignatureValidationFailure . SigningKeyNotFound ,
191- ValidationError . GetCurrentStackFrame ( ) ) ;
207+ firstStackFrame ) ;
192208 }
193209 }
194-
195- if ( kidExists )
210+ else if ( kidExists )
196211 {
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 (
212+ // There is a kid, but no keys were found.
213+ signatureValidationError = new SignatureValidationError (
201214 new MessageDetail (
202215 TokenLogMessages . IDX10524 ,
203216 LogHelper . MarkAsNonPII ( jwtToken . Kid ) ,
204217 LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
205218 LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
206219 LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
207220 SignatureValidationFailure . SigningKeyNotFound ,
208- ValidationError . GetCurrentStackFrame ( ) ) ;
221+ firstStackFrame ) ;
222+ }
223+ else
224+ {
225+ signatureValidationError = new SignatureValidationError (
226+ new MessageDetail (
227+ TokenLogMessages . IDX10525 ,
228+ LogHelper . MarkAsNonPII ( validationParameters . SigningKeys . Count ) ,
229+ LogHelper . MarkAsNonPII ( configuration ? . SigningKeys ? . Count ?? 0 ) ,
230+ LogHelper . MarkAsSecurityArtifact ( jwtToken . EncodedToken , JwtTokenUtilities . SafeLogJwtToken ) ) ,
231+ SignatureValidationFailure . SigningKeyNotFound ,
232+ firstStackFrame ) ;
209233 }
210234
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 ( ) ) ;
235+ if ( stackFrames != null )
236+ {
237+ for ( int i = 1 ; i < stackFrames . Count ; i ++ )
238+ {
239+ if ( stackFrames [ i ] != null )
240+ signatureValidationError . StackFrames . Add ( stackFrames [ i ] ) ;
241+ }
242+
243+ signatureValidationError . StackFrames . Add ( currentStackFrame ) ;
244+ }
245+
246+ return signatureValidationError ;
219247 }
220248
221249 private static ValidationResult < SecurityKey , ValidationError > ValidateSignatureWithKey (
@@ -234,7 +262,7 @@ private static ValidationResult<SecurityKey, ValidationError> ValidateSignatureW
234262 TokenLogMessages . IDX10652 ,
235263 LogHelper . MarkAsNonPII ( jsonWebToken . Alg ) ,
236264 key ) ,
237- AlgorithmValidationFailure . AlgorithmIsNotSupported ,
265+ AlgorithmValidationFailure . NotSupported ,
238266 ValidationError . GetCurrentStackFrame ( ) ) ;
239267 }
240268
0 commit comments