gpt4 book ai didi

c# - 使用 AspNet Core MVC 在 Ajax 请求中验证 AntiForgeryToken

转载 作者:可可西里 更新时间:2023-11-01 08:23:10 30 4
gpt4 key购买 nike

我一直在尝试重新创建一个 Ajax 版本的 ValidateAntiForgeryToken - 有很多关于如何为以前版本的 MVC 执行此操作的博客文章,但是对于最新的 MVC 6,没有任何代码是相关的。不过,我要遵循的核心原则是让验证查看 __RequestVerificationToken 的 Cookie 和 header 。 ,而不是将 Cookie 与表单值进行比较。我使用的是 MVC 6.0.0-rc1-final、dnx451 框架,所有 Microsoft.Extensions 库都是 1.0.0-rc1-final。

我最初的想法是继承ValidateAntiForgeryTokenAttribute ,但是查看源代码,我需要返回我自己的授权过滤器实现,以让它查看 header 。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateAjaxAntiForgeryTokenAttribute : Attribute, IFilterFactory, IFilterMetadata, IOrderedFilter
{
public int Order { get; set; }
public bool IsReusable => true;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return serviceProvider.GetRequiredService<ValidateAjaxAntiforgeryTokenAuthorizationFilter>();
}
}

因此,我制作了自己的 ValidateAntiforgeryTokenAuthorizationFilter 版本

public class ValidateAjaxAntiforgeryTokenAuthorizationFilter : IAsyncAuthorizationFilter, IAntiforgeryPolicy
{
private readonly IAntiforgery _antiforgery;
private readonly ILogger _logger;
public ValidateAjaxAntiforgeryTokenAuthorizationFilter(IAntiforgery antiforgery, ILoggerFactory loggerFactory)
{
if (antiforgery == null)
{
throw new ArgumentNullException(nameof(antiforgery));
}
_antiforgery = antiforgery;
_logger = loggerFactory.CreateLogger<ValidateAjaxAntiforgeryTokenAuthorizationFilter>();
}
public async Task OnAuthorizationAsync(AuthorizationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (IsClosestAntiforgeryPolicy(context.Filters) && ShouldValidate(context))
{
try
{
await _antiforgery.ValidateRequestAsync(context.HttpContext);
}
catch (AjaxAntiforgeryValidationException exception)
{
_logger.LogInformation(1, string.Concat("Ajax Antiforgery token validation failed. ", exception.Message));
context.Result = new BadRequestResult();
}
}
}
protected virtual bool ShouldValidate(AuthorizationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return true;
}
private bool IsClosestAntiforgeryPolicy(IList<IFilterMetadata> filters)
{
// Determine if this instance is the 'effective' antiforgery policy.
for (var i = filters.Count - 1; i >= 0; i--)
{
var filter = filters[i];
if (filter is IAntiforgeryPolicy)
{
return object.ReferenceEquals(this, filter);
}
}
Debug.Fail("The current instance should be in the list of filters.");
return false;
}
}

但是,我找不到包含 IAntiforgeryPolicy 的正确 Nuget 包和命名空间.当我在 GitHub 上找到界面时 - 我在哪个包中找到它?

我的下一次尝试是在 IAntiforgery 注入(inject)之后,替换 DefaultAntiforgery用我自己的AjaxAntiforgery .

public class AjaxAntiforgery : DefaultAntiforgery
{
private readonly AntiforgeryOptions _options;
private readonly IAntiforgeryTokenGenerator _tokenGenerator;
private readonly IAntiforgeryTokenSerializer _tokenSerializer;
private readonly IAntiforgeryTokenStore _tokenStore;
private readonly ILogger<AjaxAntiforgery> _logger;
public AjaxAntiforgery(
IOptions<AntiforgeryOptions> antiforgeryOptionsAccessor,
IAntiforgeryTokenGenerator tokenGenerator,
IAntiforgeryTokenSerializer tokenSerializer,
IAntiforgeryTokenStore tokenStore,
ILoggerFactory loggerFactory)
{
_options = antiforgeryOptionsAccessor.Value;
_tokenGenerator = tokenGenerator;
_tokenSerializer = tokenSerializer;
_tokenStore = tokenStore;
_logger = loggerFactory.CreateLogger<AjaxAntiforgery>();
}
}

在我停滞不前之前我已经走了这么远,因为 ILoggerFactory 上没有通用方法对于 CreateLogger<T>() . DefaultAntiforgery 的源代码有Microsoft.Extensions.Options ,但我无法在任何 Nuget 包中找到该命名空间。 Microsoft.Extensions.OptionsModel存在,但这只会带来 IOptions<out TOptions>界面。

为了跟进所有这些,一旦我确实让授权过滤器工作,或者我得到了 IAntiforgery 的新实现。 ,在哪里或如何使用依赖注入(inject)注册它以使用它 - 并且仅用于我将接受 Ajax 请求的操作?

最佳答案

我有类似的问题。我不知道 .NET 中是否对此有任何更改,但当时,我在 Startup.cs 中的 ConfigureServices 方法中添加了以下行,在行 services.AddMvc(),以验证通过 Ajax 发送的 AntiForgeryToken:

services.AddAntiforgery(options =>
{
options.CookieName = "yourChosenCookieName";
options.HeaderName = "RequestVerificationToken";
});

AJAX 调用类似于以下内容:

var token = $('input[type=hidden][name=__RequestVerificationToken]', document).val();

var request = $.ajax({
data: { 'yourField': 'yourValue' },
...
headers: { 'RequestVerificationToken': token }
});

然后,只需在您的操作中使用 native 属性 [ValidadeAntiForgeryToken]

关于c# - 使用 AspNet Core MVC 在 Ajax 请求中验证 AntiForgeryToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36628666/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com