Throwing custom AntiforgeryException for token validation failure scenarios
This commit is contained in:
parent
a281b2e369
commit
80fa2908bd
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -119,13 +119,13 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
// Do the tokens have the correct format?
|
// Do the tokens have the correct format?
|
||||||
if (!cookieToken.IsCookieToken || requestToken.IsCookieToken)
|
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?
|
// Are the security tokens embedded in each incoming token identical?
|
||||||
if (!object.Equals(cookieToken.SecurityToken, requestToken.SecurityToken))
|
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?
|
// Is the incoming token meant for the current user?
|
||||||
|
|
@ -153,20 +153,20 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
|
|
||||||
if (!comparer.Equals(requestToken.Username, currentUsername))
|
if (!comparer.Equals(requestToken.Username, currentUsername))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new AntiforgeryValidationException(
|
||||||
Resources.FormatAntiforgeryToken_UsernameMismatch(requestToken.Username, currentUsername));
|
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?
|
// Is the AdditionalData valid?
|
||||||
if (_additionalDataProvider != null &&
|
if (_additionalDataProvider != null &&
|
||||||
!_additionalDataProvider.ValidateAdditionalData(httpContext, requestToken.AdditionalData))
|
!_additionalDataProvider.ValidateAdditionalData(httpContext, requestToken.AdditionalData))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(Resources.AntiforgeryToken_AdditionalDataCheckFailed);
|
throw new AntiforgeryValidationException(Resources.AntiforgeryToken_AdditionalDataCheckFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var requestCookie = httpContext.Request.Cookies[_options.CookieName];
|
var requestCookie = httpContext.Request.Cookies[_options.CookieName];
|
||||||
if (string.IsNullOrEmpty(requestCookie))
|
if (string.IsNullOrEmpty(requestCookie))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new AntiforgeryValidationException(
|
||||||
Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.CookieName));
|
Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.CookieName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,19 +92,19 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
if (_options.HeaderName == null)
|
if (_options.HeaderName == null)
|
||||||
{
|
{
|
||||||
var message = Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName);
|
var message = Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName);
|
||||||
throw new InvalidOperationException(message);
|
throw new AntiforgeryValidationException(message);
|
||||||
}
|
}
|
||||||
else if (!httpContext.Request.HasFormContentType)
|
else if (!httpContext.Request.HasFormContentType)
|
||||||
{
|
{
|
||||||
var message = Resources.FormatAntiforgery_HeaderToken_MustBeProvided(_options.HeaderName);
|
var message = Resources.FormatAntiforgery_HeaderToken_MustBeProvided(_options.HeaderName);
|
||||||
throw new InvalidOperationException(message);
|
throw new AntiforgeryValidationException(message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var message = Resources.FormatAntiforgery_RequestToken_MustBeProvided(
|
var message = Resources.FormatAntiforgery_RequestToken_MustBeProvided(
|
||||||
_options.FormFieldName,
|
_options.FormFieldName,
|
||||||
_options.HeaderName);
|
_options.HeaderName);
|
||||||
throw new InvalidOperationException(message);
|
throw new AntiforgeryValidationException(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,13 +43,13 @@ namespace Microsoft.AspNet.Antiforgery.FunctionalTests
|
||||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/items");
|
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/items");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(async () =>
|
||||||
{
|
{
|
||||||
var response = await Client.SendAsync(httpRequestMessage);
|
var response = await Client.SendAsync(httpRequestMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Contains("required antiforgery cookie", exception.Message);
|
Assert.Contains("The required antiforgery cookie \"3Cs-jwHTMFk\" is not present.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
var ex1 =
|
var ex1 =
|
||||||
Assert.Throws<InvalidOperationException>(
|
Assert.Throws<AntiforgeryValidationException>(
|
||||||
() => tokenProvider.ValidateTokens(httpContext, fieldtoken, fieldtoken));
|
() => tokenProvider.ValidateTokens(httpContext, fieldtoken, fieldtoken));
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"Validation of the provided antiforgery token failed. " +
|
"Validation of the provided antiforgery token failed. " +
|
||||||
|
|
@ -311,7 +311,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
ex1.Message);
|
ex1.Message);
|
||||||
|
|
||||||
var ex2 =
|
var ex2 =
|
||||||
Assert.Throws<InvalidOperationException>(
|
Assert.Throws<AntiforgeryValidationException>(
|
||||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, cookieToken));
|
() => tokenProvider.ValidateTokens(httpContext, cookieToken, cookieToken));
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"Validation of the provided antiforgery token failed. " +
|
"Validation of the provided antiforgery token failed. " +
|
||||||
|
|
@ -334,7 +334,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var exception = Assert.Throws<InvalidOperationException>(
|
var exception = Assert.Throws<AntiforgeryValidationException>(
|
||||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
@"The antiforgery cookie token and request token do not match.",
|
@"The antiforgery cookie token and request token do not match.",
|
||||||
|
|
@ -369,7 +369,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var exception = Assert.Throws<InvalidOperationException>(
|
var exception = Assert.Throws<AntiforgeryValidationException>(
|
||||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
@"The provided antiforgery token was meant for user """ + embeddedUsername +
|
@"The provided antiforgery token was meant for user """ + embeddedUsername +
|
||||||
|
|
@ -403,7 +403,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
var exception = Assert.Throws<InvalidOperationException>(
|
var exception = Assert.Throws<AntiforgeryValidationException>(
|
||||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
@"The provided antiforgery token was meant for a different claims-based user than the current user.",
|
@"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);
|
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
var exception = Assert.Throws<InvalidOperationException>(
|
var exception = Assert.Throws<AntiforgeryValidationException>(
|
||||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||||
Assert.Equal(@"The provided antiforgery token failed a custom data check.", exception.Message);
|
Assert.Equal(@"The provided antiforgery token failed a custom data check.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
// Arrange
|
// Arrange
|
||||||
var mockHttpContext = GetMockHttpContext(_cookieName, "invalid-value");
|
var mockHttpContext = GetMockHttpContext(_cookieName, "invalid-value");
|
||||||
|
|
||||||
var expectedException = new InvalidOperationException("some exception");
|
var expectedException = new AntiforgeryValidationException("some exception");
|
||||||
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>();
|
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>();
|
||||||
mockSerializer
|
mockSerializer
|
||||||
.Setup(o => o.Deserialize("invalid-value"))
|
.Setup(o => o.Deserialize("invalid-value"))
|
||||||
|
|
@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
tokenSerializer: mockSerializer.Object);
|
tokenSerializer: mockSerializer.Object);
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => tokenStore.GetCookieToken(mockHttpContext));
|
var ex = Assert.Throws<AntiforgeryValidationException>(() => tokenStore.GetCookieToken(mockHttpContext));
|
||||||
Assert.Same(expectedException, ex);
|
Assert.Same(expectedException, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());
|
tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
|
||||||
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -212,7 +212,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
|
||||||
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -315,7 +315,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
|
||||||
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -346,7 +346,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());
|
tokenSerializer: Mock.Of<IAntiforgeryTokenSerializer>());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await Assert.ThrowsAsync<AntiforgeryValidationException>(
|
||||||
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue