Throwing AntiforgeryValidationException for failure to deserializing tokens

This commit is contained in:
Kiran Challa 2018-01-08 16:56:03 -08:00
parent 0401377fe4
commit d2c27104dd
5 changed files with 50 additions and 4 deletions

View File

@ -12,12 +12,23 @@ namespace Microsoft.AspNetCore.Antiforgery
{
/// <summary>
/// Creates a new instance of <see cref="AntiforgeryValidationException"/> with the specified
/// exception <paramref name="message"/>.
/// exception message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public AntiforgeryValidationException(string message)
: base(message)
{
}
/// <summary>
/// Creates a new instance of <see cref="AntiforgeryValidationException"/> with the specified
/// exception message and inner exception.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="innerException">The inner <see cref="Exception"/>.</param>
public AntiforgeryValidationException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

View File

@ -8,6 +8,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
{
internal static class AntiforgeryLoggerExtensions
{
private static readonly Action<ILogger, Exception> _failedToDeserialzeTokens;
private static readonly Action<ILogger, string, Exception> _validationFailed;
private static readonly Action<ILogger, Exception> _validated;
private static readonly Action<ILogger, string, Exception> _missingCookieToken;
@ -54,6 +55,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
"The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " +
"'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery " +
"should not be cached.");
_failedToDeserialzeTokens = LoggerMessage.Define(
LogLevel.Debug,
9,
"Failed to deserialize antiforgery tokens.");
}
public static void ValidationFailed(this ILogger logger, string message)
@ -95,5 +100,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
{
_responseCacheHeadersOverridenToNoCache(logger, null);
}
public static void FailedToDeserialzeTokens(this ILogger logger, Exception exception)
{
_failedToDeserialzeTokens(logger, exception);
}
}
}

View File

@ -124,7 +124,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
// Extract cookie & request tokens
AntiforgeryToken deserializedCookieToken;
AntiforgeryToken deserializedRequestToken;
DeserializeTokens(httpContext, tokens, out deserializedCookieToken, out deserializedRequestToken);
if (!TryDeserializeTokens(httpContext, tokens, out deserializedCookieToken, out deserializedRequestToken))
{
return false;
}
// Validate
string message;
@ -197,6 +200,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
// Extract cookie & request tokens
AntiforgeryToken deserializedCookieToken;
AntiforgeryToken deserializedRequestToken;
DeserializeTokens(
httpContext,
antiforgeryTokenSet,
@ -430,6 +434,27 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
_options.HeaderName);
}
private bool TryDeserializeTokens(
HttpContext httpContext,
AntiforgeryTokenSet antiforgeryTokenSet,
out AntiforgeryToken cookieToken,
out AntiforgeryToken requestToken)
{
try
{
DeserializeTokens(httpContext, antiforgeryTokenSet, out cookieToken, out requestToken);
return true;
}
catch (AntiforgeryValidationException ex)
{
_logger.FailedToDeserialzeTokens(ex);
cookieToken = null;
requestToken = null;
return false;
}
}
private void DeserializeTokens(
HttpContext httpContext,
AntiforgeryTokenSet antiforgeryTokenSet,

View File

@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
}
// if we reached this point, something went wrong deserializing
throw new InvalidOperationException(Resources.AntiforgeryToken_DeserializationFailed, innerException);
throw new AntiforgeryValidationException(Resources.AntiforgeryToken_DeserializationFailed, innerException);
}
/* The serialized format of the anti-XSRF token is as follows:

View File

@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object, _pool);
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => testSerializer.Deserialize(serializedToken));
var ex = Assert.Throws<AntiforgeryValidationException>(() => testSerializer.Deserialize(serializedToken));
Assert.Equal(@"The antiforgery token could not be decrypted.", ex.Message);
}