加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – .net核心MVC:X-SRF-TOKEN不被接受,400返回

发布时间:2020-12-17 07:16:31 所属栏目:安全 来源:网络整理
导读:我有一个使用angularJS的.net核心应用程序,我想保护受基于cookie的身份验证保护的api调用.我按照本文中的步骤操作: https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery 我添加了services.AddAntiforgery(options = options.Heade
我有一个使用angularJS的.net核心应用程序,我想保护受基于cookie的身份验证保护的api调用.我按照本文中的步骤操作:

https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery

>我添加了services.AddAntiforgery(options => options.HeaderName =“X-XSRF-TOKEN”);到我的服务配置
>我在加载页面时在开发人员工具中看到了XSRF-TOKEN cookie.
>我看到X-XSRF-TOKEN标头被添加到我的$http发送请求中.
>我已将[AutoValidateAntiforgeryToken]添加到处理ajax请求的控制器.
>我已启用ssl,并通过https访问这些页面.

我可以按预期通过此api端点使GET请求正常.但是,我收到400错误,没有任何有关PUT和POST请求错误的详细信息.

我知道X-XSRF-TOKEN是请求的(在chrome dev工具的网络选项卡中看到)所以我不确定我缺少什么来允许正确接收这些请求.

TL; DR:为什么.net核心拒绝我的有效AntiforgeryToken?

更新尝试@ joey建议的解决方案,但它没有工作,仍然收到400个响应.下面的代码反映了我试图解决这个问题的另一个解决方案(aka angularjs的解决方案,为跨站点脚本保护设置默认cookie和标头)

我还尝试配置AngularJS以更改cookie和标题名称与我在Startup.cs中配置的名称相匹配的内容.我更改了他们的名字以尝试XSRF-TOKEN(cookie)和X-XSRF-TOKEN(标题)以及CSRF-TOKEN和X-CSRF-TOKEN,而angular内的配置正确地使用了新的默认值我提供,我在.net核心中的身份验证代码仍然无效.

有关更多信息,请参阅我如何配置AngularJS:

app.config(function ($httpProvider) {
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRF-TOKEN';
    $httpProvider.defaults.xsrfCookieName = 'CSRF-TOKEN';
});

这是我在Startup.cs文件中的ConfigureServices行:

services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");

最后这是我添加到Startup.cs文件的Configure方法的代码:

app.Use(next => context => 
    {
        string path = context.Request.Path.Value;
        if (path.Contains("/MyProtectedPath/"))
        {
            var tokens = antiforgery.GetAndStoreTokens(context);
            context.Response.Cookies.Append("CSRF-TOKEN",tokens.RequestToken,new CookieOptions { HttpOnly = false });
        }
        return next(context);
    });

更新2:
我已将以下内容添加到控制器操作中:

if (HttpContext.Request.Method.ToLower(CultureInfo.InvariantCulture) != "get")
{
    await _antiforgery.ValidateRequestAsync(HttpContext);
}

AntiforgeryValidationException:提供的防伪令牌适用于与当前用户不同的基于声明的用户.

我想也许是antiforgery.GetAndStoreTokens(上下文)可能会覆盖页面加载时发送的当前cookie,所以我只让它在GET请求上点击该代码,但我得到的帖子结果相同.

更新3
感谢@joey的帮助,我查看了我的startup.cs文件,并在单独的分支中使用了UseAuthentication:

app.Use(next => context => //note: order of these use statements is key. keep this antiforgery section above auth!
    {
        string path = context.Request.Path.Value;
        if (path.ToLower(CultureInfo.InvariantCulture).Contains("/campaigns/proxy/"))
        {
            var tokens = antiforgery.GetAndStoreTokens(context);
            context.Response.Cookies.Append("XSRF-TOKEN",new CookieOptions { HttpOnly = false });
        }
        return next(context);
    });

    // Use Basic Auth for /api
    app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")),branch =>
    {
        branch.UseBasicAuth();
    });
    // Use Identity for everything except /api
    app.UseWhen(context => !context.Request.Path.StartsWithSegments(new PathString("/api")),branch =>
    {

        app.UseAuthentication(); // required for .net core 2.0 authentication
    });

我不确定为什么我的令牌在这一点上会被视为无效……

解决方法

在您发布的代码中,您要添加标题X-XSRF-TOKEN,但标题应为X-CSRF-TOKEN.

您链接的网页中的示例提供了示例:

services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");

更新:

感谢您使用附加代码和&信息.这里选择的实现CSRF的方法是将标记作为初始HTML文件响应的标题传递的方法.以下是如何为SPA Web应用程序配置此类案例的示例:

app.Use(next => context =>
{
    string path = context.Request.Path.Value;
    if (
        string.Equals(path,"/",StringComparison.OrdinalIgnoreCase) || 
        string.Equals(path,"/index.html",StringComparison.OrdinalIgnoreCase)
    )
    {
        var tokens = antiforgery.GetAndStoreTokens(context);
        context.Response.Cookies.Append("CSRF-TOKEN",new CookieOptions() { HttpOnly = false });
    }

    return next(context);
});

但是,将服务配置为使用String.Contains方法[1],将为包含/ MyProtectedPath / anywhere的任何路径调用antiforgery.GetAndStoreTokens(context).这意味着它的配置方式不仅与/ MyProtectedPath /匹配,还与/ MyProtectectedPath / a / b / c或/ a / b / c / MyProtectedPath /匹配.

检查在适用的HTTP方法的后续请求中发送的CSRF令牌,如下所示:

if (string.Equals("POST",context.Request.Method,StringComparison.OrdinalIgnoreCase))
{
    await antiforgery.ValidateRequestAsync(context);
    // The line above will throw if the CSRF token is invalid.
}

如果在此之前为任何匹配路径调用GetAndStoreTokens方法,则在检查之前将覆盖该令牌,这就是为什么.net示例通常首先命令GetAndStoreTokens,但具有查看路径和HTTP方法的特定条件.

[1] https://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.110).aspx

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读