Add Header support
This change adds support for retrieving an antiforgery CSRF token via a configurable header in addition to the form field. This helps with doing ajax requests in a 1st-party SPA when using cookie auth, and is similar to functionality provided by a bunch of different frameworks. In this change there's also a bunch of churn due to avoiding the term 'form' in favor of 'request' and 'session' in favor of 'cookie'. Where code and error message now mention 'form' they specifically mean form-encoded content.
This commit is contained in:
Родитель
b69aef3c51
Коммит
3280ff6ac5
|
@ -40,7 +40,7 @@ namespace AntiforgerySample
|
|||
</html>";
|
||||
|
||||
var tokenSet = _antiforgery.GetAndStoreTokens(context);
|
||||
await context.Response.WriteAsync(string.Format(page, _options.FormFieldName, tokenSet.FormToken));
|
||||
await context.Response.WriteAsync(string.Format(page, _options.FormFieldName, tokenSet.RequestToken));
|
||||
}
|
||||
else if (context.Request.Method == "POST")
|
||||
{
|
||||
|
|
|
@ -11,16 +11,17 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
public class AntiforgeryOptions
|
||||
{
|
||||
private const string AntiforgeryTokenFieldName = "__RequestVerificationToken";
|
||||
private const string AntiforgertyTokenHeaderName = "RequestVerificationToken";
|
||||
|
||||
private string _cookieName;
|
||||
private string _headerName = AntiforgertyTokenHeaderName;
|
||||
private string _formFieldName = AntiforgeryTokenFieldName;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the name of the cookie that is used by the antiforgery
|
||||
/// system.
|
||||
/// Specifies the name of the cookie that is used by the antiforgery system.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If an explicit name is not provided, the system will automatically
|
||||
/// generate a name.
|
||||
/// If an explicit name is not provided, the system will automatically generate a name.
|
||||
/// </remarks>
|
||||
public string CookieName
|
||||
{
|
||||
|
@ -59,6 +60,16 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the name of the header value that is used by the antiforgery system. If <c>null</c> then
|
||||
/// antiforgery validation will only consider form data.
|
||||
/// </summary>
|
||||
public string HeaderName
|
||||
{
|
||||
get { return _headerName; }
|
||||
set { _headerName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether SSL is required for the antiforgery system
|
||||
/// to operate. If this setting is 'true' and a non-SSL request
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
public BinaryBlob ClaimUid { get; set; }
|
||||
|
||||
public bool IsSessionToken { get; set; }
|
||||
public bool IsCookieToken { get; set; }
|
||||
|
||||
public BinaryBlob SecurityToken
|
||||
{
|
||||
|
|
|
@ -6,23 +6,23 @@ using System;
|
|||
namespace Microsoft.AspNet.Antiforgery
|
||||
{
|
||||
/// <summary>
|
||||
/// The antiforgery token pair (cookie and form token) for a request.
|
||||
/// The antiforgery token pair (cookie and request token) for a request.
|
||||
/// </summary>
|
||||
public class AntiforgeryTokenSet
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the antiforgery token pair (cookie and form token) for a request.
|
||||
/// Creates the antiforgery token pair (cookie and request token) for a request.
|
||||
/// </summary>
|
||||
/// <param name="formToken">The token that is supplied in the request form body.</param>
|
||||
/// <param name="requestToken">The token that is supplied in the request.</param>
|
||||
/// <param name="cookieToken">The token that is supplied in the request cookie.</param>
|
||||
public AntiforgeryTokenSet(string formToken, string cookieToken)
|
||||
public AntiforgeryTokenSet(string requestToken, string cookieToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(formToken))
|
||||
if (string.IsNullOrEmpty(requestToken))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(formToken));
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(requestToken));
|
||||
}
|
||||
|
||||
FormToken = formToken;
|
||||
RequestToken = requestToken;
|
||||
|
||||
// Cookie Token is allowed to be null in the case when the old cookie is valid
|
||||
// and there is no new cookieToken generated.
|
||||
|
@ -30,9 +30,9 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The token that is supplied in the request form body.
|
||||
/// The token that is supplied in the request.
|
||||
/// </summary>
|
||||
public string FormToken { get; private set; }
|
||||
public string RequestToken { get; private set; }
|
||||
|
||||
/// The cookie token is allowed to be null.
|
||||
/// This would be the case when the old cookie token is still valid.
|
||||
|
|
|
@ -45,14 +45,14 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
var tokenSet = GetAndStoreTokens(context);
|
||||
|
||||
// Though FormToken normally contains only US-ASCII letters, numbers, '-', and '_', must assume the
|
||||
// Though RequestToken normally contains only US-ASCII letters, numbers, '-', and '_', must assume the
|
||||
// IAntiforgeryTokenSerializer implementation has been overridden. Similarly, users may choose a
|
||||
// FormFieldName containing almost any character.
|
||||
var content = new HtmlContentBuilder()
|
||||
.AppendHtml("<input name=\"")
|
||||
.Append(_options.FormFieldName)
|
||||
.AppendHtml("\" type=\"hidden\" value=\"")
|
||||
.Append(tokenSet.FormToken)
|
||||
.Append(tokenSet.RequestToken)
|
||||
.AppendHtml("\" />");
|
||||
|
||||
return content;
|
||||
|
@ -122,22 +122,22 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
nameof(antiforgeryTokenSet));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(antiforgeryTokenSet.FormToken))
|
||||
if (string.IsNullOrEmpty(antiforgeryTokenSet.RequestToken))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
Resources.Antiforgery_FormToken_MustBeProvided_Generic,
|
||||
Resources.Antiforgery_RequestToken_MustBeProvided_Generic,
|
||||
nameof(antiforgeryTokenSet));
|
||||
}
|
||||
|
||||
// Extract cookie & form tokens
|
||||
// Extract cookie & request tokens
|
||||
var deserializedCookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken);
|
||||
var deserializedFormToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.FormToken);
|
||||
var deserializedRequestToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.RequestToken);
|
||||
|
||||
// Validate
|
||||
_tokenGenerator.ValidateTokens(
|
||||
context,
|
||||
deserializedCookieToken,
|
||||
deserializedFormToken);
|
||||
deserializedRequestToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -225,7 +225,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
cookieToken = newCookieToken;
|
||||
}
|
||||
var formToken = _tokenGenerator.GenerateFormToken(
|
||||
var requestToken = _tokenGenerator.GenerateRequestToken(
|
||||
context,
|
||||
cookieToken);
|
||||
|
||||
|
@ -233,7 +233,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
// Note : The new cookie would be null if the old cookie is valid.
|
||||
CookieToken = cookieToken,
|
||||
FormToken = formToken,
|
||||
RequestToken = requestToken,
|
||||
IsNewCookieToken = newCookieToken != null
|
||||
};
|
||||
}
|
||||
|
@ -241,13 +241,13 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
private AntiforgeryTokenSet Serialize(AntiforgeryTokenSetInternal tokenSet)
|
||||
{
|
||||
return new AntiforgeryTokenSet(
|
||||
tokenSet.FormToken != null ? _tokenSerializer.Serialize(tokenSet.FormToken) : null,
|
||||
tokenSet.RequestToken != null ? _tokenSerializer.Serialize(tokenSet.RequestToken) : null,
|
||||
tokenSet.CookieToken != null ? _tokenSerializer.Serialize(tokenSet.CookieToken) : null);
|
||||
}
|
||||
|
||||
private class AntiforgeryTokenSetInternal
|
||||
{
|
||||
public AntiforgeryToken FormToken { get; set; }
|
||||
public AntiforgeryToken RequestToken { get; set; }
|
||||
|
||||
public AntiforgeryToken CookieToken { get; set; }
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
return new AntiforgeryToken()
|
||||
{
|
||||
// SecurityToken will be populated automatically.
|
||||
IsSessionToken = true
|
||||
IsCookieToken = true
|
||||
};
|
||||
}
|
||||
|
||||
public AntiforgeryToken GenerateFormToken(
|
||||
public AntiforgeryToken GenerateRequestToken(
|
||||
HttpContext httpContext,
|
||||
AntiforgeryToken cookieToken)
|
||||
{
|
||||
|
@ -42,10 +42,10 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
Debug.Assert(IsCookieTokenValid(cookieToken));
|
||||
|
||||
var formToken = new AntiforgeryToken()
|
||||
var requestToken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
IsSessionToken = false
|
||||
IsCookieToken = false
|
||||
};
|
||||
|
||||
var isIdentityAuthenticated = false;
|
||||
|
@ -55,23 +55,23 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
if (identity != null && identity.IsAuthenticated)
|
||||
{
|
||||
isIdentityAuthenticated = true;
|
||||
formToken.ClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(identity));
|
||||
if (formToken.ClaimUid == null)
|
||||
requestToken.ClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(identity));
|
||||
if (requestToken.ClaimUid == null)
|
||||
{
|
||||
formToken.Username = identity.Name;
|
||||
requestToken.Username = identity.Name;
|
||||
}
|
||||
}
|
||||
|
||||
// populate AdditionalData
|
||||
if (_additionalDataProvider != null)
|
||||
{
|
||||
formToken.AdditionalData = _additionalDataProvider.GetAdditionalData(httpContext);
|
||||
requestToken.AdditionalData = _additionalDataProvider.GetAdditionalData(httpContext);
|
||||
}
|
||||
|
||||
if (isIdentityAuthenticated
|
||||
&& string.IsNullOrEmpty(formToken.Username)
|
||||
&& formToken.ClaimUid == null
|
||||
&& string.IsNullOrEmpty(formToken.AdditionalData))
|
||||
&& string.IsNullOrEmpty(requestToken.Username)
|
||||
&& requestToken.ClaimUid == null
|
||||
&& string.IsNullOrEmpty(requestToken.AdditionalData))
|
||||
{
|
||||
// Application says user is authenticated, but we have no identifier for the user.
|
||||
throw new InvalidOperationException(
|
||||
|
@ -84,46 +84,46 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
nameof(DefaultAntiforgeryAdditionalDataProvider)));
|
||||
}
|
||||
|
||||
return formToken;
|
||||
return requestToken;
|
||||
}
|
||||
|
||||
public bool IsCookieTokenValid(AntiforgeryToken cookieToken)
|
||||
{
|
||||
return (cookieToken != null && cookieToken.IsSessionToken);
|
||||
return (cookieToken != null && cookieToken.IsCookieToken);
|
||||
}
|
||||
|
||||
public void ValidateTokens(
|
||||
HttpContext httpContext,
|
||||
AntiforgeryToken sessionToken,
|
||||
AntiforgeryToken fieldToken)
|
||||
AntiforgeryToken cookieToken,
|
||||
AntiforgeryToken requestToken)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(httpContext));
|
||||
}
|
||||
|
||||
if (sessionToken == null)
|
||||
if (cookieToken == null)
|
||||
{
|
||||
throw new ArgumentNullException(
|
||||
nameof(sessionToken),
|
||||
nameof(cookieToken),
|
||||
Resources.Antiforgery_CookieToken_MustBeProvided_Generic);
|
||||
}
|
||||
|
||||
if (fieldToken == null)
|
||||
if (requestToken == null)
|
||||
{
|
||||
throw new ArgumentNullException(
|
||||
nameof(fieldToken),
|
||||
Resources.Antiforgery_FormToken_MustBeProvided_Generic);
|
||||
nameof(requestToken),
|
||||
Resources.Antiforgery_RequestToken_MustBeProvided_Generic);
|
||||
}
|
||||
|
||||
// Do the tokens have the correct format?
|
||||
if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken)
|
||||
if (!cookieToken.IsCookieToken || requestToken.IsCookieToken)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.AntiforgeryToken_TokensSwapped);
|
||||
}
|
||||
|
||||
// Are the security tokens embedded in each incoming token identical?
|
||||
if (!Equals(sessionToken.SecurityToken, fieldToken.SecurityToken))
|
||||
if (!Equals(cookieToken.SecurityToken, requestToken.SecurityToken))
|
||||
{
|
||||
throw new InvalidOperationException(Resources.AntiforgeryToken_SecurityTokenMismatch);
|
||||
}
|
||||
|
@ -148,24 +148,24 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
|
||||
currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!string.Equals(fieldToken.Username,
|
||||
if (!string.Equals(requestToken.Username,
|
||||
currentUsername,
|
||||
(useCaseSensitiveUsernameComparison) ?
|
||||
StringComparison.Ordinal :
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatAntiforgeryToken_UsernameMismatch(fieldToken.Username, currentUsername));
|
||||
Resources.FormatAntiforgeryToken_UsernameMismatch(requestToken.Username, currentUsername));
|
||||
}
|
||||
|
||||
if (!Equals(fieldToken.ClaimUid, currentClaimUid))
|
||||
if (!Equals(requestToken.ClaimUid, currentClaimUid))
|
||||
{
|
||||
throw new InvalidOperationException(Resources.AntiforgeryToken_ClaimUidMismatch);
|
||||
}
|
||||
|
||||
// Is the AdditionalData valid?
|
||||
if (_additionalDataProvider != null &&
|
||||
!_additionalDataProvider.ValidateAdditionalData(httpContext, fieldToken.AdditionalData))
|
||||
!_additionalDataProvider.ValidateAdditionalData(httpContext, requestToken.AdditionalData))
|
||||
{
|
||||
throw new InvalidOperationException(Resources.AntiforgeryToken_AdditionalDataCheckFailed);
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
/* The serialized format of the anti-XSRF token is as follows:
|
||||
* Version: 1 byte integer
|
||||
* SecurityToken: 16 byte binary blob
|
||||
* IsSessionToken: 1 byte Boolean
|
||||
* [if IsSessionToken != true]
|
||||
* IsCookieToken: 1 byte Boolean
|
||||
* [if IsCookieToken != true]
|
||||
* +- IsClaimsBased: 1 byte Boolean
|
||||
* | [if IsClaimsBased = true]
|
||||
* | `- ClaimUid: 32 byte binary blob
|
||||
|
@ -78,9 +78,9 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var securityTokenBytes = reader.ReadBytes(AntiforgeryToken.SecurityTokenBitLength / 8);
|
||||
deserializedToken.SecurityToken =
|
||||
new BinaryBlob(AntiforgeryToken.SecurityTokenBitLength, securityTokenBytes);
|
||||
deserializedToken.IsSessionToken = reader.ReadBoolean();
|
||||
deserializedToken.IsCookieToken = reader.ReadBoolean();
|
||||
|
||||
if (!deserializedToken.IsSessionToken)
|
||||
if (!deserializedToken.IsCookieToken)
|
||||
{
|
||||
var isClaimsBased = reader.ReadBoolean();
|
||||
if (isClaimsBased)
|
||||
|
@ -119,9 +119,9 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
writer.Write(TokenVersion);
|
||||
writer.Write(token.SecurityToken.GetData());
|
||||
writer.Write(token.IsSessionToken);
|
||||
writer.Write(token.IsCookieToken);
|
||||
|
||||
if (!token.IsSessionToken)
|
||||
if (!token.IsCookieToken)
|
||||
{
|
||||
if (token.ClaimUid != null)
|
||||
{
|
||||
|
|
|
@ -7,10 +7,10 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNet.Antiforgery
|
||||
{
|
||||
// Saves anti-XSRF tokens split between HttpRequest.Cookies and HttpRequest.Form
|
||||
public class DefaultAntiforgeryTokenStore : IAntiforgeryTokenStore
|
||||
{
|
||||
private readonly AntiforgeryOptions _options;
|
||||
|
@ -72,23 +72,43 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.CookieName));
|
||||
}
|
||||
|
||||
if (!httpContext.Request.HasFormContentType)
|
||||
StringValues requestToken;
|
||||
if (httpContext.Request.HasFormContentType)
|
||||
{
|
||||
// Check the content-type before accessing the form collection to make sure
|
||||
// we throw gracefully.
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName));
|
||||
var form = await httpContext.Request.ReadFormAsync();
|
||||
requestToken = form[_options.FormFieldName];
|
||||
}
|
||||
|
||||
var form = await httpContext.Request.ReadFormAsync();
|
||||
var formField = form[_options.FormFieldName];
|
||||
if (string.IsNullOrEmpty(formField))
|
||||
// Fall back to header if the form value was not provided.
|
||||
if (requestToken.Count == 0 && _options.HeaderName != null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName));
|
||||
requestToken = httpContext.Request.Headers[_options.HeaderName];
|
||||
}
|
||||
|
||||
return new AntiforgeryTokenSet(formField, requestCookie);
|
||||
if (requestToken.Count == 0)
|
||||
{
|
||||
if (_options.HeaderName == null)
|
||||
{
|
||||
var message = Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
else if (!httpContext.Request.HasFormContentType)
|
||||
{
|
||||
var message = Resources.FormatAntiforgery_HeaderToken_MustBeProvided(_options.HeaderName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = Resources.FormatAntiforgery_RequestToken_MustBeProvided(
|
||||
_options.FormFieldName,
|
||||
_options.HeaderName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
}
|
||||
|
||||
return new AntiforgeryTokenSet(requestToken, requestCookie);
|
||||
}
|
||||
|
||||
public void SaveCookieToken(HttpContext httpContext, AntiforgeryToken token)
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
/// </summary>
|
||||
/// <param name="context">The <see cref="HttpContext"/> associated with the current request.</param>
|
||||
/// <param name="antiforgeryTokenSet">
|
||||
/// The <see cref="AntiforgeryTokenSet"/> (cookie and form token) for this request.
|
||||
/// The <see cref="AntiforgeryTokenSet"/> (cookie and request token) for this request.
|
||||
/// </param>
|
||||
void ValidateTokens(HttpContext context, AntiforgeryTokenSet antiforgeryTokenSet);
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
// Generates a new random cookie token.
|
||||
AntiforgeryToken GenerateCookieToken();
|
||||
|
||||
// Given a cookie token, generates a corresponding form token.
|
||||
// Given a cookie token, generates a corresponding request token.
|
||||
// The incoming cookie token must be valid.
|
||||
AntiforgeryToken GenerateFormToken(
|
||||
AntiforgeryToken GenerateRequestToken(
|
||||
HttpContext httpContext,
|
||||
AntiforgeryToken cookieToken);
|
||||
|
||||
|
@ -23,10 +23,10 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
// If it is not, the caller must call GenerateCookieToken() before calling GenerateFormToken().
|
||||
bool IsCookieTokenValid(AntiforgeryToken cookieToken);
|
||||
|
||||
// Validates a (cookie, form) token pair.
|
||||
// Validates a (cookie, request) token pair.
|
||||
void ValidateTokens(
|
||||
HttpContext httpContext,
|
||||
AntiforgeryToken cookieToken,
|
||||
AntiforgeryToken formToken);
|
||||
AntiforgeryToken requestToken);
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
AntiforgeryToken GetCookieToken(HttpContext httpContext);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cookie and form tokens from the request. Will throw an exception if either token is
|
||||
/// Gets the cookie and request 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>
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The antiforgery cookie token and form field token do not match.
|
||||
/// The antiforgery cookie token and request token do not match.
|
||||
/// </summary>
|
||||
internal static string AntiforgeryToken_SecurityTokenMismatch
|
||||
{
|
||||
|
@ -83,7 +83,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The antiforgery cookie token and form field token do not match.
|
||||
/// The antiforgery cookie token and request token do not match.
|
||||
/// </summary>
|
||||
internal static string FormatAntiforgeryToken_SecurityTokenMismatch()
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation of the provided antiforgery token failed. The cookie token and the form token were swapped.
|
||||
/// Validation of the provided antiforgery token failed. The cookie token and the request token were swapped.
|
||||
/// </summary>
|
||||
internal static string AntiforgeryToken_TokensSwapped
|
||||
{
|
||||
|
@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation of the provided antiforgery token failed. The cookie token and the form token were swapped.
|
||||
/// Validation of the provided antiforgery token failed. The cookie token and the request token were swapped.
|
||||
/// </summary>
|
||||
internal static string FormatAntiforgeryToken_TokensSwapped()
|
||||
{
|
||||
|
@ -155,7 +155,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The cookie token must be provided.
|
||||
/// The required antiforgery cookie token must be provided.
|
||||
/// </summary>
|
||||
internal static string Antiforgery_CookieToken_MustBeProvided_Generic
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The cookie token must be provided.
|
||||
/// The required antiforgery cookie token must be provided.
|
||||
/// </summary>
|
||||
internal static string FormatAntiforgery_CookieToken_MustBeProvided_Generic()
|
||||
{
|
||||
|
@ -187,19 +187,51 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The form token must be provided.
|
||||
/// The required antiforgery header value "{0}" is not present.
|
||||
/// </summary>
|
||||
internal static string Antiforgery_FormToken_MustBeProvided_Generic
|
||||
internal static string Antiforgery_HeaderToken_MustBeProvided
|
||||
{
|
||||
get { return GetString("Antiforgery_FormToken_MustBeProvided_Generic"); }
|
||||
get { return GetString("Antiforgery_HeaderToken_MustBeProvided"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The form token must be provided.
|
||||
/// The required antiforgery header value "{0}" is not present.
|
||||
/// </summary>
|
||||
internal static string FormatAntiforgery_FormToken_MustBeProvided_Generic()
|
||||
internal static string FormatAntiforgery_HeaderToken_MustBeProvided(object p0)
|
||||
{
|
||||
return GetString("Antiforgery_FormToken_MustBeProvided_Generic");
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Antiforgery_HeaderToken_MustBeProvided"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The required antiforgery request token was not provided in either form field "{0}" or header value "{1}".
|
||||
/// </summary>
|
||||
internal static string Antiforgery_RequestToken_MustBeProvided
|
||||
{
|
||||
get { return GetString("Antiforgery_RequestToken_MustBeProvided"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The required antiforgery request token was not provided in either form field "{0}" or header value "{1}".
|
||||
/// </summary>
|
||||
internal static string FormatAntiforgery_RequestToken_MustBeProvided(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Antiforgery_RequestToken_MustBeProvided"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The required antiforgery request token must be provided.
|
||||
/// </summary>
|
||||
internal static string Antiforgery_RequestToken_MustBeProvided_Generic
|
||||
{
|
||||
get { return GetString("Antiforgery_RequestToken_MustBeProvided_Generic"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The required antiforgery request token must be provided.
|
||||
/// </summary>
|
||||
internal static string FormatAntiforgery_RequestToken_MustBeProvided_Generic()
|
||||
{
|
||||
return GetString("Antiforgery_RequestToken_MustBeProvided_Generic");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -131,10 +131,10 @@
|
|||
<value>The antiforgery token could not be decrypted.</value>
|
||||
</data>
|
||||
<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 request token do not match.</value>
|
||||
</data>
|
||||
<data name="AntiforgeryToken_TokensSwapped" xml:space="preserve">
|
||||
<value>Validation of the provided antiforgery token failed. The cookie token and the form token were swapped.</value>
|
||||
<value>Validation of the provided antiforgery token failed. The cookie token and the request token were swapped.</value>
|
||||
</data>
|
||||
<data name="AntiforgeryToken_UsernameMismatch" xml:space="preserve">
|
||||
<value>The provided antiforgery token was meant for user "{0}", but the current user is "{1}".</value>
|
||||
|
@ -147,13 +147,19 @@
|
|||
<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>
|
||||
<value>The required antiforgery 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 name="Antiforgery_HeaderToken_MustBeProvided" xml:space="preserve">
|
||||
<value>The required antiforgery header value "{0}" is not present.</value>
|
||||
</data>
|
||||
<data name="Antiforgery_RequestToken_MustBeProvided" xml:space="preserve">
|
||||
<value>The required antiforgery request token was not provided in either form field "{0}" or header value "{1}".</value>
|
||||
</data>
|
||||
<data name="Antiforgery_RequestToken_MustBeProvided_Generic" xml:space="preserve">
|
||||
<value>The required antiforgery request token must be provided.</value>
|
||||
</data>
|
||||
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
||||
<value>Value cannot be null or empty.</value>
|
||||
|
|
|
@ -45,21 +45,21 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void IsSessionTokenProperty()
|
||||
public void IsCookieTokenProperty()
|
||||
{
|
||||
// Arrange
|
||||
var token = new AntiforgeryToken();
|
||||
|
||||
// Act & assert - 1
|
||||
Assert.False(token.IsSessionToken);
|
||||
Assert.False(token.IsCookieToken);
|
||||
|
||||
// Act & assert - 2
|
||||
token.IsSessionToken = true;
|
||||
Assert.True(token.IsSessionToken);
|
||||
token.IsCookieToken = true;
|
||||
Assert.True(token.IsCookieToken);
|
||||
|
||||
// Act & assert - 3
|
||||
token.IsSessionToken = false;
|
||||
Assert.False(token.IsSessionToken);
|
||||
token.IsCookieToken = false;
|
||||
Assert.False(token.IsCookieToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -289,7 +289,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Assert
|
||||
Assert.Equal("serialized-new-cookie-token", tokenset.CookieToken);
|
||||
Assert.Equal("serialized-form-token", tokenset.FormToken);
|
||||
Assert.Equal("serialized-form-token", tokenset.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -316,7 +316,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Assert
|
||||
Assert.Equal("serialized-new-cookie-token", tokenset.CookieToken);
|
||||
Assert.Equal("serialized-form-token", tokenset.FormToken);
|
||||
Assert.Equal("serialized-form-token", tokenset.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -334,7 +334,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Assert
|
||||
Assert.Equal("serialized-old-cookie-token", tokenset.CookieToken);
|
||||
Assert.Equal("serialized-form-token", tokenset.FormToken);
|
||||
Assert.Equal("serialized-form-token", tokenset.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -356,7 +356,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
t => t.SaveCookieToken(It.IsAny<HttpContext>(), It.IsAny<AntiforgeryToken>()), Times.Never);
|
||||
|
||||
Assert.Equal("serialized-old-cookie-token", tokenSet.CookieToken);
|
||||
Assert.Equal("serialized-form-token", tokenSet.FormToken);
|
||||
Assert.Equal("serialized-form-token", tokenSet.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -377,7 +377,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
t => t.SaveCookieToken(It.IsAny<HttpContext>(), It.IsAny<AntiforgeryToken>()), Times.Once);
|
||||
|
||||
Assert.Equal("serialized-new-cookie-token", tokenSet.CookieToken);
|
||||
Assert.Equal("serialized-form-token", tokenSet.FormToken);
|
||||
Assert.Equal("serialized-form-token", tokenSet.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -391,13 +391,13 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
.Returns(context.TestTokenSet.OldCookieToken);
|
||||
context.TokenSerializer
|
||||
.Setup(o => o.Deserialize("form-token"))
|
||||
.Returns(context.TestTokenSet.FormToken);
|
||||
.Returns(context.TestTokenSet.RequestToken);
|
||||
|
||||
context.TokenGenerator
|
||||
.Setup(o => o.ValidateTokens(
|
||||
context.HttpContext,
|
||||
context.TestTokenSet.OldCookieToken,
|
||||
context.TestTokenSet.FormToken))
|
||||
context.TestTokenSet.RequestToken))
|
||||
.Throws(new InvalidOperationException("my-message"));
|
||||
context.TokenStore = null;
|
||||
var antiforgery = GetAntiforgery(context);
|
||||
|
@ -421,13 +421,13 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
.Returns(context.TestTokenSet.OldCookieToken);
|
||||
context.TokenSerializer
|
||||
.Setup(o => o.Deserialize("form-token"))
|
||||
.Returns(context.TestTokenSet.FormToken);
|
||||
.Returns(context.TestTokenSet.RequestToken);
|
||||
|
||||
context.TokenGenerator
|
||||
.Setup(o => o.ValidateTokens(
|
||||
context.HttpContext,
|
||||
context.TestTokenSet.OldCookieToken,
|
||||
context.TestTokenSet.FormToken))
|
||||
context.TestTokenSet.RequestToken))
|
||||
.Verifiable();
|
||||
context.TokenStore = null;
|
||||
var antiforgery = GetAntiforgery(context);
|
||||
|
@ -455,7 +455,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Assert
|
||||
var trimmed = exception.Message.Substring(0, exception.Message.IndexOf(Environment.NewLine));
|
||||
Assert.Equal("The cookie token must be provided.", trimmed);
|
||||
Assert.Equal("The required antiforgery cookie token must be provided.", trimmed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -468,7 +468,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
.Setup(o => o.ValidateTokens(
|
||||
context.HttpContext,
|
||||
context.TestTokenSet.OldCookieToken,
|
||||
context.TestTokenSet.FormToken))
|
||||
context.TestTokenSet.RequestToken))
|
||||
.Throws(new InvalidOperationException("my-message"));
|
||||
|
||||
var antiforgery = GetAntiforgery(context);
|
||||
|
@ -489,7 +489,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
.Setup(o => o.ValidateTokens(
|
||||
context.HttpContext,
|
||||
context.TestTokenSet.OldCookieToken,
|
||||
context.TestTokenSet.FormToken))
|
||||
context.TestTokenSet.RequestToken))
|
||||
.Verifiable();
|
||||
|
||||
var antiforgery = GetAntiforgery(context);
|
||||
|
@ -567,7 +567,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
bool saveNewCookie = true)
|
||||
{
|
||||
var oldCookieToken = testTokenSet.OldCookieToken;
|
||||
var formToken = testTokenSet.FormToken;
|
||||
var formToken = testTokenSet.RequestToken;
|
||||
var mockTokenStore = new Mock<IAntiforgeryTokenStore>(MockBehavior.Strict);
|
||||
mockTokenStore.Setup(o => o.GetCookieToken(context))
|
||||
.Returns(oldCookieToken);
|
||||
|
@ -591,7 +591,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
var oldCookieToken = testTokenSet.OldCookieToken;
|
||||
var newCookieToken = testTokenSet.NewCookieToken;
|
||||
var formToken = testTokenSet.FormToken;
|
||||
var formToken = testTokenSet.RequestToken;
|
||||
var mockSerializer = new Mock<IAntiforgeryTokenSerializer>(MockBehavior.Strict);
|
||||
mockSerializer.Setup(o => o.Serialize(formToken))
|
||||
.Returns(testTokenSet.FormTokenString);
|
||||
|
@ -613,7 +613,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
// Arrange
|
||||
var httpContext = GetHttpContext();
|
||||
var testTokenSet = GetTokenSet(isOldCookieTokenSessionToken: true, isNewCookieSessionToken: true);
|
||||
var testTokenSet = GetTokenSet();
|
||||
|
||||
var mockSerializer = GetTokenSerializer(testTokenSet);
|
||||
|
||||
|
@ -621,10 +621,10 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
var mockGenerator = new Mock<IAntiforgeryTokenGenerator>(MockBehavior.Strict);
|
||||
mockGenerator
|
||||
.Setup(o => o.GenerateFormToken(
|
||||
.Setup(o => o.GenerateRequestToken(
|
||||
httpContext,
|
||||
useOldCookie ? testTokenSet.OldCookieToken : testTokenSet.NewCookieToken))
|
||||
.Returns(testTokenSet.FormToken);
|
||||
.Returns(testTokenSet.RequestToken);
|
||||
|
||||
mockGenerator
|
||||
.Setup(o => o.GenerateCookieToken())
|
||||
|
@ -649,22 +649,22 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
};
|
||||
}
|
||||
|
||||
private TestTokenSet GetTokenSet(bool isOldCookieTokenSessionToken = true, bool isNewCookieSessionToken = true)
|
||||
private TestTokenSet GetTokenSet()
|
||||
{
|
||||
return new TestTokenSet()
|
||||
{
|
||||
FormToken = new AntiforgeryToken() { IsSessionToken = false },
|
||||
RequestToken = new AntiforgeryToken() { IsCookieToken = false },
|
||||
FormTokenString = "serialized-form-token",
|
||||
OldCookieToken = new AntiforgeryToken() { IsSessionToken = isOldCookieTokenSessionToken },
|
||||
OldCookieToken = new AntiforgeryToken() { IsCookieToken = true },
|
||||
OldCookieTokenString = "serialized-old-cookie-token",
|
||||
NewCookieToken = new AntiforgeryToken() { IsSessionToken = isNewCookieSessionToken },
|
||||
NewCookieToken = new AntiforgeryToken() { IsCookieToken = true },
|
||||
NewCookieTokenString = "serialized-new-cookie-token",
|
||||
};
|
||||
}
|
||||
|
||||
private class TestTokenSet
|
||||
{
|
||||
public AntiforgeryToken FormToken { get; set; }
|
||||
public AntiforgeryToken RequestToken { get; set; }
|
||||
|
||||
public string FormTokenString { get; set; }
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
public void GenerateFormToken_AnonymousUser()
|
||||
{
|
||||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
Assert.False(httpContext.User.Identity.IsAuthenticated);
|
||||
|
@ -41,12 +41,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: null);
|
||||
|
||||
// Act
|
||||
var fieldToken = tokenProvider.GenerateFormToken(httpContext, cookieToken);
|
||||
var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(fieldToken);
|
||||
Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
|
||||
Assert.False(fieldToken.IsSessionToken);
|
||||
Assert.False(fieldToken.IsCookieToken);
|
||||
Assert.Empty(fieldToken.Username);
|
||||
Assert.Null(fieldToken.ClaimUid);
|
||||
Assert.Empty(fieldToken.AdditionalData);
|
||||
|
@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken()
|
||||
{
|
||||
IsSessionToken = true
|
||||
IsCookieToken = true
|
||||
};
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
@ -73,7 +73,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Act & assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(
|
||||
() => tokenProvider.GenerateFormToken(httpContext, cookieToken));
|
||||
() => tokenProvider.GenerateRequestToken(httpContext, cookieToken));
|
||||
Assert.Equal(
|
||||
"The provided identity of type " +
|
||||
$"'{typeof(MyAuthenticatedIdentityWithoutUsername).FullName}' " +
|
||||
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData()
|
||||
{
|
||||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.User = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername());
|
||||
|
@ -106,12 +106,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||
|
||||
// Act
|
||||
var fieldToken = tokenProvider.GenerateFormToken(httpContext, cookieToken);
|
||||
var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(fieldToken);
|
||||
Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
|
||||
Assert.False(fieldToken.IsSessionToken);
|
||||
Assert.False(fieldToken.IsCookieToken);
|
||||
Assert.Empty(fieldToken.Username);
|
||||
Assert.Null(fieldToken.ClaimUid);
|
||||
Assert.Equal("additional-data", fieldToken.AdditionalData);
|
||||
|
@ -121,7 +121,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
public void GenerateFormToken_ClaimsBasedIdentity()
|
||||
{
|
||||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
|
||||
var identity = GetAuthenticatedIdentity("some-identity");
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
@ -144,12 +144,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: null);
|
||||
|
||||
// Act
|
||||
var fieldToken = tokenProvider.GenerateFormToken(httpContext, cookieToken);
|
||||
var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(fieldToken);
|
||||
Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
|
||||
Assert.False(fieldToken.IsSessionToken);
|
||||
Assert.False(fieldToken.IsCookieToken);
|
||||
Assert.Equal("", fieldToken.Username);
|
||||
Assert.Equal(expectedClaimUid, fieldToken.ClaimUid);
|
||||
Assert.Equal("", fieldToken.AdditionalData);
|
||||
|
@ -159,7 +159,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
public void GenerateFormToken_RegularUserWithUsername()
|
||||
{
|
||||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var mockIdentity = new Mock<ClaimsIdentity>();
|
||||
|
@ -177,12 +177,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: null);
|
||||
|
||||
// Act
|
||||
var fieldToken = tokenProvider.GenerateFormToken(httpContext, cookieToken);
|
||||
var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(fieldToken);
|
||||
Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken);
|
||||
Assert.False(fieldToken.IsSessionToken);
|
||||
Assert.False(fieldToken.IsCookieToken);
|
||||
Assert.Equal("my-username", fieldToken.Username);
|
||||
Assert.Null(fieldToken.ClaimUid);
|
||||
Assert.Empty(fieldToken.AdditionalData);
|
||||
|
@ -194,7 +194,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken()
|
||||
{
|
||||
IsSessionToken = false
|
||||
IsCookieToken = false
|
||||
};
|
||||
|
||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||
|
@ -230,7 +230,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
// Arrange
|
||||
var cookieToken = new AntiforgeryToken()
|
||||
{
|
||||
IsSessionToken = true
|
||||
IsCookieToken = true
|
||||
};
|
||||
|
||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||
|
@ -246,13 +246,13 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
|
||||
[Fact]
|
||||
public void ValidateTokens_SessionTokenMissing()
|
||||
public void ValidateTokens_CookieTokenMissing()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
|
||||
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
||||
var fieldtoken = new AntiforgeryToken() { IsCookieToken = false };
|
||||
|
||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||
claimUidExtractor: null,
|
||||
|
@ -263,7 +263,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
() => tokenProvider.ValidateTokens(httpContext, null, fieldtoken));
|
||||
|
||||
var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine));
|
||||
Assert.Equal(@"The cookie token must be provided.", trimmed);
|
||||
Assert.Equal(@"The required antiforgery cookie token must be provided.", trimmed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -273,7 +273,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
|
||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||
claimUidExtractor: null,
|
||||
|
@ -281,21 +281,21 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<ArgumentNullException>(
|
||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, null));
|
||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, null));
|
||||
|
||||
var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine));
|
||||
Assert.Equal("The form token must be provided.", trimmed);
|
||||
Assert.Equal("The required antiforgery request token must be provided.", trimmed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidateTokens_FieldAndSessionTokensSwapped()
|
||||
public void ValidateTokens_FieldAndCookieTokensSwapped()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken() { IsCookieToken = false };
|
||||
|
||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||
claimUidExtractor: null,
|
||||
|
@ -307,27 +307,27 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
() => tokenProvider.ValidateTokens(httpContext, fieldtoken, fieldtoken));
|
||||
Assert.Equal(
|
||||
"Validation of the provided antiforgery token failed. " +
|
||||
@"The cookie token and the form token were swapped.",
|
||||
@"The cookie token and the request token were swapped.",
|
||||
ex1.Message);
|
||||
|
||||
var ex2 =
|
||||
Assert.Throws<InvalidOperationException>(
|
||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, sessionToken));
|
||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, cookieToken));
|
||||
Assert.Equal(
|
||||
"Validation of the provided antiforgery token failed. " +
|
||||
@"The cookie token and the form token were swapped.",
|
||||
@"The cookie token and the request token were swapped.",
|
||||
ex2.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidateTokens_FieldAndSessionTokensHaveDifferentSecurityKeys()
|
||||
public void ValidateTokens_FieldAndCookieTokensHaveDifferentSecurityKeys()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var fieldtoken = new AntiforgeryToken() { IsSessionToken = false };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken() { IsCookieToken = false };
|
||||
|
||||
var tokenProvider = new DefaultAntiforgeryTokenGenerator(
|
||||
claimUidExtractor: null,
|
||||
|
@ -335,9 +335,9 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(
|
||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
|
||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||
Assert.Equal(
|
||||
@"The antiforgery cookie token and form field token do not match.",
|
||||
@"The antiforgery cookie token and request token do not match.",
|
||||
exception.Message);
|
||||
}
|
||||
|
||||
|
@ -352,12 +352,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var identity = GetAuthenticatedIdentity(identityUsername);
|
||||
httpContext.User = new ClaimsPrincipal(identity);
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = sessionToken.SecurityToken,
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
Username = embeddedUsername,
|
||||
IsSessionToken = false
|
||||
IsCookieToken = false
|
||||
};
|
||||
|
||||
var mockClaimUidExtractor = new Mock<IClaimUidExtractor>();
|
||||
|
@ -370,7 +370,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(
|
||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
|
||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||
Assert.Equal(
|
||||
@"The provided antiforgery token was meant for user """ + embeddedUsername +
|
||||
@""", but the current user is """ + identityUsername + @""".",
|
||||
|
@ -385,11 +385,11 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var identity = GetAuthenticatedIdentity("the-user");
|
||||
httpContext.User = new ClaimsPrincipal(identity);
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = sessionToken.SecurityToken,
|
||||
IsSessionToken = false,
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
IsCookieToken = false,
|
||||
ClaimUid = new BinaryBlob(256)
|
||||
};
|
||||
|
||||
|
@ -404,7 +404,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Act & assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(
|
||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
|
||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||
Assert.Equal(
|
||||
@"The provided antiforgery token was meant for a different claims-based user than the current user.",
|
||||
exception.Message);
|
||||
|
@ -418,12 +418,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var identity = new ClaimsIdentity();
|
||||
httpContext.User = new ClaimsPrincipal(identity);
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = sessionToken.SecurityToken,
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
Username = String.Empty,
|
||||
IsSessionToken = false,
|
||||
IsCookieToken = false,
|
||||
AdditionalData = "some-additional-data"
|
||||
};
|
||||
|
||||
|
@ -437,7 +437,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Act & assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(
|
||||
() => tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken));
|
||||
() => tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken));
|
||||
Assert.Equal(@"The provided antiforgery token failed a custom data check.", exception.Message);
|
||||
}
|
||||
|
||||
|
@ -449,12 +449,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var identity = new ClaimsIdentity();
|
||||
httpContext.User = new ClaimsPrincipal(identity);
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = sessionToken.SecurityToken,
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
Username = String.Empty,
|
||||
IsSessionToken = false,
|
||||
IsCookieToken = false,
|
||||
AdditionalData = "some-additional-data"
|
||||
};
|
||||
|
||||
|
@ -467,7 +467,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||
|
||||
// Act
|
||||
tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken);
|
||||
tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken);
|
||||
|
||||
// Assert
|
||||
// Nothing to assert - if we got this far, success!
|
||||
|
@ -481,12 +481,12 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var identity = GetAuthenticatedIdentity("the-user");
|
||||
httpContext.User = new ClaimsPrincipal(identity);
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = sessionToken.SecurityToken,
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
Username = "THE-USER",
|
||||
IsSessionToken = false,
|
||||
IsCookieToken = false,
|
||||
AdditionalData = "some-additional-data"
|
||||
};
|
||||
|
||||
|
@ -499,7 +499,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: mockAdditionalDataProvider.Object);
|
||||
|
||||
// Act
|
||||
tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken);
|
||||
tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken);
|
||||
|
||||
// Assert
|
||||
// Nothing to assert - if we got this far, success!
|
||||
|
@ -513,11 +513,11 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var identity = GetAuthenticatedIdentity("the-user");
|
||||
httpContext.User = new ClaimsPrincipal(identity);
|
||||
|
||||
var sessionToken = new AntiforgeryToken() { IsSessionToken = true };
|
||||
var cookieToken = new AntiforgeryToken() { IsCookieToken = true };
|
||||
var fieldtoken = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = sessionToken.SecurityToken,
|
||||
IsSessionToken = false,
|
||||
SecurityToken = cookieToken.SecurityToken,
|
||||
IsCookieToken = false,
|
||||
ClaimUid = new BinaryBlob(256)
|
||||
};
|
||||
|
||||
|
@ -530,7 +530,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
additionalDataProvider: null);
|
||||
|
||||
// Act
|
||||
tokenProvider.ValidateTokens(httpContext, sessionToken, fieldtoken);
|
||||
tokenProvider.ValidateTokens(httpContext, cookieToken, fieldtoken);
|
||||
|
||||
// Assert
|
||||
// Nothing to assert - if we got this far, success!
|
||||
|
|
|
@ -26,18 +26,18 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
[InlineData(
|
||||
"01" // Version
|
||||
+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
|
||||
+ "01" // IsSessionToken
|
||||
+ "01" // IsCookieToken
|
||||
+ "00" // (WRONG!) Too much data in stream
|
||||
)]
|
||||
[InlineData(
|
||||
"02" // (WRONG! - must be 0x01) Version
|
||||
+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
|
||||
+ "01" // IsSessionToken
|
||||
+ "01" // IsCookieToken
|
||||
)]
|
||||
[InlineData(
|
||||
"01" // Version
|
||||
+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
|
||||
+ "00" // IsSessionToken
|
||||
+ "00" // IsCookieToken
|
||||
+ "00" // IsClaimsBased
|
||||
+ "05" // Username length header
|
||||
+ "0000" // (WRONG!) Too little data in stream
|
||||
|
@ -60,7 +60,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
//"01" // Version
|
||||
//+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
|
||||
//+ "00" // IsSessionToken
|
||||
//+ "00" // IsCookieToken
|
||||
//+ "01" // IsClaimsBased
|
||||
//+ "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid
|
||||
//+ "05" // AdditionalData length header
|
||||
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var token = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = _securityToken,
|
||||
IsSessionToken = false,
|
||||
IsCookieToken = false,
|
||||
ClaimUid = _claimUid,
|
||||
AdditionalData = "€47"
|
||||
};
|
||||
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
//"01" // Version
|
||||
//+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
|
||||
//+ "00" // IsSessionToken
|
||||
//+ "00" // IsCookieToken
|
||||
//+ "00" // IsClaimsBased
|
||||
//+ "08" // Username length header
|
||||
//+ "4AC3A972C3B46D65" // Username ("Jérôme") as UTF8
|
||||
|
@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
var token = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = _securityToken,
|
||||
IsSessionToken = false,
|
||||
IsCookieToken = false,
|
||||
Username = "Jérôme",
|
||||
AdditionalData = "€47"
|
||||
};
|
||||
|
@ -114,18 +114,18 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_SessionToken_TokenRoundTripSuccessful()
|
||||
public void Serialize_CookieToken_TokenRoundTripSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
var testSerializer = new DefaultAntiforgeryTokenSerializer(_dataProtector.Object);
|
||||
|
||||
//"01" // Version
|
||||
//+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken
|
||||
//+ "01"; // IsSessionToken
|
||||
//+ "01"; // IsCookieToken
|
||||
var token = new AntiforgeryToken()
|
||||
{
|
||||
SecurityToken = _securityToken,
|
||||
IsSessionToken = true
|
||||
IsCookieToken = true
|
||||
};
|
||||
|
||||
// Act
|
||||
|
@ -178,7 +178,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.AdditionalData, actual.AdditionalData);
|
||||
Assert.Equal(expected.ClaimUid, actual.ClaimUid);
|
||||
Assert.Equal(expected.IsSessionToken, actual.IsSessionToken);
|
||||
Assert.Equal(expected.IsCookieToken, actual.IsCookieToken);
|
||||
Assert.Equal(expected.SecurityToken, actual.SecurityToken);
|
||||
Assert.Equal(expected.Username, actual.Username);
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRequestTokens_NonFormContentType_Throws()
|
||||
public async Task GetRequestTokens_NonFormContentType_HeaderDisabled_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
@ -204,6 +204,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
CookieName = "cookie-name",
|
||||
FormFieldName = "form-field-name",
|
||||
HeaderName = null,
|
||||
};
|
||||
|
||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||
|
@ -219,7 +220,110 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRequestTokens_FormFieldIsEmpty_Throws()
|
||||
public async Task GetRequestTokens_FormContentType_FallbackHeaderToken()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = "application/json";
|
||||
|
||||
// Will not be accessed
|
||||
httpContext.Request.ContentType = "application/x-www-form-urlencoded";
|
||||
httpContext.Request.Form = new FormCollection(new Dictionary<string, StringValues>());
|
||||
httpContext.Request.Cookies = new RequestCookieCollection(new Dictionary<string, string>()
|
||||
{
|
||||
{ "cookie-name", "cookie-value" },
|
||||
});
|
||||
httpContext.Request.Headers.Add("header-name", "header-value");
|
||||
|
||||
var options = new AntiforgeryOptions()
|
||||
{
|
||||
CookieName = "cookie-name",
|
||||
FormFieldName = "form-field-name",
|
||||
HeaderName = "header-name",
|
||||
};
|
||||
|
||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||
optionsAccessor: new TestOptionsManager(options),
|
||||
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
||||
|
||||
// Act
|
||||
var tokens = await tokenStore.GetRequestTokensAsync(httpContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("cookie-value", tokens.CookieToken);
|
||||
Assert.Equal("header-value", tokens.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRequestTokens_NonFormContentType_UsesHeaderToken()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = "application/json";
|
||||
|
||||
// Will not be accessed
|
||||
httpContext.Request.Form = null;
|
||||
httpContext.Request.Cookies = new RequestCookieCollection(new Dictionary<string, string>()
|
||||
{
|
||||
{ "cookie-name", "cookie-value" },
|
||||
});
|
||||
|
||||
httpContext.Request.Headers.Add("header-name", "header-value");
|
||||
|
||||
var options = new AntiforgeryOptions()
|
||||
{
|
||||
CookieName = "cookie-name",
|
||||
FormFieldName = "form-field-name",
|
||||
HeaderName = "header-name",
|
||||
};
|
||||
|
||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||
optionsAccessor: new TestOptionsManager(options),
|
||||
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
||||
|
||||
// Act
|
||||
var tokens = await tokenStore.GetRequestTokensAsync(httpContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("cookie-value", tokens.CookieToken);
|
||||
Assert.Equal("header-value", tokens.RequestToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRequestTokens_NonFormContentType_UsesHeaderToken_ThrowsOnMissingValue()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = "application/json";
|
||||
|
||||
// Will not be accessed
|
||||
httpContext.Request.Form = null;
|
||||
httpContext.Request.Cookies = new RequestCookieCollection(new Dictionary<string, string>()
|
||||
{
|
||||
{ "cookie-name", "cookie-value" },
|
||||
});
|
||||
|
||||
var options = new AntiforgeryOptions()
|
||||
{
|
||||
CookieName = "cookie-name",
|
||||
FormFieldName = "form-field-name",
|
||||
HeaderName = "header-name",
|
||||
};
|
||||
|
||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||
optionsAccessor: new TestOptionsManager(options),
|
||||
tokenSerializer: new DefaultAntiforgeryTokenSerializer(new EphemeralDataProtectionProvider()));
|
||||
|
||||
// Act
|
||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("The required antiforgery header value \"header-name\" is not present.", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRequestTokens_BothFieldsEmpty_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
@ -234,6 +338,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
CookieName = "cookie-name",
|
||||
FormFieldName = "form-field-name",
|
||||
HeaderName = "header-name",
|
||||
};
|
||||
|
||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||
|
@ -245,7 +350,10 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
async () => await tokenStore.GetRequestTokensAsync(httpContext));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("The required antiforgery form field \"form-field-name\" is not present.", exception.Message);
|
||||
Assert.Equal(
|
||||
"The required antiforgery request token was not provided in either form field \"form-field-name\" " +
|
||||
"or header value \"header-name\".",
|
||||
exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -262,11 +370,13 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
{
|
||||
{ "cookie-name", "cookie-value" },
|
||||
});
|
||||
httpContext.Request.Headers.Add("header-name", "header-value"); // form value has priority.
|
||||
|
||||
var options = new AntiforgeryOptions()
|
||||
{
|
||||
CookieName = "cookie-name",
|
||||
FormFieldName = "form-field-name",
|
||||
HeaderName = "header-name",
|
||||
};
|
||||
|
||||
var tokenStore = new DefaultAntiforgeryTokenStore(
|
||||
|
@ -278,7 +388,7 @@ namespace Microsoft.AspNet.Antiforgery
|
|||
|
||||
// Assert
|
||||
Assert.Equal("cookie-value", tokens.CookieToken);
|
||||
Assert.Equal("form-value", tokens.FormToken);
|
||||
Assert.Equal("form-value", tokens.RequestToken);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
Загрузка…
Ссылка в новой задаче