zoukankan      html  css  js  c++  java
  • ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击 (转载)

    什么是反伪造攻击?


    跨站点请求伪造(也称为XSRF或CSRF,发音为see-surf)是对Web托管应用程序的攻击,因为恶意网站可能会影响客户端浏览器和浏览器信任网站之间的交互。这种攻击是完全有可能的,因为Web浏览器会自动在每一个请求中发送某些身份验证令牌到请求网站。这种攻击形式也被称为 一键式攻击 或 会话控制 ,因为攻击利用了用户以前认证的会话。

    CSRF攻击的示例:

    (1)用户登录 www.example.com,使用表单身份验证。

    (2)服务器对用户进行身份验证,并作出包含身份验证Cookie的响应。

    (3)用户访问恶意网站。

    恶意网站包含类似于以下内容的HTML表单:

            <h1>You Are a Winner!</h1>
            <form action="http://example.com/api/account" method="post">
                <input type="hidden" name="Transaction" value="withdraw" />
                <input type="hidden" name="Amount" value="1000000" />
                <input type="submit" value="Click Me"/>
            </form>
    请注意,表单的Action属性将请求发送到易受攻击的网站,而不是恶意网站。这是CSRF的“跨站点”部分。

    (4)用户点击提交按钮,浏览器会自动包含请求站点(在这种情况下为易受攻击的站点)的认证Cookie。

    (5)请求在拥有用户身份验证上下文的服务端运行,并且可以执行允许经过身份验证用户执行的任何操作。

    此示例需要用户单击表单按钮,恶意页面也可以通过以下方式:

    • 自动运行提交表单的脚本。
    • 通过AJAX请求发送表单提交。
    • 通过CSS隐藏的表单。

    使用SSL不能阻止CSRF攻击,恶意网站可以发送https://请求。

    针对GET请求站点的攻击,可以使用Image元素来执行(这种形式的攻击在允许图片的论坛网站上很常见)。使用GET请求更改应用程序状态更容易受到恶意攻击。

    因为浏览器将所有相关的Cookie发送到目标网站,所以可以针对使用Cookie进行身份验证的网站进行CSRF攻击。然而,CSRF攻击并不仅限于利用Cookie,例如,Basic和Digest身份验证也很脆弱。用户使用Basic或Digest身份验证登录后,浏览器将自动发送凭据,直到会话(Session)结束。

    注意:在这本文中,Session是指用户进行身份验证的客户端会话。它与服务器端会话或Session中间件无关。

    用户可以通过以下方式防范CSRF漏洞:

    • 网站使用完毕后,注销会话。
    • 定期清理浏览器的Cookie。

    然而,CSRF漏洞根本上是Web应用程序的问题,而不是依靠用户来解决。

    ASP.NET Core MVC是如何处理CSRF的?


    警告:
    ASP.NET Core使用 ASP.NET Core data protection stack 来实现防请求伪造。如果在服务器集群中必须配置 ASP.NET Core Data Protection,有关详细信息,请参阅 Configuring data protection。如果你的ASP.NET Core站点使用了负载均衡部署了多个实例,就要做ASP.NET Core Data Protection的配置,否则Html.AntiForgeryToken()用的时候会报错。

    还可以参考:Host ASP.NET Core in a web farm 以及 Share authentication cookies among ASP.NET apps

    如何管理ASP.NET Core Data Protection的过期key,可以查看:Data Protection - how to manage expired key? 

    在ASP.NET Core MVC 2.0中,FormTagHelper为HTML表单元素注入防伪造令牌。例如,Razor文件中的以下标记将自动生成防伪令牌:

            <form method="post">
                <!-- form markup -->
            </form>

    在以下情况为HTML格式元素自动生成防伪令牌:

    • form标签包含method="post"属性
      • action属性为空( action="") 或者
      • 未提供action属性(<form method="post">)。

    您可以通过以下方式禁用自动生成HTML表单元素的防伪令牌:

    • 明确禁止asp-antiforgery,例如
            <form method="post" asp-antiforgery="false">
            </form>
    • 通过使用标签帮助器! 禁用语法,从标签帮助器转化为表单元素。
            <!form method="post">
            </!form>
    • 在视图中移除FormTagHelper,您可以在Razor视图中添加以下指令移除FormTagHelper
    @removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers

    提示:
    Razor页面会自动受到XSRF/CSRF的保护。您不必编写任何其他代码,有关详细信息,请参阅XSRF/CSRF和Razor页面

    防御CSRF攻击的最常见方法是令牌同步模式(STP)。STP是当用户请求表单数据页面时使用的技术。服务器将与当前用户的标识相关联的令牌发送给客户端。客户端将令牌发回服务器进行验证。如果服务器接收到与验证用户身份不匹配的令牌,则该请求将被拒绝。令牌是唯一的,并且是不可预测的。令牌也可用于确保一系列请求的正确顺序(确保页面1在第2页之前,页面2在第3页之前)。ASP.NET Core MVC模板中的所有表单都会生成防伪令牌,以下两个示例演示在视图逻辑中生成防伪令牌:

            <form asp-controller="Manage" asp-action="ChangePassword" method="post">
    
            </form>
    
            @using (Html.BeginForm("ChangePassword", "Manage"))
            {
        
            }

    您可以在不使用HTML标签助手的情况下,向<form>元素显式添加防伪令牌@Html.AntiForgeryToken

            <form action="/" method="post">
                @Html.AntiForgeryToken()
            </form>

    在前面的例子中,ASP.NET Core将添加一个隐藏的表单字段,类似于以下内容:

            <input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkSldwD9CpLRyOtm6FiJB1Jr_F3FQJQDvhlHoLNJJrLA6zaMUmhjMsisu2D2tFkAiYgyWQawJk9vNm36sYP1esHOtamBEPvSk1_x--Sg8Ey2a-d9CV2zHVWIN9MVhvKHOSyKqdZFlYDVd69XYx-rOWPw3ilHGLN6K0Km-1p83jZzF0E4WU5OGg5ns2-m9Yw" />

    为项目添加防伪技术


    Microsoft.AspNetCore.Antiforgery软件包已作为Microsoft.AspNetCore.Mvc的依赖项包含在内。 同样,通过在Startup.ConfigureServices(IServiceCollection services)方法中调用services.AddMvc(),所需的Antiforgery服务会自动在DI容器中注册。
    仍然有些情况需要手动将Antiforgery添加到项目中:  

    1. 需要覆盖默认Antiforgery选项,则需要手动调用services.AddAntiforgery(opts => {opts setup}),以便可以提供特定的选项设置。 这些选项包括诸如cookie标记的cookie名称以及请求标记的表单字段或标题名称等内容。
    2. 在不使用MVC框架的情况下从头开始编写ASP.Net Core应用程序,则需要手动包含Antiforgery包并注册服务。

    请记住,这只是在项目中注册Antiforgery并设置选项。 它不会自动启用任何类型的请求验证! 需要按照以下部分手动执行操作

    在ASP.NET Core 中间件(Middleware)管道中验证Antiforgery


    即使Antiforgery已添加到项目中,令牌也不会自动生成,也不会根据任何请求进行验证,除非启用它们。

    当你需要判断当前Http请求是否通过Antiforgery验证时,可以通过依赖注入手动添加IAntiforgery实例到中间件,然后调用ValidateRequestAsync(httpContext),捕获任何AntiforgeryValidationException并在此情况下返回400,表示Antiforgery验证失败。如下AntiforgeryValidationMiddleware中间件所示:

    public class AntiforgeryValidationMiddleware
    {
        private readonly RequestDelegate next;
        private readonly IAntiforgery antiforgery;
    
        public AntiforgeryValidationMiddleware(RequestDelegate next, IAntiforgery antiforgery)
        {
            this.next = next;
            this.antiforgery = antiforgery;
        }
    
        public async Task Invoke(Microsoft.AspNetCore.Http.HttpContext context)
        {
            try
            {
                await antiforgery.ValidateRequestAsync(context);
                await next.Invoke(context);
            }
            catch (AntiforgeryValidationException exception)
            {
                context.Response.StatusCode = 400;
            }
        }
    }

    关键步骤,添加Cookie令牌

    ASP.NET Core中Antiforgery进行跨站请求伪造验证的关键是Antiforgery的Cookie令牌,Cookie令牌是Antiforgery进行验证的依据,ASP.NET Core会验证Http请求中Cookie令牌值(是指解密后的值,默认Cookie令牌值是加密后存储在Cookie中的)是否和隐藏表单字段值、请求头值(也是指解密后的值)相等,如果相等那么Antiforgery验证通过,如果不相等那么验证就失败,所以验证的基准是到达ASP.NET Core的Http请求中要包含Cookie令牌。

    在ASP.NET Core MVC视图中使用@Html.AntiForgeryToken添加防伪令牌,默认就会在Http响应中生成一个Cookie令牌,如下所示:

    Antiforgery会将请求和Cookie标记作为标记集处理。 当执行IAntiforgery方法GetAndStoreTokens(httpContext)(这是在调用Html.AntiForgeryToken()生成表单隐藏字段时幕后发生的事情)时,它返回包含请求和cookie标记的标记集。 不仅如此,它还将确保:

    • Cookie标记作为仅HttpOnly添加到当前的HttpContext响应中。
    • 如果已经为此请求生成了令牌集(即,已经使用相同的httpContext调用了GetAndStoreTokens),它将返回相同的令牌集,而不是再次重新生成它。 这一点很重要,因为它允许页面的多个元素得到发布并通过验证,就像有多个表单一样(因为对于所有表单,cookie都是相同的,如果每个表单都有不同的标记,那么只有带有 与cookie匹配的令牌可以通过验证!)。

    既然Cookie令牌这么重要,所以我们可以创建一个ASP.NET Core中间件AntiforgeryCookieMiddleware,来为所有Http请求的响应(Response)自动生成Cookie令牌:

    using Microsoft.AspNetCore.Antiforgery;
    using Microsoft.AspNetCore.Http;
    using System.Threading.Tasks;
    
    namespace Assembly.Middlewares
    {
        public class AntiforgeryCookieMiddleware
        {
            private readonly RequestDelegate next;
            private readonly IAntiforgery antiforgery;
    
            public AntiforgeryCookieMiddleware(RequestDelegate next, IAntiforgery antiforgery)
            {
                this.next = next;
                this.antiforgery = antiforgery;
            }
    
            public async Task Invoke(Microsoft.AspNetCore.Http.HttpContext context)
            {
                var antiforgeryTokenSet = antiforgery.GetAndStoreTokens(context);//调用IAntiforgery的GetAndStoreTokens(httpContext)方法,为所有Http请求的响应添加Cookie令牌
                string requestToken = antiforgeryTokenSet.RequestToken;//IAntiforgery的GetAndStoreTokens(httpContext)方法返回的AntiforgeryTokenSet对象,通过调用其RequestToken属性可以获得请求令牌的值,该值就是隐藏表单字段值、请求头值
                string cookieToken = antiforgeryTokenSet.CookieToken;//IAntiforgery的GetAndStoreTokens(httpContext)方法返回的AntiforgeryTokenSet对象,通过调用其CookieToken属性也可以获得Cookie令牌的值
    
                await next.Invoke(context);
            }
        }
    }

    另外我们定义一个AntiforgeryCookieMiddleware中间件的扩展类AntiforgeryCookieMiddlewareExtension,用来在ASP.NET Core中间件管道上启用AntiforgeryCookieMiddleware中间件:

    using Microsoft.AspNetCore.Builder;
    
    namespace Assembly.Middlewares
    {
        public static class AntiforgeryCookieMiddlewareExtension
        {
            public static void UseAntiforgeryCookie(this IApplicationBuilder app)
            {
                app.UseMiddleware<AntiforgeryCookieMiddleware>();
            }
        }
    }

    然后我们在ASP.NET Core项目中Startup类的Configure方法中,调用app.UseAntiforgeryCookie()方法来启用AntiforgeryCookieMiddleware中间件即可,注意还要在Startup类的ConfigureServices方法中使用services.AddAntiforgery()来注册IAntiforgery的依赖注入

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAntiforgery();//在中间件中使用IAntiforgery,记得要在ConfigureServices方法中使用services.AddAntiforgery来注册IAntiforgery的依赖注入
        services.AddMvc();
    }
    
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseAntiforgeryCookie();//启用AntiforgeryCookieMiddleware
    
        if (env.IsDevelopment())
        {
            //app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    在ASP.NET Core MVC中验证Antiforgery


    ASP.NET Core MVC包括三个过滤器用于防伪令牌的运行:ValidateAntiForgeryTokenAutoValidateAntiforgeryTokenIgnoreAntiforgeryToken

    ValidateAntiForgeryToken


    ValidateAntiForgeryToken是一个可应用于单个Action、控制器或全局的操作过滤器。请求必须包含一个有效的令牌,否则对具有该过滤器Action的请求将被阻止。

            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
            {
                ManageMessageId? message = ManageMessageId.Error;
                var user = await GetCurrentUserAsync();
                if (user != null)
                {
                    var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
                    if (result.Succeeded)
                    {
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        message = ManageMessageId.RemoveLoginSuccess;
                    }
                }
                return RedirectToAction(nameof(ManageLogins), new { Message = message });
            }

    ValidateAntiForgeryToken特性标记的Action方法需要一个令牌,包括HTTP GET请求。如果您全局使用,您可以使用IgnoreAntiforgeryToken特性来覆盖它。

    AutoValidateAntiforgeryToken


    ASP.NET Core应用程序通常不会为HTTP安全方式(GET,HEAD,OPTIONS和TRACE)生成防伪令牌,而不是在全局范围内使用ValidateAntiForgeryToken特性,然后用IgnoreAntiforgeryToken特性覆盖它,您可以使用AutoValidateAntiforgeryToken特性。该特性与ValidateAntiForgeryToken特性相似,但对以下HTTP请求方式不需要请求令牌:

    • GET
    • HEAD
    • OPTIONS
    • TRACE

    我们建议您在非API场景中广泛使用AutoValidateAntiforgeryToken。这确保您的POST Action 默认受保护。另一种方式是在默认情况下忽略反伪造令牌,除非在个别Action方法标记了ValidateAntiForgeryToken特性,不过在这种情况下,POST Action方法有可能不受保护,使您的应用程序容易受到CSRF攻击。即使匿名的POST请求也应该发送防伪令牌。

    注意:API没有自动机制来发送非Cookie的令牌;您的实现可能取决于您的客户端代码的实现。


    一些例子如下所示。


    示例(控制器级别):

            [Authorize]
            [AutoValidateAntiforgeryToken]
            public class ManageController : Controller
            {

    示例(全局)

                services.AddMvc(options => 
                    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));

    IgnoreAntiforgeryToken


    IgnoreAntiforgeryToken过滤器用于取消已经使用防伪标记的Action(或控制器)的需求。应用时,此过滤器将覆盖在更高级别(全局或控制器)上指定的过滤器ValidateAntiForgeryToken和/或AutoValidateAntiforgeryToken过滤器。

            [Authorize]
            [AutoValidateAntiforgeryToken]
            public class ManageController : Controller
            {
                [HttpPost]
                [IgnoreAntiforgeryToken]
                public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
                {
                    // no antiforgery token required
                }
            }

    JavaScript,AJAX和SPA(单页应用程序)


    在传统基于HTML的应用程序中,使用隐藏的表单字段将防伪令牌发送到服务器。在当前基于JavaScript的应用程序和单页应用程序(SPA)中,许多请求以编程方式进行。这些AJAX请求可能会使用其它技术(如请求头或Cookie)来发送令牌。如果使用Cookie来存储身份验证令牌,并在服务器上验证API请求,那么CSRF将是一个潜在的问题,但是,如果使用本地存储来存储令牌,那么CSRF漏洞可能会被减轻,因为本地存储的值不会在每个请求时自动发送到服务器。因此,使用本地存储将反伪造令牌存储在客户机上,并将令牌作为请求头发送,这是一种推荐的方式。

    AngularJS


    AngularJS通过约定来解决CSRF。如果服务器发送带有名称为XSRF-TOKEN的Cookie ,则Angular的$http服务将向该服务器发送的请求将该Cookie的值添加到请求头。这个过程是自动的,您不需要明确设置请求头。请求头的名称是X-XSRF-TOKEN,服务器会检测该请求头并验证其内容。

    对于ASP.NET Core API,使用此约定:

    • 配置您的应用程序,在一个Cookie中提供一个称为XSRF-TOKEN的令牌;
    • 配置防伪服务查找名为X-XSRF-TOKEN的请求头。
                services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

    查看示例

    JavaScript


    在视图中使用JavaScript,您可以在视图中使用服务创建令牌,您将Microsoft.AspNetCore.Antiforgery.IAntiforgery服务注入视图并调用GetAndStoreTokens,如下所示:

    @{
        ViewData["Title"] = "AJAX Demo";
    }
    @inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
    @functions{
        public string GetAntiXsrfRequestToken()
        {
            return Xsrf.GetAndStoreTokens(Context).RequestToken;
        }
    }
    <h2>@ViewData["Title"].</h2>
    <h3>@ViewData["Message"]</h3>
    
    <div class="row">
        <input type="button" id="antiforgery" value="Antiforgery" />
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script>
        <script>
                    $("#antiforgery").click(function () {
                        $.ajax({
                            type: "post",
                            dataType: "html",
                            headers:
                            {
                                "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
                            },
                            url: '@Url.Action("Antiforgery", "Home")',
                            success: function (result) {
                                alert(result);
                            },
                            error: function (err, scnd) {
                                alert(err.statusText);
                            }
                        });
                    });
        </script>
    </div>

    这种方法无需在服务器设置Cookie或从客户端读取Cookie。


    JavaScript还可以访问Cookie中提供的令牌,然后使用Cookie的内容创建带有令牌值的请求头,如下所示。

                context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, 
                    new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });

    然后,假设您构建的脚本发送的请求,将令牌发送为一个名为X-CSRF-TOKEN的请求头中,请配置防伪服务以查找X-CSRF-TOKEN请求头:

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

    以下示例使用jQuery来创建一个包含相应请求头AJAX请求:

    var csrfToken = $.cookie("CSRF-TOKEN");
    
    $.ajax({
        url: "/api/password/changepassword",
        contentType: "application/json",
        data: JSON.stringify({ "newPassword": "ReallySecurePassword999$$$" }),
        type: "POST",
        headers: {
            "X-CSRF-TOKEN": csrfToken
        }
    });

    配置防伪



    IAntiforgery提供API来配置防伪系统。它可以在Startup类的Configure方法中使用。以下示例在应用程序的主页生成防伪令牌,并将其作为Cookie发送到响应中(使用上述默认命名约定):

            public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
            {
                app.Use(next => context =>
                {
                    string path = context.Request.Path.Value;
                    if ( string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) || string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
                    {
                        // We can send the request token as a JavaScript-readable cookie, 
                        // and Angular will use it by default.
                        var tokens = antiforgery.GetAndStoreTokens(context);
                        context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,  new CookieOptions() { HttpOnly = false });
                    }
    
                    return next(context);
                });
                
            }

    选项


    您可以在ConfigureServices方法中定制防伪选项

    ASP.NET Core 1.X

    services.AddAntiforgery(options =>
    {
        options.CookieDomain = "mydomain.com";
        options.CookieName = "X-CSRF-TOKEN-COOKIENAME";
        options.CookiePath = "Path";
        options.RequireSsl = false;
        options.FormFieldName = "AntiforgeryFieldname";
        options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
        options.SuppressXFrameOptionsHeader = false;
    });

    ASP.NET Core 2.X,与Cookie相关的配置项都移到了options.Cookie属性中,可以和上面ASP.NET Core 1.X对照理解

    services.AddAntiforgery(options =>
    {
        options.Cookie.Domain = "mydomain.com";
        options.Cookie.Name = "X-CSRF-TOKEN-COOKIENAME";
        options.Cookie.Path = "Path";
        options.Cookie.SecurePolicy = CookieSecurePolicy.None;
        options.FormFieldName = "AntiforgeryFieldname";
        options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
        options.SuppressXFrameOptionsHeader = false;
    });
    选项描述
    CookieDomain Cookie的域名。默认为null
    CookieName Cookie的名称。如果未设置,系统将生成一个以DefaultCookiePrefix(".AspNetCore.Antiforgery")开头的唯一名称。
    CookiePath Cookie设置的路径。
    FormFieldName 在视图中隐藏表单字段的名称。
    HeaderName 防伪系统使用的请求头的名称。如果null,系统将仅使用表单数据。
    RequireSsl 指定防伪系统是否需要SSL。默认为false。如果为true,非SSL请求会失败。
    SuppressXFrameOptionsHeader 指定是否禁止X-Frame-Options响应头的生成。默认情况下,响应头生成的值为“SAMEORIGIN”。默认为false

    有关详细信息,请参阅 https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.antiforgery.antiforgeryoptions

    扩展防伪


    IAntiForgeryAdditionalDataProvider类型允许开发者扩展anti-XSRF系统的行为,在每个令牌中的增加额外数据。每次创建令牌时会调用GetAdditionalData方法,并且返回的值被嵌入生成的令牌内。实现者可以返回时间戳、随机数或任何其它值,然后在验证令牌时调用ValidateAdditionalData来验证此数据。客户的用户名已经嵌入到生成的令牌中,因此不需要包含此信息。如果令牌包含补充数据但没有配置IAntiForgeryAdditionalDataProvider,则补充数据不被验证。

    常用场景


    CSRF攻击依赖于浏览器默认行为,向站点发出请求同时,会发送与站点相关联的Cookie。这些Cookies存储在浏览器中,它们经常用于经过身份验证的用户提供会话Cookie。基于Cookie的身份验证是一种非常流行的身份验证模式。基于令牌的认证系统越来越受欢迎,特别是对于SPA和其它“智能客户端”场景。

    基于Cookie的身份验证


    一旦用户使用他们的用户名和密码进行身份验证,就会发出一个令牌,用于标识它们并验证它们是否经过身份验证。令牌存储为Cookie,客户端所做的每个请求都会附带令牌。生成和验证此Cookie是由Cookie身份验证中间件完成的。ASP.NET Core提供了将用户主体序列化为加密Cookie的Cookie 中间件,然后在随后的请求中验证Cookie,重新创建主体并将其分配给HttpContextUser属性。


    当使用Cookie时,身份验证Cookie只是表单身份验证凭证的一个容器。在每个请求中,票据作为的表单认证Cookie的值传递并通过表单身份验证,在服务端,以标识经过身份验证的用户。


    当用户登录到系统时,会在服务器端创建用户会话,并将其存储在数据库或其他持久存储中,系统生成指向数据存储中的会话密钥,并将其作为客户端Cookie发送。每当用户请求需要授权的资源时,Web服务器将检查此会话密钥,系统检查关联的用户会话是否具有访问请求的资源的权限。如果是,请求继续;否则,请求返回为未授权。在这种方法下,Cookie的使用,使应用程序看起来是有状态的,因为它能够“记住”用户以前已经在服务端完成了身份验证。

    用户令牌


    基于令牌的身份验证不会在服务器上存储会话。相反,当用户登录时,将颁发令牌(不是防伪令牌)。该令牌保存验证令牌所需的所有数据,它还包含用户信息,以claims的形式。当用户想要访问需要身份验证的服务器资源时,会使用 Bearer {token} 形式的附加授权头发送令牌给服务器。这使得应用程序无状态,因为在每个后续请求中,令牌在请求中传递给服务器端验证。该令牌未 加密 , 而是 编码 。在服务器端,令牌可以被解码以访问令牌内的原始信息。要在随后的请求中发送令牌,您可以将其存储在浏览器的本地存储或Cookie中。如果您的令牌存储在本地存储中,则不必担心XSRF漏洞,但如果令牌存储在Cookie中,则会出现问题。

    多个应用程序托管在一个域中



    即使example1.cloudapp.netexample2.cloudapp.net是不同的主机,在.cloudapp.net域内的所有主机之间存在一种隐式信任关系。这种隐式信任关系允许潜在的不受信任的主机影响彼此的Cookie(管理AJAX请求的同源策略不一定适用于HTTP Cookie)。ASP.NET Core运行时提供了一些缓解,用户名被嵌入到字段令牌中,因此即使恶意子域能够覆盖会话令牌,它将无法为用户生成有效的字段令牌。然而,当托管在这样的环境中,内置的反XSRF例程仍然无法防止会话劫持或登录CSRF攻击。共享主机环境对会话劫持、登录CSRF和其它攻击都是不可控制的。

    其他资源


    XSRF on Open Web Application Security Project (OWASP)。

    原文:《Preventing Cross-Site Request Forgery (XSRF/CSRF) Attacks in ASP.NET Core》https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery

    在ASP.NET Core Web程序中使用Antiforgery防御CSRF

    Anti forgery with token API and angular

    原文链接

  • 相关阅读:
    CodeForces
    Codeforces 1523D Love-Hate(随机化算法,sos dp)
    CodeForces
    讲题泛做
    CF vp 新题乱做
    10.11 牛客
    10.6 牛客
    10.4 牛客
    10.9 模拟考试 题解报告
    9.18 校内模拟赛 题解报告
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10342963.html
Copyright © 2011-2022 走看看