Return BadRequest response when antiforgery token validation fails
This commit is contained in:
parent
8afe28c05d
commit
bf1fcf6b56
|
|
@ -4,13 +4,14 @@
|
|||
using System;
|
||||
using Microsoft.AspNet.Antiforgery;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
||||
{
|
||||
public class AutoValidateAntiforgeryTokenAuthorizationFilter : ValidateAntiforgeryTokenAuthorizationFilter
|
||||
{
|
||||
public AutoValidateAntiforgeryTokenAuthorizationFilter(IAntiforgery antiforgery)
|
||||
: base(antiforgery)
|
||||
public AutoValidateAntiforgeryTokenAuthorizationFilter(IAntiforgery antiforgery, ILoggerFactory loggerFactory)
|
||||
: base(antiforgery, loggerFactory)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,17 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Antiforgery;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
using Microsoft.AspNet.Mvc.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
||||
{
|
||||
public class ValidateAntiforgeryTokenAuthorizationFilter : IAsyncAuthorizationFilter, IAntiforgeryPolicy
|
||||
{
|
||||
private readonly IAntiforgery _antiforgery;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ValidateAntiforgeryTokenAuthorizationFilter(IAntiforgery antiforgery)
|
||||
public ValidateAntiforgeryTokenAuthorizationFilter(IAntiforgery antiforgery, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (antiforgery == null)
|
||||
{
|
||||
|
|
@ -23,9 +26,10 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
}
|
||||
|
||||
_antiforgery = antiforgery;
|
||||
_logger = loggerFactory.CreateLogger<ValidateAntiforgeryTokenAuthorizationFilter>();
|
||||
}
|
||||
|
||||
public Task OnAuthorizationAsync(AuthorizationContext context)
|
||||
public async Task OnAuthorizationAsync(AuthorizationContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
|
|
@ -34,10 +38,16 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
|
||||
if (IsClosestAntiforgeryPolicy(context.Filters) && ShouldValidate(context))
|
||||
{
|
||||
return _antiforgery.ValidateRequestAsync(context.HttpContext);
|
||||
try
|
||||
{
|
||||
await _antiforgery.ValidateRequestAsync(context.HttpContext);
|
||||
}
|
||||
catch (AntiforgeryValidationException exception)
|
||||
{
|
||||
_logger.AntiforgeryTokenInvalid(exception.Message, exception);
|
||||
context.Result = new BadRequestResult();
|
||||
}
|
||||
}
|
||||
|
||||
return TaskCache.CompletedTask;
|
||||
}
|
||||
|
||||
protected virtual bool ShouldValidate(AuthorizationContext context)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Logging
|
||||
{
|
||||
public static class ValidateAntiforgeryTokenAuthorizationFilterLoggerExtensions
|
||||
{
|
||||
private static readonly Action<ILogger, string, Exception> _antiforgeryTokenInvalid;
|
||||
|
||||
static ValidateAntiforgeryTokenAuthorizationFilterLoggerExtensions()
|
||||
{
|
||||
_antiforgeryTokenInvalid = LoggerMessage.Define<string>(
|
||||
LogLevel.Information,
|
||||
1,
|
||||
"Antiforgery token validation failed. {Message}");
|
||||
}
|
||||
|
||||
public static void AntiforgeryTokenInvalid(this ILogger logger, string message, Exception exception)
|
||||
{
|
||||
_antiforgeryTokenInvalid(logger, message, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Antiforgery;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
|
|
@ -116,5 +117,33 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("OK", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Antiforgery_HeaderNotSet_SendsBadRequest()
|
||||
{
|
||||
// Arrange
|
||||
var getResponse = await Client.GetAsync("http://localhost/Antiforgery/Login");
|
||||
var responseBody = await getResponse.Content.ReadAsStringAsync();
|
||||
|
||||
var formToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(
|
||||
responseBody,
|
||||
"Antiforgery/Login");
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Antiforgery/Login");
|
||||
var nameValueCollection = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new KeyValuePair<string,string>("__RequestVerificationToken", formToken),
|
||||
new KeyValuePair<string,string>("UserName", "test"),
|
||||
new KeyValuePair<string,string>("Password", "password"),
|
||||
};
|
||||
|
||||
request.Content = new FormUrlEncodedContent(nameValueCollection);
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNet.Http.Internal;
|
|||
using Microsoft.AspNet.Mvc.Abstractions;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
.Returns(Task.FromResult(0))
|
||||
.Verifiable();
|
||||
|
||||
var filter = new AutoValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object);
|
||||
var filter = new AutoValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object, NullLoggerFactory.Instance);
|
||||
|
||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||
actionContext.HttpContext.Request.Method = httpMethod;
|
||||
|
|
@ -56,7 +57,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
.Returns(Task.FromResult(0))
|
||||
.Verifiable();
|
||||
|
||||
var filter = new AutoValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object);
|
||||
var filter = new AutoValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object, NullLoggerFactory.Instance);
|
||||
|
||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||
actionContext.HttpContext.Request.Method = httpMethod;
|
||||
|
|
@ -80,7 +81,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
.Returns(Task.FromResult(0))
|
||||
.Verifiable();
|
||||
|
||||
var filter = new AutoValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object);
|
||||
var filter = new AutoValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object, NullLoggerFactory.Instance);
|
||||
|
||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||
actionContext.HttpContext.Request.Method = "POST";
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNet.Http.Internal;
|
|||
using Microsoft.AspNet.Mvc.Abstractions;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
.Returns(Task.FromResult(0))
|
||||
.Verifiable();
|
||||
|
||||
var filter = new ValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object);
|
||||
var filter = new ValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object, NullLoggerFactory.Instance);
|
||||
|
||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||
actionContext.HttpContext.Request.Method = httpMethod;
|
||||
|
|
@ -56,7 +57,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Internal
|
|||
.Returns(Task.FromResult(0))
|
||||
.Verifiable();
|
||||
|
||||
var filter = new ValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object);
|
||||
var filter = new ValidateAntiforgeryTokenAuthorizationFilter(antiforgery.Object, NullLoggerFactory.Instance);
|
||||
|
||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||
actionContext.HttpContext.Request.Method = "POST";
|
||||
|
|
|
|||
Loading…
Reference in New Issue