Fix #5 - better error message for missing tokens
This fix changes the model for error messaging in antiforgery. Now only the token store will report a detailed error message including the names of form field and cookie. Other components will give more generic errors and assume that this was handled by the token store. This way you still see an error if the user creates a token store that doesn't throw, but it's a generic error that doesn't give incorrect information.
This commit is contained in:
parent
fbe9dc58e8
commit
9bcecf3994
|
|
@ -76,12 +76,8 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
{
|
{
|
||||||
CheckSSLConfig(context);
|
CheckSSLConfig(context);
|
||||||
|
|
||||||
// Extract cookie & form tokens
|
var tokens = await _tokenStore.GetRequestTokensAsync(context);
|
||||||
var cookieToken = _tokenStore.GetCookieToken(context);
|
ValidateTokens(context, tokens);
|
||||||
var formToken = await _tokenStore.GetFormTokenAsync(context);
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
_tokenGenerator.ValidateTokens(context, cookieToken, formToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -89,9 +85,23 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
{
|
{
|
||||||
CheckSSLConfig(context);
|
CheckSSLConfig(context);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.Antiforgery_CookieToken_MustBeProvided_Generic,
|
||||||
|
nameof(antiforgeryTokenSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(antiforgeryTokenSet.FormToken))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.Antiforgery_FormToken_MustBeProvided_Generic,
|
||||||
|
nameof(antiforgeryTokenSet));
|
||||||
|
}
|
||||||
|
|
||||||
// Extract cookie & form tokens
|
// Extract cookie & form tokens
|
||||||
var deserializedCookieToken = DeserializeToken(antiforgeryTokenSet.CookieToken);
|
var deserializedCookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken);
|
||||||
var deserializedFormToken = DeserializeToken(antiforgeryTokenSet.FormToken);
|
var deserializedFormToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.FormToken);
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
_tokenGenerator.ValidateTokens(
|
_tokenGenerator.ValidateTokens(
|
||||||
|
|
@ -154,26 +164,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AntiforgeryToken DeserializeToken(string serializedToken)
|
|
||||||
{
|
|
||||||
return (!string.IsNullOrEmpty(serializedToken))
|
|
||||||
? _tokenSerializer.Deserialize(serializedToken)
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AntiforgeryToken DeserializeTokenDoesNotThrow(string serializedToken)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return DeserializeToken(serializedToken);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore failures since we'll just generate a new token
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private AntiforgeryToken GetCookieTokenDoesNotThrow(HttpContext context)
|
private AntiforgeryToken GetCookieTokenDoesNotThrow(HttpContext context)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,18 @@ using System.Diagnostics;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.Framework.OptionsModel;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Antiforgery
|
namespace Microsoft.AspNet.Antiforgery
|
||||||
{
|
{
|
||||||
public class DefaultAntiforgeryTokenGenerator : IAntiforgeryTokenGenerator
|
public class DefaultAntiforgeryTokenGenerator : IAntiforgeryTokenGenerator
|
||||||
{
|
{
|
||||||
private readonly IClaimUidExtractor _claimUidExtractor;
|
private readonly IClaimUidExtractor _claimUidExtractor;
|
||||||
private readonly AntiforgeryOptions _options;
|
|
||||||
private readonly IAntiforgeryAdditionalDataProvider _additionalDataProvider;
|
private readonly IAntiforgeryAdditionalDataProvider _additionalDataProvider;
|
||||||
|
|
||||||
public DefaultAntiforgeryTokenGenerator(
|
public DefaultAntiforgeryTokenGenerator(
|
||||||
IOptions<AntiforgeryOptions> optionsAccessor,
|
|
||||||
IClaimUidExtractor claimUidExtractor,
|
IClaimUidExtractor claimUidExtractor,
|
||||||
IAntiforgeryAdditionalDataProvider additionalDataProvider)
|
IAntiforgeryAdditionalDataProvider additionalDataProvider)
|
||||||
{
|
{
|
||||||
_options = optionsAccessor.Options;
|
|
||||||
_claimUidExtractor = claimUidExtractor;
|
_claimUidExtractor = claimUidExtractor;
|
||||||
_additionalDataProvider = additionalDataProvider;
|
_additionalDataProvider = additionalDataProvider;
|
||||||
}
|
}
|
||||||
|
|
@ -96,23 +92,24 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
AntiforgeryToken sessionToken,
|
AntiforgeryToken sessionToken,
|
||||||
AntiforgeryToken fieldToken)
|
AntiforgeryToken fieldToken)
|
||||||
{
|
{
|
||||||
// Were the tokens even present at all?
|
|
||||||
if (sessionToken == null)
|
if (sessionToken == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new ArgumentNullException(
|
||||||
Resources.FormatAntiforgeryToken_CookieMissing(_options.CookieName));
|
nameof(sessionToken),
|
||||||
|
Resources.Antiforgery_CookieToken_MustBeProvided_Generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldToken == null)
|
if (fieldToken == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new ArgumentNullException(
|
||||||
Resources.FormatAntiforgeryToken_FormFieldMissing(_options.FormFieldName));
|
nameof(fieldToken),
|
||||||
|
Resources.Antiforgery_FormToken_MustBeProvided_Generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the tokens have the correct format?
|
// Do the tokens have the correct format?
|
||||||
if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken)
|
if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(Resources.AntiforgeryToken_TokensSwapped);
|
||||||
Resources.FormatAntiforgeryToken_TokensSwapped(_options.CookieName, _options.FormFieldName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are the security tokens embedded in each incoming token identical?
|
// Are the security tokens embedded in each incoming token identical?
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
|
@ -43,17 +44,24 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
return _tokenSerializer.Deserialize(requestCookie);
|
return _tokenSerializer.Deserialize(requestCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AntiforgeryToken> GetFormTokenAsync(HttpContext httpContext)
|
public async Task<AntiforgeryTokenSet> GetRequestTokensAsync([NotNull] HttpContext httpContext)
|
||||||
{
|
{
|
||||||
var form = await httpContext.Request.ReadFormAsync();
|
var requestCookie = httpContext.Request.Cookies[_options.CookieName];
|
||||||
var value = form[_options.FormFieldName];
|
if (string.IsNullOrEmpty(requestCookie))
|
||||||
if (string.IsNullOrEmpty(value))
|
|
||||||
{
|
{
|
||||||
// did not exist
|
throw new InvalidOperationException(
|
||||||
return null;
|
Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.CookieName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _tokenSerializer.Deserialize(value);
|
var form = await httpContext.Request.ReadFormAsync();
|
||||||
|
var formField = form[_options.FormFieldName];
|
||||||
|
if (string.IsNullOrEmpty(formField))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AntiforgeryTokenSet(formField, requestCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token)
|
public void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Antiforgery
|
namespace Microsoft.AspNet.Antiforgery
|
||||||
{
|
{
|
||||||
|
|
@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
// Given a cookie token, generates a corresponding form token.
|
// Given a cookie token, generates a corresponding form token.
|
||||||
// The incoming cookie token must be valid.
|
// The incoming cookie token must be valid.
|
||||||
AntiforgeryToken GenerateFormToken(
|
AntiforgeryToken GenerateFormToken(
|
||||||
HttpContext httpContext,
|
[NotNull] HttpContext httpContext,
|
||||||
AntiforgeryToken cookieToken);
|
AntiforgeryToken cookieToken);
|
||||||
|
|
||||||
// Determines whether an existing cookie token is valid (well-formed).
|
// Determines whether an existing cookie token is valid (well-formed).
|
||||||
|
|
@ -26,8 +26,8 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
|
|
||||||
// Validates a (cookie, form) token pair.
|
// Validates a (cookie, form) token pair.
|
||||||
void ValidateTokens(
|
void ValidateTokens(
|
||||||
HttpContext httpContext,
|
[NotNull] HttpContext httpContext,
|
||||||
AntiforgeryToken cookieToken,
|
[NotNull] AntiforgeryToken cookieToken,
|
||||||
AntiforgeryToken formToken);
|
[NotNull] AntiforgeryToken formToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,14 +3,23 @@
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Antiforgery
|
namespace Microsoft.AspNet.Antiforgery
|
||||||
{
|
{
|
||||||
// Provides an abstraction around how tokens are persisted and retrieved for a request
|
// Provides an abstraction around how tokens are persisted and retrieved for a request
|
||||||
public interface IAntiforgeryTokenStore
|
public interface IAntiforgeryTokenStore
|
||||||
{
|
{
|
||||||
AntiforgeryToken GetCookieToken(HttpContext httpContext);
|
AntiforgeryToken GetCookieToken([NotNull] HttpContext httpContext);
|
||||||
Task<AntiforgeryToken> GetFormTokenAsync(HttpContext httpContext);
|
|
||||||
void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token);
|
/// <summary>
|
||||||
|
/// Gets the cookie and form tokens from the request. Will throw an exception if either token is
|
||||||
|
/// not present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpContext">The <see cref="HttpContext"/> for the current request.</param>
|
||||||
|
/// <returns>The <see cref="AntiforgeryTokenSet"/>.</returns>
|
||||||
|
Task<AntiforgeryTokenSet> GetRequestTokensAsync([NotNull] HttpContext httpContext);
|
||||||
|
|
||||||
|
void SaveCookieToken([NotNull] HttpContext httpContext, [NotNull] AntiforgeryToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,22 +58,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
return GetString("AntiforgeryToken_ClaimUidMismatch");
|
return GetString("AntiforgeryToken_ClaimUidMismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The required antiforgery cookie "{0}" is not present.
|
|
||||||
/// </summary>
|
|
||||||
internal static string AntiforgeryToken_CookieMissing
|
|
||||||
{
|
|
||||||
get { return GetString("AntiforgeryToken_CookieMissing"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The required antiforgery cookie "{0}" is not present.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatAntiforgeryToken_CookieMissing(object p0)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("AntiforgeryToken_CookieMissing"), p0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The antiforgery token could not be decrypted.
|
/// The antiforgery token could not be decrypted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -90,22 +74,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
return GetString("AntiforgeryToken_DeserializationFailed");
|
return GetString("AntiforgeryToken_DeserializationFailed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The required antiforgery form field "{0}" is not present.
|
|
||||||
/// </summary>
|
|
||||||
internal static string AntiforgeryToken_FormFieldMissing
|
|
||||||
{
|
|
||||||
get { return GetString("AntiforgeryToken_FormFieldMissing"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The required antiforgery form field "{0}" is not present.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatAntiforgeryToken_FormFieldMissing(object p0)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("AntiforgeryToken_FormFieldMissing"), p0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The antiforgery cookie token and form field token do not match.
|
/// The antiforgery cookie token and form field token do not match.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -123,7 +91,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validation of the provided antiforgery token failed. The cookie "{0}" and the form field "{1}" were swapped.
|
/// Validation of the provided antiforgery token failed. The cookie token and the form token were swapped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string AntiforgeryToken_TokensSwapped
|
internal static string AntiforgeryToken_TokensSwapped
|
||||||
{
|
{
|
||||||
|
|
@ -131,11 +99,11 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validation of the provided antiforgery token failed. The cookie "{0}" and the form field "{1}" were swapped.
|
/// Validation of the provided antiforgery token failed. The cookie token and the form token were swapped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string FormatAntiforgeryToken_TokensSwapped(object p0, object p1)
|
internal static string FormatAntiforgeryToken_TokensSwapped()
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("AntiforgeryToken_TokensSwapped"), p0, p1);
|
return GetString("AntiforgeryToken_TokensSwapped");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -170,6 +138,70 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("AntiforgeryWorker_RequireSSL"), p0, p1, p2);
|
return string.Format(CultureInfo.CurrentCulture, GetString("AntiforgeryWorker_RequireSSL"), p0, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The required antiforgery cookie "{0}" is not present.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Antiforgery_CookieToken_MustBeProvided
|
||||||
|
{
|
||||||
|
get { return GetString("Antiforgery_CookieToken_MustBeProvided"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The required antiforgery cookie "{0}" is not present.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatAntiforgery_CookieToken_MustBeProvided(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("Antiforgery_CookieToken_MustBeProvided"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The cookie token must be provided.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Antiforgery_CookieToken_MustBeProvided_Generic
|
||||||
|
{
|
||||||
|
get { return GetString("Antiforgery_CookieToken_MustBeProvided_Generic"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The cookie token must be provided.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatAntiforgery_CookieToken_MustBeProvided_Generic()
|
||||||
|
{
|
||||||
|
return GetString("Antiforgery_CookieToken_MustBeProvided_Generic");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The required antiforgery form field "{0}" is not present.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Antiforgery_FormToken_MustBeProvided
|
||||||
|
{
|
||||||
|
get { return GetString("Antiforgery_FormToken_MustBeProvided"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The required antiforgery form field "{0}" is not present.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatAntiforgery_FormToken_MustBeProvided(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("Antiforgery_FormToken_MustBeProvided"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The form token must be provided.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Antiforgery_FormToken_MustBeProvided_Generic
|
||||||
|
{
|
||||||
|
get { return GetString("Antiforgery_FormToken_MustBeProvided_Generic"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The form token must be provided.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatAntiforgery_FormToken_MustBeProvided_Generic()
|
||||||
|
{
|
||||||
|
return GetString("Antiforgery_FormToken_MustBeProvided_Generic");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Value cannot be null or empty.
|
/// Value cannot be null or empty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -127,20 +127,14 @@
|
||||||
<data name="AntiforgeryToken_ClaimUidMismatch" xml:space="preserve">
|
<data name="AntiforgeryToken_ClaimUidMismatch" xml:space="preserve">
|
||||||
<value>The provided antiforgery token was meant for a different claims-based user than the current user.</value>
|
<value>The provided antiforgery token was meant for a different claims-based user than the current user.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AntiforgeryToken_CookieMissing" xml:space="preserve">
|
|
||||||
<value>The required antiforgery cookie "{0}" is not present.</value>
|
|
||||||
</data>
|
|
||||||
<data name="AntiforgeryToken_DeserializationFailed" xml:space="preserve">
|
<data name="AntiforgeryToken_DeserializationFailed" xml:space="preserve">
|
||||||
<value>The antiforgery token could not be decrypted.</value>
|
<value>The antiforgery token could not be decrypted.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AntiforgeryToken_FormFieldMissing" xml:space="preserve">
|
|
||||||
<value>The required antiforgery form field "{0}" is not present.</value>
|
|
||||||
</data>
|
|
||||||
<data name="AntiforgeryToken_SecurityTokenMismatch" xml:space="preserve">
|
<data name="AntiforgeryToken_SecurityTokenMismatch" xml:space="preserve">
|
||||||
<value>The antiforgery cookie token and form field token do not match.</value>
|
<value>The antiforgery cookie token and form field token do not match.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AntiforgeryToken_TokensSwapped" xml:space="preserve">
|
<data name="AntiforgeryToken_TokensSwapped" xml:space="preserve">
|
||||||
<value>Validation of the provided antiforgery token failed. The cookie "{0}" and the form field "{1}" were swapped.</value>
|
<value>Validation of the provided antiforgery token failed. The cookie token and the form token were swapped.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AntiforgeryToken_UsernameMismatch" xml:space="preserve">
|
<data name="AntiforgeryToken_UsernameMismatch" xml:space="preserve">
|
||||||
<value>The provided antiforgery token was meant for user "{0}", but the current user is "{1}".</value>
|
<value>The provided antiforgery token was meant for user "{0}", but the current user is "{1}".</value>
|
||||||
|
|
@ -149,6 +143,18 @@
|
||||||
<value>The antiforgery system has the configuration value {0}.{1} = {2}, but the current request is not an SSL request.</value>
|
<value>The antiforgery system has the configuration value {0}.{1} = {2}, but the current request is not an SSL request.</value>
|
||||||
<comment>0 = nameof(AntiforgeryOptions), 1 = nameof(RequireSsl), 2 = bool.TrueString</comment>
|
<comment>0 = nameof(AntiforgeryOptions), 1 = nameof(RequireSsl), 2 = bool.TrueString</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Antiforgery_CookieToken_MustBeProvided" xml:space="preserve">
|
||||||
|
<value>The required antiforgery cookie "{0}" is not present.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Antiforgery_CookieToken_MustBeProvided_Generic" xml:space="preserve">
|
||||||
|
<value>The cookie token must be provided.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Antiforgery_FormToken_MustBeProvided" xml:space="preserve">
|
||||||
|
<value>The required antiforgery form field "{0}" is not present.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Antiforgery_FormToken_MustBeProvided_Generic" xml:space="preserve">
|
||||||
|
<value>The form token must be provided.</value>
|
||||||
|
</data>
|
||||||
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
||||||
<value>Value cannot be null or empty.</value>
|
<value>Value cannot be null or empty.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Validate_FromInvalidStrings_Throws()
|
public void ValidateTokens_FromInvalidStrings_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = CreateMockContext(new AntiforgeryOptions());
|
var context = CreateMockContext(new AntiforgeryOptions());
|
||||||
|
|
@ -344,7 +344,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Validate_FromValidStrings_TokensValidatedSuccessfully()
|
public void ValidateTokens_FromValidStrings_TokensValidatedSuccessfully()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = CreateMockContext(new AntiforgeryOptions());
|
var context = CreateMockContext(new AntiforgeryOptions());
|
||||||
|
|
@ -369,16 +369,37 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Validate_FromStore_Failure()
|
public void ValidateTokens_MissingCookieInTokenSet_Throws()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var context = CreateMockContext(new AntiforgeryOptions());
|
||||||
|
var antiforgery = GetAntiforgery(context);
|
||||||
|
|
||||||
|
var tokenSet = new AntiforgeryTokenSet("hi", cookieToken: null);
|
||||||
|
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var exception = Assert.Throws<ArgumentException>(
|
||||||
|
() => antiforgery.ValidateTokens(context.HttpContext, tokenSet));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var trimmed = exception.Message.Substring(0, exception.Message.IndexOf(Environment.NewLine));
|
||||||
|
Assert.Equal("The cookie token must be provided.", trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ValidateRequestAsync_FromStore_Failure()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = CreateMockContext(new AntiforgeryOptions());
|
var context = CreateMockContext(new AntiforgeryOptions());
|
||||||
|
|
||||||
context.TokenGenerator.Setup(o => o.ValidateTokens(
|
context.TokenGenerator
|
||||||
context.HttpContext,
|
.Setup(o => o.ValidateTokens(
|
||||||
context.TestTokenSet.OldCookieToken, context.TestTokenSet.FormToken))
|
context.HttpContext,
|
||||||
.Throws(new InvalidOperationException("my-message"));
|
context.TestTokenSet.OldCookieToken,
|
||||||
context.TokenSerializer = null;
|
context.TestTokenSet.FormToken))
|
||||||
|
.Throws(new InvalidOperationException("my-message"));
|
||||||
|
|
||||||
var antiforgery = GetAntiforgery(context);
|
var antiforgery = GetAntiforgery(context);
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
|
|
@ -388,16 +409,18 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Validate_FromStore_Success()
|
public async Task ValidateRequestAsync_FromStore_Success()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = CreateMockContext(new AntiforgeryOptions());
|
var context = CreateMockContext(new AntiforgeryOptions());
|
||||||
|
|
||||||
context.TokenGenerator.Setup(o => o.ValidateTokens(
|
context.TokenGenerator
|
||||||
context.HttpContext,
|
.Setup(o => o.ValidateTokens(
|
||||||
context.TestTokenSet.OldCookieToken, context.TestTokenSet.FormToken))
|
context.HttpContext,
|
||||||
.Verifiable();
|
context.TestTokenSet.OldCookieToken,
|
||||||
context.TokenSerializer = null;
|
context.TestTokenSet.FormToken))
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
var antiforgery = GetAntiforgery(context);
|
var antiforgery = GetAntiforgery(context);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -482,8 +505,11 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var mockTokenStore = new Mock<IAntiforgeryTokenStore>(MockBehavior.Strict);
|
var mockTokenStore = new Mock<IAntiforgeryTokenStore>(MockBehavior.Strict);
|
||||||
mockTokenStore.Setup(o => o.GetCookieToken(context))
|
mockTokenStore.Setup(o => o.GetCookieToken(context))
|
||||||
.Returns(oldCookieToken);
|
.Returns(oldCookieToken);
|
||||||
mockTokenStore.Setup(o => o.GetFormTokenAsync(context))
|
|
||||||
.Returns(Task.FromResult(formToken));
|
mockTokenStore.Setup(o => o.GetRequestTokensAsync(context))
|
||||||
|
.Returns(() => Task.FromResult(new AntiforgeryTokenSet(
|
||||||
|
testTokenSet.FormTokenString,
|
||||||
|
testTokenSet.OldCookieTokenString)));
|
||||||
|
|
||||||
if (saveNewCookie)
|
if (saveNewCookie)
|
||||||
{
|
{
|
||||||
|
|
@ -502,11 +528,13 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var formToken = testTokenSet.FormToken;
|
var formToken = testTokenSet.FormToken;
|
||||||
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>(MockBehavior.Strict);
|
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>(MockBehavior.Strict);
|
||||||
mockSerializer.Setup(o => o.Serialize(formToken))
|
mockSerializer.Setup(o => o.Serialize(formToken))
|
||||||
.Returns("serialized-form-token");
|
.Returns(testTokenSet.FormTokenString);
|
||||||
mockSerializer.Setup(o => o.Deserialize("serialized-old-cookie-token"))
|
mockSerializer.Setup(o => o.Deserialize(testTokenSet.FormTokenString))
|
||||||
|
.Returns(formToken);
|
||||||
|
mockSerializer.Setup(o => o.Deserialize(testTokenSet.OldCookieTokenString))
|
||||||
.Returns(oldCookieToken);
|
.Returns(oldCookieToken);
|
||||||
mockSerializer.Setup(o => o.Serialize(newCookieToken))
|
mockSerializer.Setup(o => o.Serialize(newCookieToken))
|
||||||
.Returns("serialized-new-cookie-token");
|
.Returns(testTokenSet.NewCookieTokenString);
|
||||||
return mockSerializer;
|
return mockSerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,8 +586,11 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
return new TestTokenSet()
|
return new TestTokenSet()
|
||||||
{
|
{
|
||||||
FormToken = new AntiforgeryToken() { IsSessionToken = false },
|
FormToken = new AntiforgeryToken() { IsSessionToken = false },
|
||||||
|
FormTokenString = "serialized-form-token",
|
||||||
OldCookieToken = new AntiforgeryToken() { IsSessionToken = isOldCookieTokenSessionToken },
|
OldCookieToken = new AntiforgeryToken() { IsSessionToken = isOldCookieTokenSessionToken },
|
||||||
|
OldCookieTokenString = "serialized-old-cookie-token",
|
||||||
NewCookieToken = new AntiforgeryToken() { IsSessionToken = isNewCookieSessionToken },
|
NewCookieToken = new AntiforgeryToken() { IsSessionToken = isNewCookieSessionToken },
|
||||||
|
NewCookieTokenString = "serialized-new-cookie-token",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -40,7 +39,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
Assert.False(httpContext.User.Identity.IsAuthenticated);
|
Assert.False(httpContext.User.Identity.IsAuthenticated);
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -74,7 +72,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;
|
var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: claimUidExtractor,
|
claimUidExtractor: claimUidExtractor,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -109,7 +106,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;
|
var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: claimUidExtractor,
|
claimUidExtractor: claimUidExtractor,
|
||||||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||||
|
|
||||||
|
|
@ -148,7 +144,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns(base64ClaimUId);
|
.Returns(base64ClaimUId);
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: mockClaimUidExtractor.Object,
|
claimUidExtractor: mockClaimUidExtractor.Object,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -182,7 +177,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;
|
var claimUidExtractor = new Mock<IClaimUidExtractor>().Object;
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: claimUidExtractor,
|
claimUidExtractor: claimUidExtractor,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -209,7 +203,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
};
|
};
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -226,7 +219,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
// Arrange
|
// Arrange
|
||||||
AntiforgeryToken cookieToken = null;
|
AntiforgeryToken cookieToken = null;
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -247,7 +239,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
};
|
};
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -268,21 +259,16 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
|
|
||||||
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
||||||
|
|
||||||
var options = new AntiforgeryOptions()
|
|
||||||
{
|
|
||||||
CookieName = "my-cookie-name"
|
|
||||||
};
|
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(options),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
var ex =
|
var ex = Assert.Throws<ArgumentNullException>(
|
||||||
Assert.Throws<InvalidOperationException>(
|
() => tokenProvider.ValidateTokens(httpContext, null, fieldtoken));
|
||||||
() => tokenProvider.ValidateTokens(httpContext, null, fieldtoken));
|
|
||||||
Assert.Equal(@"The required antiforgery cookie ""my-cookie-name"" is not present.", ex.Message);
|
var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine));
|
||||||
|
Assert.Equal(@"The cookie token must be provided.", trimmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -294,21 +280,16 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
|
|
||||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||||
|
|
||||||
var options = new AntiforgeryOptions()
|
|
||||||
{
|
|
||||||
FormFieldName = "my-form-field-name"
|
|
||||||
};
|
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(options),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
// Act & assert
|
// Act & assert
|
||||||
var ex =
|
var ex = Assert.Throws<ArgumentNullException>(
|
||||||
Assert.Throws<InvalidOperationException>(
|
() => tokenProvider.ValidateTokens(httpContext, sessionToken, null));
|
||||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, null));
|
|
||||||
Assert.Equal(@"The required antiforgery form field ""my-form-field-name"" is not present.", ex.Message);
|
var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine));
|
||||||
|
Assert.Equal("The form token must be provided.", trimmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -321,14 +302,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||||
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
||||||
|
|
||||||
var options = new AntiforgeryOptions()
|
|
||||||
{
|
|
||||||
CookieName = "my-cookie-name",
|
|
||||||
FormFieldName = "my-form-field-name"
|
|
||||||
};
|
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(options),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -338,7 +312,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
() => 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. " +
|
||||||
@"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
|
@"The cookie token and the form token were swapped.",
|
||||||
ex1.Message);
|
ex1.Message);
|
||||||
|
|
||||||
var ex2 =
|
var ex2 =
|
||||||
|
|
@ -346,7 +320,7 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, sessionToken));
|
() => tokenProvider.ValidateTokens(httpContext, sessionToken, sessionToken));
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"Validation of the provided antiforgery token failed. " +
|
"Validation of the provided antiforgery token failed. " +
|
||||||
@"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.",
|
@"The cookie token and the form token were swapped.",
|
||||||
ex2.Message);
|
ex2.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +335,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -399,7 +372,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns((string)null);
|
.Returns((string)null);
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: mockClaimUidExtractor.Object,
|
claimUidExtractor: mockClaimUidExtractor.Object,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -434,7 +406,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns(Convert.ToBase64String(differentToken.GetData()));
|
.Returns(Convert.ToBase64String(differentToken.GetData()));
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: mockClaimUidExtractor.Object,
|
claimUidExtractor: mockClaimUidExtractor.Object,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
@ -468,7 +439,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns(false);
|
.Returns(false);
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||||
|
|
||||||
|
|
@ -500,7 +470,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: null,
|
claimUidExtractor: null,
|
||||||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||||
|
|
||||||
|
|
@ -533,7 +502,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: new Mock<IClaimUidExtractor>().Object,
|
claimUidExtractor: new Mock<IClaimUidExtractor>().Object,
|
||||||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||||
|
|
||||||
|
|
@ -565,7 +533,6 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
.Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData()));
|
.Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData()));
|
||||||
|
|
||||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||||
optionsAccessor: new TestOptionsManager(),
|
|
||||||
claimUidExtractor: mockClaimUidExtractor.Object,
|
claimUidExtractor: mockClaimUidExtractor.Object,
|
||||||
additionalDataProvider: null);
|
additionalDataProvider: null);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Http.Internal;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -160,20 +161,16 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetFormToken_FormFieldIsEmpty_ReturnsNull()
|
public async Task GetRequestTokens_CookieIsEmpty_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var mockHttpContext = new Mock<HttpContext>();
|
var httpContext = new DefaultHttpContext();
|
||||||
var requestContext = new Mock<HttpRequest>();
|
httpContext.Request.Form = new FormCollection(new Dictionary<string, string[]>());
|
||||||
var formCollection = new Mock<IFormCollection>();
|
httpContext.Request.Cookies = new ReadableStringCollection(new Dictionary<string, string[]>());
|
||||||
formCollection.Setup(f => f["form-field-name"]).Returns(string.Empty);
|
|
||||||
requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None))
|
|
||||||
.Returns(Task.FromResult(formCollection.Object));
|
|
||||||
mockHttpContext.Setup(o => o.Request)
|
|
||||||
.Returns(requestContext.Object);
|
|
||||||
|
|
||||||
var options = new AntiforgeryOptions()
|
var options = new AntiforgeryOptions()
|
||||||
{
|
{
|
||||||
|
CookieName = "cookie-name",
|
||||||
FormFieldName = "form-field-name",
|
FormFieldName = "form-field-name",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -182,81 +179,72 @@ namespace Microsoft.AspNet.Antiforgery
|
||||||
tokenSerializer: null);
|
tokenSerializer: null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var token = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);
|
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||||
|
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(token);
|
Assert.Equal("The required antiforgery cookie \"cookie-name\" is not present.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetFormToken_FormFieldIsInvalid_PropagatesException()
|
public async Task GetRequestTokens_FormFieldIsEmpty_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var formCollection = new Mock<IFormCollection>();
|
var httpContext = new DefaultHttpContext();
|
||||||
formCollection.Setup(f => f["form-field-name"]).Returns("invalid-value");
|
httpContext.Request.Form = new FormCollection(new Dictionary<string, string[]>());
|
||||||
|
httpContext.Request.Cookies = new ReadableStringCollection(new Dictionary<string, string[]>()
|
||||||
var requestContext = new Mock<HttpRequest>();
|
{
|
||||||
requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None))
|
{ "cookie-name", new string[] { "cookie-value" } },
|
||||||
.Returns(Task.FromResult(formCollection.Object));
|
});
|
||||||
|
|
||||||
var mockHttpContext = new Mock<HttpContext>();
|
|
||||||
mockHttpContext.Setup(o => o.Request)
|
|
||||||
.Returns(requestContext.Object);
|
|
||||||
|
|
||||||
var expectedException = new InvalidOperationException("some exception");
|
|
||||||
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>();
|
|
||||||
mockSerializer.Setup(o => o.Deserialize("invalid-value"))
|
|
||||||
.Throws(expectedException);
|
|
||||||
|
|
||||||
var options = new AntiforgeryOptions()
|
var options = new AntiforgeryOptions()
|
||||||
{
|
{
|
||||||
|
CookieName = "cookie-name",
|
||||||
FormFieldName = "form-field-name",
|
FormFieldName = "form-field-name",
|
||||||
};
|
};
|
||||||
|
|
||||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||||
optionsAccessor: new TestOptionsManager(options),
|
optionsAccessor: new TestOptionsManager(options),
|
||||||
tokenSerializer: mockSerializer.Object);
|
tokenSerializer: null);
|
||||||
|
|
||||||
// Act & assert
|
// Act
|
||||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await tokenStore.GetFormTokenAsync(mockHttpContext.Object));
|
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||||
Assert.Same(expectedException, exception);
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("The required antiforgery form field \"form-field-name\" is not present.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetFormToken_FormFieldIsValid_ReturnsToken()
|
public async Task GetFormToken_FormFieldIsValid_ReturnsToken()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expectedToken = new AntiforgeryToken();
|
var httpContext = new DefaultHttpContext();
|
||||||
|
httpContext.Request.Form = new FormCollection(new Dictionary<string, string[]>()
|
||||||
// Arrange
|
{
|
||||||
var mockHttpContext = new Mock<HttpContext>();
|
{ "form-field-name", new string[] { "form-value" } },
|
||||||
var requestContext = new Mock<HttpRequest>();
|
});
|
||||||
var formCollection = new Mock<IFormCollection>();
|
httpContext.Request.Cookies = new ReadableStringCollection(new Dictionary<string, string[]>()
|
||||||
formCollection.Setup(f => f["form-field-name"]).Returns("valid-value");
|
{
|
||||||
requestContext.Setup(o => o.ReadFormAsync(CancellationToken.None))
|
{ "cookie-name", new string[] { "cookie-value" } },
|
||||||
.Returns(Task.FromResult(formCollection.Object));
|
});
|
||||||
mockHttpContext.Setup(o => o.Request)
|
|
||||||
.Returns(requestContext.Object);
|
|
||||||
|
|
||||||
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>();
|
|
||||||
mockSerializer.Setup(o => o.Deserialize("valid-value"))
|
|
||||||
.Returns(expectedToken);
|
|
||||||
|
|
||||||
var options = new AntiforgeryOptions()
|
var options = new AntiforgeryOptions()
|
||||||
{
|
{
|
||||||
|
CookieName = "cookie-name",
|
||||||
FormFieldName = "form-field-name",
|
FormFieldName = "form-field-name",
|
||||||
};
|
};
|
||||||
|
|
||||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||||
optionsAccessor: new TestOptionsManager(options),
|
optionsAccessor: new TestOptionsManager(options),
|
||||||
tokenSerializer: mockSerializer.Object);
|
tokenSerializer: null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var retVal = await tokenStore.GetFormTokenAsync(mockHttpContext.Object);
|
var tokens = await tokenStore.GetRequestTokensAsync(httpContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Same(expectedToken, retVal);
|
Assert.Equal("cookie-value", tokens.CookieToken);
|
||||||
|
Assert.Equal("form-value", tokens.FormToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue