@@ -239,12 +239,12 @@ public async Task InvalidTokenReceived()
239
239
}
240
240
241
241
[ Theory ]
242
- [ InlineData ( typeof ( SecurityTokenInvalidAudienceException ) , "The audience is invalid" ) ]
243
- [ InlineData ( typeof ( SecurityTokenInvalidIssuerException ) , "The issuer is invalid" ) ]
242
+ [ InlineData ( typeof ( SecurityTokenInvalidAudienceException ) , "The audience '(null)' is invalid" ) ]
243
+ [ InlineData ( typeof ( SecurityTokenInvalidIssuerException ) , "The issuer '(null)' is invalid" ) ]
244
244
[ InlineData ( typeof ( SecurityTokenNoExpirationException ) , "The token has no expiration" ) ]
245
- [ InlineData ( typeof ( SecurityTokenInvalidLifetimeException ) , "The token lifetime is invalid" ) ]
246
- [ InlineData ( typeof ( SecurityTokenNotYetValidException ) , "The token is not valid yet " ) ]
247
- [ InlineData ( typeof ( SecurityTokenExpiredException ) , "The token is expired" ) ]
245
+ [ InlineData ( typeof ( SecurityTokenInvalidLifetimeException ) , "The token lifetime is invalid; NotBefore: '(null)', Expires: '(null)' " ) ]
246
+ [ InlineData ( typeof ( SecurityTokenNotYetValidException ) , "The token is not valid before '01/01/0001 00:00:00' " ) ]
247
+ [ InlineData ( typeof ( SecurityTokenExpiredException ) , "The token expired at '01/01/0001 00:00:00' " ) ]
248
248
[ InlineData ( typeof ( SecurityTokenInvalidSignatureException ) , "The signature is invalid" ) ]
249
249
[ InlineData ( typeof ( SecurityTokenSignatureKeyNotFoundException ) , "The signature key was not found" ) ]
250
250
public async Task ExceptionReportedInHeaderForAuthenticationFailures ( Type errorType , string message )
@@ -261,6 +261,26 @@ public async Task ExceptionReportedInHeaderForAuthenticationFailures(Type errorT
261
261
Assert . Equal ( "" , response . ResponseText ) ;
262
262
}
263
263
264
+ [ Theory ]
265
+ [ InlineData ( typeof ( SecurityTokenInvalidAudienceException ) , "The audience 'Bad Audience' is invalid" ) ]
266
+ [ InlineData ( typeof ( SecurityTokenInvalidIssuerException ) , "The issuer 'Bad Issuer' is invalid" ) ]
267
+ [ InlineData ( typeof ( SecurityTokenInvalidLifetimeException ) , "The token lifetime is invalid; NotBefore: '01/15/2001 00:00:00', Expires: '02/20/2000 00:00:00'" ) ]
268
+ [ InlineData ( typeof ( SecurityTokenNotYetValidException ) , "The token is not valid before '01/15/2045 00:00:00'" ) ]
269
+ [ InlineData ( typeof ( SecurityTokenExpiredException ) , "The token expired at '02/20/2000 00:00:00'" ) ]
270
+ public async Task ExceptionReportedInHeaderWithDetailsForAuthenticationFailures ( Type errorType , string message )
271
+ {
272
+ var server = CreateServer ( options =>
273
+ {
274
+ options . SecurityTokenValidators . Clear ( ) ;
275
+ options . SecurityTokenValidators . Add ( new DetailedInvalidTokenValidator ( errorType ) ) ;
276
+ } ) ;
277
+
278
+ var response = await SendAsync ( server , "http://example.com/oauth" , "Bearer someblob" ) ;
279
+ Assert . Equal ( HttpStatusCode . Unauthorized , response . Response . StatusCode ) ;
280
+ Assert . Equal ( $ "Bearer error=\" invalid_token\" , error_description=\" { message } \" ", response . Response . Headers . WwwAuthenticate . First ( ) . ToString ( ) ) ;
281
+ Assert . Equal ( "" , response . ResponseText ) ;
282
+ }
283
+
264
284
[ Theory ]
265
285
[ InlineData ( typeof ( ArgumentException ) ) ]
266
286
public async Task ExceptionNotReportedInHeaderForOtherFailures ( Type errorType )
@@ -289,7 +309,7 @@ public async Task ExceptionsReportedInHeaderForMultipleAuthenticationFailures()
289
309
290
310
var response = await SendAsync ( server , "http://example.com/oauth" , "Bearer someblob" ) ;
291
311
Assert . Equal ( HttpStatusCode . Unauthorized , response . Response . StatusCode ) ;
292
- Assert . Equal ( "Bearer error=\" invalid_token\" , error_description=\" The audience is invalid; The signature key was not found\" " ,
312
+ Assert . Equal ( "Bearer error=\" invalid_token\" , error_description=\" The audience '(null)' is invalid; The signature key was not found\" " ,
293
313
response . Response . Headers . WwwAuthenticate . First ( ) . ToString ( ) ) ;
294
314
Assert . Equal ( "" , response . ResponseText ) ;
295
315
}
@@ -691,6 +711,69 @@ public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParame
691
711
}
692
712
}
693
713
714
+ class DetailedInvalidTokenValidator : ISecurityTokenValidator
715
+ {
716
+ public DetailedInvalidTokenValidator ( )
717
+ {
718
+ ExceptionType = typeof ( SecurityTokenException ) ;
719
+ }
720
+
721
+ public DetailedInvalidTokenValidator ( Type exceptionType )
722
+ {
723
+ ExceptionType = exceptionType ;
724
+ }
725
+
726
+ public Type ExceptionType { get ; set ; }
727
+
728
+ public bool CanValidateToken => true ;
729
+
730
+ public int MaximumTokenSizeInBytes
731
+ {
732
+ get { throw new NotImplementedException ( ) ; }
733
+ set { throw new NotImplementedException ( ) ; }
734
+ }
735
+
736
+ public bool CanReadToken ( string securityToken ) => true ;
737
+
738
+ public ClaimsPrincipal ValidateToken ( string securityToken , TokenValidationParameters validationParameters , out SecurityToken validatedToken )
739
+ {
740
+ if ( ExceptionType == typeof ( SecurityTokenInvalidAudienceException ) )
741
+ {
742
+ throw new SecurityTokenInvalidAudienceException ( "SecurityTokenInvalidAudienceException" ) { InvalidAudience = "Bad Audience" } ;
743
+ }
744
+ if ( ExceptionType == typeof ( SecurityTokenInvalidIssuerException ) )
745
+ {
746
+ throw new SecurityTokenInvalidIssuerException ( "SecurityTokenInvalidIssuerException" ) { InvalidIssuer = "Bad Issuer" } ;
747
+ }
748
+ if ( ExceptionType == typeof ( SecurityTokenInvalidLifetimeException ) )
749
+ {
750
+ throw new SecurityTokenInvalidLifetimeException ( "SecurityTokenInvalidLifetimeException" )
751
+ {
752
+ NotBefore = new DateTime ( 2001 , 1 , 15 ) ,
753
+ Expires = new DateTime ( 2000 , 2 , 20 ) ,
754
+ } ;
755
+ }
756
+ if ( ExceptionType == typeof ( SecurityTokenNotYetValidException ) )
757
+ {
758
+ throw new SecurityTokenNotYetValidException ( "SecurityTokenNotYetValidException" )
759
+ {
760
+ NotBefore = new DateTime ( 2045 , 1 , 15 ) ,
761
+ } ;
762
+ }
763
+ if ( ExceptionType == typeof ( SecurityTokenExpiredException ) )
764
+ {
765
+ throw new SecurityTokenExpiredException ( "SecurityTokenExpiredException" )
766
+ {
767
+ Expires = new DateTime ( 2000 , 2 , 20 ) ,
768
+ } ;
769
+ }
770
+ else
771
+ {
772
+ throw new NotImplementedException ( ExceptionType . Name ) ;
773
+ }
774
+ }
775
+ }
776
+
694
777
class BlobTokenValidator : ISecurityTokenValidator
695
778
{
696
779
private Action < string > _tokenValidator ;
0 commit comments