public class ValidateAntiforgeryTokenAuthorizationFilter : IAsyncAuthorizationFilter,IAntiforgeryPolicy
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
// Do the tokens have the correct format?
if (!cookieToken.IsCookieToken || requestToken.IsCookieToken)
{
message = Resources.AntiforgeryToken_TokensSwapped;
return false;
}
// Are the security tokens embedded in each incoming token identical?
if (!object.Equals(cookieToken.SecurityToken,requestToken.SecurityToken))
{
message = Resources.AntiforgeryToken_SecurityTokenMismatch;
return false;
}
// Is the incoming token meant for the current user?
var currentUsername = string.Empty;
BinaryBlob currentClaimUid = null;
var authenticatedIdentity = GetAuthenticatedIdentity(httpContext.User);
if (authenticatedIdentity != null)
{
currentClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(httpContext.User));
if (currentClaimUid == null)
{
currentUsername = authenticatedIdentity.Name ?? string.Empty;
}
}
// OpenID and other similar authentication schemes use URIs for the username.
// These should be treated as case-sensitive.
var comparer = StringComparer.OrdinalIgnoreCase;
if (currentUsername.StartsWith("http://",StringComparison.OrdinalIgnoreCase) ||
currentUsername.StartsWith("https://",StringComparison.OrdinalIgnoreCase))
{
comparer = StringComparer.Ordinal;
}
if (!comparer.Equals(requestToken.Username,currentUsername))
{
message = Resources.FormatAntiforgeryToken_UsernameMismatch(requestToken.Username,currentUsername);
return false;
}
if (!object.Equals(requestToken.ClaimUid,currentClaimUid))
{
message = Resources.AntiforgeryToken_ClaimUidMismatch;
return false;
}
// Is the AdditionalData valid?
if (_additionalDataProvider != null &&
!_additionalDataProvider.ValidateAdditionalData(httpContext,requestToken.AdditionalData))
{
message = Resources.AntiforgeryToken_AdditionalDataCheckFailed;
return false;
}
message = null;
return true;