Throwing custom AntiforgeryException for token validation failure scenarios

This commit is contained in:
Ajay Bhargav Baaskaran 2016-01-05 16:42:41 -08:00
parent a281b2e369
commit 80fa2908bd
6 changed files with 47 additions and 24 deletions

View File

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.Antiforgery
{
/// <summary>
/// The <see cref="Exception"/> that is thrown when the antiforgery token validation fails.
/// </summary>
public class AntiforgeryValidationException : Exception
{
/// <summary>
/// Creates a new instance of <see cref="AntiforgeryValidationException"/> with the specified
/// exception <paramref name="message"/>.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public AntiforgeryValidationException(string message)
: base(message)
{
}
}
}

View File

@ -119,13 +119,13 @@ namespace Microsoft.AspNet.Antiforgery
// Do the tokens have the correct format?
if (!cookieToken.IsCookieToken || requestToken.IsCookieToken)
{
throw new InvalidOperationException(Resources.AntiforgeryToken_TokensSwapped);
throw new AntiforgeryValidationException(Resources.AntiforgeryToken_TokensSwapped);
}
// Are the security tokens embedded in each incoming token identical?
if (!object.Equals(cookieToken.SecurityToken, requestToken.SecurityToken))
{
throw new InvalidOperationException(Resources.AntiforgeryToken_SecurityTokenMismatch);
throw new AntiforgeryValidationException(Resources.AntiforgeryToken_SecurityTokenMismatch);
}
// Is the incoming token meant for the current user?
@ -153,20 +153,20 @@ namespace Microsoft.AspNet.Antiforgery
if (!comparer.Equals(requestToken.Username, currentUsername))
{
throw new InvalidOperationException(
throw new AntiforgeryValidationException(
Resources.FormatAntiforgeryToken_UsernameMismatch(requestToken.Username, currentUsername));
}
if (!Equals(requestToken.ClaimUid, currentClaimUid))
if (!object.Equals(requestToken.ClaimUid, currentClaimUid))
{
throw new InvalidOperationException(Resources.AntiforgeryToken_ClaimUidMismatch);
throw new AntiforgeryValidationException(Resources.AntiforgeryToken_ClaimUidMismatch);
}
// Is the AdditionalData valid?
if (_additionalDataProvider != null &&
!_additionalDataProvider.ValidateAdditionalData(httpContext, requestToken.AdditionalData))
{
throw new InvalidOperationException(Resources.AntiforgeryToken_AdditionalDataCheckFailed);
throw new AntiforgeryValidationException(Resources.AntiforgeryToken_AdditionalDataCheckFailed);
}
}

View File

@ -68,7 +68,7 @@ namespace Microsoft.AspNet.Antiforgery
var requestCookie = httpContext.Request.Cookies[_options.CookieName];
if (string.IsNullOrEmpty(requestCookie))
{
throw new InvalidOperationException(
throw new AntiforgeryValidationException(
Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.CookieName));
}
@ -92,19 +92,19 @@ namespace Microsoft.AspNet.Antiforgery
if (_options.HeaderName == null)
{
var message = Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName);
throw new InvalidOperationException(message);
throw new AntiforgeryValidationException(message);
}
else if (!httpContext.Request.HasFormContentType)
{
var message = Resources.FormatAntiforgery_HeaderToken_MustBeProvided(_options.HeaderName);
throw new InvalidOperationException(message);
throw new AntiforgeryValidationException(message);
}
else
{
var message = Resources.FormatAntiforgery_RequestToken_MustBeProvided(
_options.FormFieldName,
_options.HeaderName);
throw new InvalidOperationException(message);
throw new AntiforgeryValidationException(message);
}
}

View File

@ -43,13 +43,13 @@ namespace Microsoft.AspNet.Antiforgery.FunctionalTests
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/items");
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(async () =>
{
var response = await Client.SendAsync(httpRequestMessage);
});
// Assert
Assert.Contains("required antiforgery cookie", exception.Message);
Assert.Contains("The required antiforgery cookie \"3Cs-jwHTMFk\" is not present.", exception.Message);
}
[Fact]

View File

@ -303,7 +303,7 @@ namespace Microsoft.AspNet.Antiforgery
// Act & assert
var ex1 =
Assert.Throws<InvalidOperationException>(
Assert.Throws<AntiforgeryValidationException>(
() => tokenProvider.ValidateTokens(httpContext, fieldtoken, fieldtoken));
Assert.Equal(
"Validation of the provided antiforgery token failed. " +
@ -311,7 +311,7 @@ namespace Microsoft.AspNet.Antiforgery
ex1.Message);
var ex2 =
Assert.Throws<InvalidOperationException>(
Assert.Throws<AntiforgeryValidationException>(
() => tokenProvider.ValidateTokens(httpContext, cookieToken, cookieToken));
Assert.Equal(
"Validation of the provided antiforgery token failed. " +
@ -334,7 +334,7 @@ namespace Microsoft.AspNet.Antiforgery
additionalDataProvider: null);
// Act & Assert
var exception = Assert.Throws<InvalidOperationException>(
var exception = Assert.Throws<AntiforgeryValidationException>(
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
Assert.Equal(
@"The antiforgery cookie token and request token do not match.",
@ -369,7 +369,7 @@ namespace Microsoft.AspNet.Antiforgery
additionalDataProvider: null);
// Act & Assert
var exception = Assert.Throws<InvalidOperationException>(
var exception = Assert.Throws<AntiforgeryValidationException>(
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
Assert.Equal(
@"The provided antiforgery token was meant for user """ + embeddedUsername +
@ -403,7 +403,7 @@ namespace Microsoft.AspNet.Antiforgery
additionalDataProvider: null);
// Act & assert
var exception = Assert.Throws<InvalidOperationException>(
var exception = Assert.Throws<AntiforgeryValidationException>(
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
Assert.Equal(
@"The provided antiforgery token was meant for a different claims-based user than the current user.",
@ -436,7 +436,7 @@ namespace Microsoft.AspNet.Antiforgery
additionalDataProvider: mockAdditionalDataProvider.Object);
// Act & assert
var exception = Assert.Throws<InvalidOperationException>(
var exception = Assert.Throws<AntiforgeryValidationException>(
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
Assert.Equal(@"The provided antiforgery token failed a custom data check.", exception.Message);
}

View File

@ -112,7 +112,7 @@ namespace Microsoft.AspNet.Antiforgery
// Arrange
var mockHttpContext = GetMockHttpContext(_cookieName, "invalid-value");
var expectedException = new InvalidOperationException("some exception");
var expectedException = new AntiforgeryValidationException("some exception");
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>();
mockSerializer
.Setup(o => o.Deserialize("invalid-value"))
@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Antiforgery
tokenSerializer: mockSerializer.Object);
// Act & assert
var ex = Assert.Throws<InvalidOperationException>(() => tokenStore.GetCookieToken(mockHttpContext));
var ex = Assert.Throws<AntiforgeryValidationException>(() => tokenStore.GetCookieToken(mockHttpContext));
Assert.Same(expectedException, ex);
}
@ -179,7 +179,7 @@ namespace Microsoft.AspNet.Antiforgery
tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
async () => await tokenStore.GetRequestTokensAsync(httpContext));
// Assert
@ -212,7 +212,7 @@ namespace Microsoft.AspNet.Antiforgery
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
async () => await tokenStore.GetRequestTokensAsync(httpContext));
// Assert
@ -315,7 +315,7 @@ namespace Microsoft.AspNet.Antiforgery
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
async () => await tokenStore.GetRequestTokensAsync(httpContext));
// Assert
@ -346,7 +346,7 @@ namespace Microsoft.AspNet.Antiforgery
tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
async () => await tokenStore.GetRequestTokensAsync(httpContext));
// Assert