Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何覆盖[ValidateAntiForgeryToken]返回的响应或手动验证令牌?_C#_Asp.net Core_Antiforgerytoken - Fatal编程技术网

C# 如何覆盖[ValidateAntiForgeryToken]返回的响应或手动验证令牌?

C# 如何覆盖[ValidateAntiForgeryToken]返回的响应或手动验证令牌?,c#,asp.net-core,antiforgerytoken,C#,Asp.net Core,Antiforgerytoken,如果我对API方法使用[ValidateAntiForgeryToken]属性,我将获得自动生成的HTTP400 JSON。我希望能够编写JSON内容。我是否可以手动决定对验证问题的响应 我实现了我自己的: public class ExceptionFilteraaAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) {

如果我对API方法使用
[ValidateAntiForgeryToken]
属性,我将获得自动生成的HTTP400 JSON。我希望能够编写JSON内容。我是否可以手动决定对验证问题的响应

我实现了我自己的:

public class ExceptionFilteraaAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        System.Console.WriteLine(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        if (context?.Exception != null)
        {
            context.Result = new ObjectResult(...)
            {
                StatusCode = (int)HttpStatusCode.InternalServerError,
            };
            context.ExceptionHandled = true;
        }
    }
}
但是它永远不会到达这个地方,因为它已经响应了请求


我需要实施:

public class ChangedAntiforgeryResultFilter : ResultFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
  
//this is never hit
    if (context?.Result is AntiforgeryValidationFailedResult)
    {
        context.Result = new BadRequestObjectResult(new LoginErrorResponseDto
        {
            OperationId = context.HttpContext.Features?.Get<RequestTelemetry>()?.Context?.Operation?.Id
        });
    }
}

public override void OnResultExecuted(ResultExecutedContext context)
{
}
my
ChangedAntiForgeryResultFilter
从未访问过,400将返回default内容。

您可以通过复制默认值,替换它生成的结果来构建自己的授权筛选器。一种不需要您重新实现验证逻辑的更简单的方法是,除了默认的
[ValidateAntiForgeryToken]
之外,添加一个结果过滤器,用于检查
AntiforgeryValidationFailedResult
并用其他内容替换它。这样的过滤器看起来很简单,如下所示:

公共类更改DantifOrgeryResultFilter:IAlwaysRunSultFilter
{
ResultExecuting上的公共void(ResultExecutingContext)
{
if(context.Result为AntiforgeryValidationFailedResult)
{
context.Result=新的StatusCodeResult(500);
}
}
ResultExecuted上的公共无效(ResultExecutedContext)
{ }
}
[HttpPost]
[ValidateAntiForgeryToken]
[TypeFilter(typeof(ChangedAntiforgeryResultFilter))]
公共IActionResult ExampleAction(ExampleModel模型)
=>视图(模型);
尽管如此,我不建议更改响应代码。响应代码的定义非常精确。4xx错误表示存在客户端错误,而5xx错误表示存在服务器错误。客户端未发送正确的防伪令牌在很大程度上是客户端错误。在这种情况下返回一个值是错误的

来自
AntiforgeryValidationFailedResult
的默认响应是a,这是此处的正确结果:

400(错误请求)状态代码表示服务器无法或将不会处理请求,原因是被认为是客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性的请求路由)


谢谢你的回答。我不想更改任何代码,只想用任何4xx/5xx只返回
operationId
,但同时我不想改变应用程序中其他API控制器的任何行为。我得到的错误是
context。Result
是只读的,它只有getter。@Yoda Oops,我的坏,您需要实现OnResultExecuting方法。我纠正了我的错误code@Yoda我猜我错了,您无法覆盖从授权筛选器返回的结果:/。很抱歉。不幸的是,
ValidateAntiforgeryTokenAuthorizationFilter
是内部的,因此您不能仅仅从中继承,而是需要自己滚动:/哦,对了,我忘了这个。让我自己试试,看看这里发生了什么。
    [ValidateAntiForgeryToken]
    [ChangedAntiforgeryResultFilter]