parent
435867e8c5
commit
5170c31b23
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
|
@ -284,23 +285,25 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
// and we want to display the most specific message possible.
|
||||
switch (ex)
|
||||
{
|
||||
case SecurityTokenInvalidAudienceException _:
|
||||
messages.Add("The audience is invalid");
|
||||
case SecurityTokenInvalidAudienceException stia:
|
||||
messages.Add($"The audience '{stia.InvalidAudience ?? "(null)"}' is invalid");
|
||||
break;
|
||||
case SecurityTokenInvalidIssuerException _:
|
||||
messages.Add("The issuer is invalid");
|
||||
case SecurityTokenInvalidIssuerException stii:
|
||||
messages.Add($"The issuer '{stii.InvalidIssuer ?? "(null)"}' is invalid");
|
||||
break;
|
||||
case SecurityTokenNoExpirationException _:
|
||||
messages.Add("The token has no expiration");
|
||||
break;
|
||||
case SecurityTokenInvalidLifetimeException _:
|
||||
messages.Add("The token lifetime is invalid");
|
||||
case SecurityTokenInvalidLifetimeException stil:
|
||||
messages.Add("The token lifetime is invalid; NotBefore: "
|
||||
+ $"'{stil.NotBefore?.ToString(CultureInfo.InvariantCulture) ?? "(null)"}'"
|
||||
+ $", Expires: '{stil.Expires?.ToString(CultureInfo.InvariantCulture) ?? "(null)"}'");
|
||||
break;
|
||||
case SecurityTokenNotYetValidException _:
|
||||
messages.Add("The token is not valid yet");
|
||||
case SecurityTokenNotYetValidException stnyv:
|
||||
messages.Add($"The token is not valid before '{stnyv.NotBefore.ToString(CultureInfo.InvariantCulture)}'");
|
||||
break;
|
||||
case SecurityTokenExpiredException _:
|
||||
messages.Add("The token is expired");
|
||||
case SecurityTokenExpiredException ste:
|
||||
messages.Add($"The token expired at '{ste.Expires.ToString(CultureInfo.InvariantCulture)}'");
|
||||
break;
|
||||
case SecurityTokenSignatureKeyNotFoundException _:
|
||||
messages.Add("The signature key was not found");
|
||||
|
|
|
|||
|
|
@ -239,12 +239,12 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(SecurityTokenInvalidAudienceException), "The audience is invalid")]
|
||||
[InlineData(typeof(SecurityTokenInvalidIssuerException), "The issuer is invalid")]
|
||||
[InlineData(typeof(SecurityTokenInvalidAudienceException), "The audience '(null)' is invalid")]
|
||||
[InlineData(typeof(SecurityTokenInvalidIssuerException), "The issuer '(null)' is invalid")]
|
||||
[InlineData(typeof(SecurityTokenNoExpirationException), "The token has no expiration")]
|
||||
[InlineData(typeof(SecurityTokenInvalidLifetimeException), "The token lifetime is invalid")]
|
||||
[InlineData(typeof(SecurityTokenNotYetValidException), "The token is not valid yet")]
|
||||
[InlineData(typeof(SecurityTokenExpiredException), "The token is expired")]
|
||||
[InlineData(typeof(SecurityTokenInvalidLifetimeException), "The token lifetime is invalid; NotBefore: '(null)', Expires: '(null)'")]
|
||||
[InlineData(typeof(SecurityTokenNotYetValidException), "The token is not valid before '01/01/0001 00:00:00'")]
|
||||
[InlineData(typeof(SecurityTokenExpiredException), "The token expired at '01/01/0001 00:00:00'")]
|
||||
[InlineData(typeof(SecurityTokenInvalidSignatureException), "The signature is invalid")]
|
||||
[InlineData(typeof(SecurityTokenSignatureKeyNotFoundException), "The signature key was not found")]
|
||||
public async Task ExceptionReportedInHeaderForAuthenticationFailures(Type errorType, string message)
|
||||
|
|
@ -261,6 +261,26 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
Assert.Equal("", response.ResponseText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(SecurityTokenInvalidAudienceException), "The audience 'Bad Audience' is invalid")]
|
||||
[InlineData(typeof(SecurityTokenInvalidIssuerException), "The issuer 'Bad Issuer' is invalid")]
|
||||
[InlineData(typeof(SecurityTokenInvalidLifetimeException), "The token lifetime is invalid; NotBefore: '01/15/2001 00:00:00', Expires: '02/20/2000 00:00:00'")]
|
||||
[InlineData(typeof(SecurityTokenNotYetValidException), "The token is not valid before '01/15/2045 00:00:00'")]
|
||||
[InlineData(typeof(SecurityTokenExpiredException), "The token expired at '02/20/2000 00:00:00'")]
|
||||
public async Task ExceptionReportedInHeaderWithDetailsForAuthenticationFailures(Type errorType, string message)
|
||||
{
|
||||
var server = CreateServer(options =>
|
||||
{
|
||||
options.SecurityTokenValidators.Clear();
|
||||
options.SecurityTokenValidators.Add(new DetailedInvalidTokenValidator(errorType));
|
||||
});
|
||||
|
||||
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
|
||||
Assert.Equal($"Bearer error=\"invalid_token\", error_description=\"{message}\"", response.Response.Headers.WwwAuthenticate.First().ToString());
|
||||
Assert.Equal("", response.ResponseText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(ArgumentException))]
|
||||
public async Task ExceptionNotReportedInHeaderForOtherFailures(Type errorType)
|
||||
|
|
@ -289,7 +309,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
|
||||
Assert.Equal("Bearer error=\"invalid_token\", error_description=\"The audience is invalid; The signature key was not found\"",
|
||||
Assert.Equal("Bearer error=\"invalid_token\", error_description=\"The audience '(null)' is invalid; The signature key was not found\"",
|
||||
response.Response.Headers.WwwAuthenticate.First().ToString());
|
||||
Assert.Equal("", response.ResponseText);
|
||||
}
|
||||
|
|
@ -691,6 +711,69 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
}
|
||||
|
||||
class DetailedInvalidTokenValidator : ISecurityTokenValidator
|
||||
{
|
||||
public DetailedInvalidTokenValidator()
|
||||
{
|
||||
ExceptionType = typeof(SecurityTokenException);
|
||||
}
|
||||
|
||||
public DetailedInvalidTokenValidator(Type exceptionType)
|
||||
{
|
||||
ExceptionType = exceptionType;
|
||||
}
|
||||
|
||||
public Type ExceptionType { get; set; }
|
||||
|
||||
public bool CanValidateToken => true;
|
||||
|
||||
public int MaximumTokenSizeInBytes
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool CanReadToken(string securityToken) => true;
|
||||
|
||||
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
|
||||
{
|
||||
if (ExceptionType == typeof(SecurityTokenInvalidAudienceException))
|
||||
{
|
||||
throw new SecurityTokenInvalidAudienceException("SecurityTokenInvalidAudienceException") { InvalidAudience = "Bad Audience" };
|
||||
}
|
||||
if (ExceptionType == typeof(SecurityTokenInvalidIssuerException))
|
||||
{
|
||||
throw new SecurityTokenInvalidIssuerException("SecurityTokenInvalidIssuerException") { InvalidIssuer = "Bad Issuer" };
|
||||
}
|
||||
if (ExceptionType == typeof(SecurityTokenInvalidLifetimeException))
|
||||
{
|
||||
throw new SecurityTokenInvalidLifetimeException("SecurityTokenInvalidLifetimeException")
|
||||
{
|
||||
NotBefore = new DateTime(2001, 1, 15),
|
||||
Expires = new DateTime(2000, 2, 20),
|
||||
};
|
||||
}
|
||||
if (ExceptionType == typeof(SecurityTokenNotYetValidException))
|
||||
{
|
||||
throw new SecurityTokenNotYetValidException("SecurityTokenNotYetValidException")
|
||||
{
|
||||
NotBefore = new DateTime(2045, 1, 15),
|
||||
};
|
||||
}
|
||||
if (ExceptionType == typeof(SecurityTokenExpiredException))
|
||||
{
|
||||
throw new SecurityTokenExpiredException("SecurityTokenExpiredException")
|
||||
{
|
||||
Expires = new DateTime(2000, 2, 20),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException(ExceptionType.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BlobTokenValidator : ISecurityTokenValidator
|
||||
{
|
||||
private Action<string> _tokenValidator;
|
||||
|
|
|
|||
Loading…
Reference in New Issue