ASP.NET Core中Cookie验证身份用法详解

目录
  • 添加配置
    • ASP.NETCore1.x
    • ASP.NETCore2.x
  • 创建身份认证Cookie
    • ASP.NETCore1.x
    • ASP.NETCore2.x
  • Signingout(登出)
    • ASP.NETCore1.x
    • ASP.NETCore2.x
  • 服务端变化反馈
    • ASP.NETCore1.x
    • ASP.NETCore2.x
  • Cookie设置选项
    • ASP.NETCore1.x
    • ASP.NETCore2.x
  • 持久Cookie
    • ASP.NETCore1.x
    • ASP.NETCore2.x
  • 绝对到期时间
    • ASP.NETCore1.x
    • ASP.NETCore2.x

ASP.NET Core 1.x提供了通过Cookie 中间件将用户主体序列化为一个加密的Cookie,然后在后续请求中验证Cookie并重新创建主体,并将其分配给HttpContext.User属性。如果您要提供自己的登录界面和用户数据库,可以使用作为独立功能的Cookie中间件。

ASP.NET Core 2.x的一个主要变化是不再存在Cookie中间件。取而代之的是在Startup.cs文件中的Configure方法中的调用UseAuthentication方法会添加设置HttpContext.User属性的 AuthenticationMiddleware 中间件。

添加配置

ASP.NET Core 1.x

按下列步骤操作:

  • 在您的项目中安装Microsoft.AspNetCore.Authentication.CookiesNuGet包。此包包含Cookie中间件。
  • 在Startup.cs文件中的Configure方法中添加下面的行,在app.UseMvc()语句之前:
        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AccessDeniedPath = "/Account/Forbidden/",
            AuthenticationScheme = "MyCookieAuthenticationScheme",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            LoginPath = "/Account/Unauthorized/"
        });

ASP.NET Core 2.x

按下列步骤操作:

  • 如果不使用Microsoft.AspNetCore.All 元包,则在您的项目中安装2.0版的Microsoft.AspNetCore.Authentication.CookiesNuGet包。
  • 在Startup.cs文件中的Configure方法中调用UseAuthentication方法:
        app.UseAuthentication();
  • 在Startup.cs文件中的ConfigureServices方法中调用AddAuthenticationAddCookie方法:
        services.AddAuthentication("MyCookieAuthenticationScheme")
                .AddCookie("MyCookieAuthenticationScheme", options => {
                    options.AccessDeniedPath = "/Account/Forbidden/";
                    options.LoginPath = "/Account/Unauthorized/";
                });

上面的代码片段配置了以下部分或全部选项:

  • AccessDeniedPath - 当用户尝试访问资源但没有通过任何授权策略时,这是请求会重定向的相对路径资源。
  • AuthenticationScheme - 这是一个已知的特定Cookie认证方案的值。当有多个Cookie验证实例,并且您想限制对一个实例的授权时,这就非常有用。
  • AutomaticAuthenticate - 此标识仅适用于ASP.NET Core 1.x。它表示Cookie身份验证应在每个请求上运行,并尝试验证和重建序列化主体。
  • AutomaticChallenge - 此标识仅适用于ASP.NET Core 1.x。这表示当授权失败时,1.x Cookie认证应将浏览器重定向到LoginPathAccessDeniedPath
  • LoginPath - 当用户尝试访问资源但尚未认证时,这是请求重定向的相对路径。

其它选项包括为Cookie认证创建的设置选项,身份验证的Cookie的名称,Cookie的域和Cookie各种安全属性。默认情况下,Cookie身份验证为其创建的任何Cookie使用适当的安全选项,例如:

  • 设置HttpOnly标志以防止客户端JavaScript中访问Cookie
  • 如果请求是通过HTTPS访问,则将Cookie限制为HTTPS

创建身份认证Cookie

要创建一个保存用户信息的cookie,您必须构建一个ClaimsPrincipal 保存您希望序列化到Cookie中的信息。

ASP.NET Core 1.x

    await HttpContext.Authentication.SignInAsync("MyCookieAuthenticationScheme", principal);

ASP.NET Core 2.x

    await HttpContext.SignInAsync("MyCookieAuthenticationScheme", principal);

这将创建一个加密的Cookie并将其添加到当前响应中。在调用SignInAsync时,必须在配置中指定的AuthenticationScheme

顺便提一下,使用的加密方式是ASP.NET Core的Data Protection系统。如果您在多台机器上进行托管、负载平衡或使用Web集群,则需要配置Data Protection才能使用相同的密钥和应用程序标识符。

Signing out(登出)

要退出当前用户并删除其Cookie,请在控制器中调用以下方法:

ASP.NET Core 1.x

    await HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme");

ASP.NET Core 2.x

    await HttpContext.SignOutAsync("MyCookieAuthenticationScheme");

服务端变化反馈

警告: 一旦创建了认证的Cookie,它将成为唯一的身份来源。即使您在服务系统中禁用用户,Cookie身份验证也无法了解此信息,只要Cookie有效,用户仍可登录。

Cookie认证在其选项中提供了一系列事件。ValidateAsync()事件可用于拦截和重写Cookie身份验证。

可以考虑在后端用户数据库中增加LastChanged列。为了在数据库更改时使Cookie无效,您应该首先在创建Cookie时添加一个LastChanged包含当前值的声明。数据库更改时,更新LastChanged例的值。

要重写ValidateAsync()事件的实现,您必须编写一个具有以下签名的方法:

    Task ValidateAsync(CookieValidatePrincipalContext context);

ASP.NET Core Identity 在SecurityStampValidator实现了这一逻辑,链接地址。示例如下所示:

ASP.NET Core 1.x

    public static class LastChangedValidator
    {
        public static async Task ValidateAsync(CookieValidatePrincipalContext context)
        {
            // Pull database from registered DI services.
            var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
            var userPrincipal = context.Principal;

            // Look for the last changed claim.
            string lastChanged;
            lastChanged = (from c in userPrincipal.Claims
                            where c.Type == "LastUpdated"
                            select c.Value).FirstOrDefault();

            if (string.IsNullOrEmpty(lastChanged) ||
                !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
            {
                context.RejectPrincipal();
                await context.HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme");
            }
        }
    }

然后,在Startup.cs文件中的Configure方法中将Cokie认证配置进行重写:

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        Events = new CookieAuthenticationEvents
        {
            OnValidatePrincipal = LastChangedValidator.ValidateAsync
        }
    });

ASP.NET Core 2.x

    public static class LastChangedValidator
    {
        public static async Task ValidateAsync(CookieValidatePrincipalContext context)
        {
            // Pull database from registered DI services.
            var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
            var userPrincipal = context.Principal;

            // Look for the last changed claim.
            string lastChanged;
            lastChanged = (from c in userPrincipal.Claims
                            where c.Type == "LastUpdated"
                            select c.Value).FirstOrDefault();

            if (string.IsNullOrEmpty(lastChanged) ||
                !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
            {
                context.RejectPrincipal();
                await context.HttpContext.SignOutAsync("MyCookieAuthenticationScheme");
            }
        }
    }

然后,将在Startup.cs的ConfigureServices方法中将Cookie服务注册进行配置:

    services.AddAuthentication("MyCookieAuthenticationScheme")
            .AddCookie(options =>
            {
                options.Events = new CookieAuthenticationEvents
                {
                    OnValidatePrincipal = LastChangedValidator.ValidateAsync
                };
            });

如果要非破坏性地更新用户主体,可以调用context.ReplacePrincipal(),并将context.ShouldRenew属性设置为true

Cookie设置选项

CookieAuthenticationOptions类提供了各种配置选项,在创建时调整Cookie的配置。

ASP.NET Core 1.x

  • ClaimsIssuer是由中间件创建的任何声明时使用的Issuer属性。
  • CookieDomain是提供Cookie的域名。默认情况下,这是发送请求的主机名。浏览器仅将Cookie提供给匹配的主机名。您可能希望对此进行调整,以便您的域中的任何主机都可以使用Cookie。例如,将Cookie域名设置为.contoso.com,可以使用Cookie的域名有contoso.comwww.contoso.comstaging.www.contoso.com等。
  • CookieHttpOnly是一个标识,指定Cookie是否只能由服务器访问。默认为true。如果您的应用程序具有Cross-Site Scripting(XSS)的问题,更改此值可能会导致Cookie被盗用。
  • CookiePath可用于隔离在相同主机名上运行的应用程序。如果你有一个应用程序在/app1中运行,并希望限制发送的Cookie只发送到该应用程序,那么您应该将CookiePath属性设置为/app1。通过这样做,Cookie只适用于对/app1或其下任何内容的请求。
  • CookieSecure是一个标识,表示创建的Cookie是否应该被限制为HTTPS,HTTP或HTTPS,或与请求相同的协议。默认为SameAsRequest
  • ExpireTimeSpanTimeSpan类型,在此时间段之后Cookie将过期。将当前日期加上此时间段为创建Cookie的到期日期。
  • SlidingExpiration是一个标识,指示当超过一半的ExpireTimeSpan间隔时,Cookie到期日期是否复位。新的到期日是当前时间加上ExpireTimespan。调用SignInAsync时,可以使用AuthenticationProperties类设置绝对到期时间。绝对到期时间可以通过限制认证Cookie有效的时间来提高应用程序的安全性。

在Startup.cs文件中的Configure方法中使用CookieAuthenticationOptions的例子如下:

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        CookieName = "AuthCookie",
        CookieDomain = "contoso.com",
        CookiePath = "/",
        CookieHttpOnly = true,
        CookieSecure = CookieSecurePolicy.Always
    });

ASP.NET Core 2.x

ASP.NET Core 2.x 统一了用于配置Cookie的API。1.x API已被标记为过时,并且在CookieAuthenticationOptions类中引入了一种类型为CookieBuilder新的Cookie属性。建议您迁移到2.x API。

  • ClaimsIssuer是由Cookie认证创建的任何声明时使用的Issuer属性。
  • CookieBuilder.Domain是提供Cookie的域名。默认情况下,这是发送请求的主机名。浏览器仅将Cookie提供给匹配的主机名。您可能希望对此进行调整,以便您的域中的任何主机都可以使用Cookie。例如,将Cookie域名设置为.contoso.com,可以使用Cookie的域名有contoso.comwww.contoso.comstaging.www.contoso.com
  • CookieBuilder.HttpOnly是一个标识,指定Cookie是否只能由服务器访问。默认为true。如果您的应用程序具有Cross-Site Scripting(XSS)的问题,更改此值可能会导致Cookie被盗用。
  • CookieBuilder.Path可用于隔离在相同主机名上运行的应用程序。如果你有一个应用程序在/app1中运行,并希望限制发送的Cookie只发送到该应用程序,那么您应该将CookiePath属性设置为/app1。通过这样做,Cookie只适用于对/app1或其下任何内容的请求。
  • CookieBuilder.SameSite表示浏览器是否允许Cookie被附加到同一站点或跨站点的请求。默认为SameSiteMode.Lax
  • CookieBuilder.SecurePolicy是一个标识,表示创建的Cookie是否应该被限制为HTTPS,HTTP或HTTPS,或与请求相同的协议。默认为SameAsRequest
  • ExpireTimeSpanTimeSpan类型,在此时间段之后Cookie将过期。将当前日期加上此时间段为创建Cookie的到期日期。
  • SlidingExpiration是一个标识,指示当超过一半的ExpireTimeSpan间隔时,Cookie到期日期是否复位。新的到期日是当前时间加上ExpireTimespan。调用SignInAsync时,可以使用AuthenticationProperties类设置绝对到期时间。绝对到期时间可以通过限制认证Cookie有效的时间来提高应用程序的安全性。

在Startup.cs的ConfigureServices方法中使用CookieAuthenticationOptions的例子如下:

    services.AddAuthentication()
        .AddCookie(options =>
        {
            options.Cookie.Name = "AuthCookie";
            options.Cookie.Domain = "contoso.com";
            options.Cookie.Path = "/";
            options.Cookie.HttpOnly = true;
            options.Cookie.SameSite = SameSiteMode.Lax;
            options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
        });

持久Cookie

您可能希望Cookie在浏览器会话中持续存在,并希望设置身份和Cookie传输的绝对过期时间。这种持久性应该只能是用户显示同意,在登录时的“记住我”复选框或类似的机制启用。您可以通过在创建身份认证Cookie时调用的SignInAsync方法中使用AuthenticationProperties参数来执行这些操作。例如:

ASP.NET Core 1.x

    await HttpContext.Authentication.SignInAsync(
        "MyCookieAuthenticationScheme",
        principal,
        new AuthenticationProperties
        {
            IsPersistent = true
        });

上述代码片段中使用的AuthenticationProperties类,位于Microsoft.AspNetCore.Http.Authentication命名空间中。

ASP.NET Core 2.x

    await HttpContext.SignInAsync(
        "MyCookieAuthenticationScheme",
        principal,
        new AuthenticationProperties
        {
            IsPersistent = true
        });

上述代码片段中使用的AuthenticationProperties类,位于Microsoft.AspNetCore.Authentication命名空间中。

上面的代码段创建一个身份和相应的Cookie,直到浏览器关闭。以前通过Cookie设置选项配置的任何滑动过期设置仍然有效。如果Cookie在浏览器关闭时过期,浏览器会在重新启动后清除它。如果Cookie在浏览器关闭时过期,浏览器会在重新启动后清除它。

绝对到期时间

ASP.NET Core 1.x

    await HttpContext.Authentication.SignInAsync(
        "MyCookieAuthenticationScheme",
        principal,
        new AuthenticationProperties
        {
            ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
        });

ASP.NET Core 2.x

    await HttpContext.SignInAsync(
        "MyCookieAuthenticationScheme",
        principal,
        new AuthenticationProperties
        {
            ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
        });

上述代码段创建一个持续20分钟的身份和相应的cookie。这将忽略以前通过Cookie设置选项配置的任何滑动过期设置。

ExpiresUtcIsPersistent属性是互斥的。

到此这篇关于ASP.NET Core中Cookie验证身份用法详解的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET Core中间件实现限流的代码

    目录 一.限流算法 1.计数器算法 1.1固定窗口算法 1.2滑动窗口算法 2.令牌桶算法 3.漏桶算法 二.ASP.NETCore中间件实现限流 1.中间件代码 2.在管道中的使用 一.限流算法 在高并发系统中,有三把利器用来保护系统:缓存.降级和限流. 本文主要是介绍限流,限流算法主要有以下三种: 1.计数器算法 固定窗口 滑动窗口 2.令牌桶算法 3.漏桶算法 1.计数器算法 1.1 固定窗口算法 计数器算法是限流算法里最简单也是最容易实现的一种算法.比如我们规定,对于A接口来说,我们1分

  • ASP.NET Core中的策略授权和ABP授权

    目录 ASP.NETCore中的策略授权 策略 定义一个Controller 设定权限 定义策略 存储用户信息 标记访问权限 认证:Token凭据 颁发登录凭据 自定义授权 IAuthorizationService ABP授权 创建ABP应用 定义权限 ASP.NET Core 中的策略授权 首先我们来创建一个 WebAPI 应用. 然后引入 Microsoft.AspNetCore.Authentication.JwtBearer 包. 策略 Startup 类的 ConfigureServ

  • Asp.NET Core 限流控制(AspNetCoreRateLimit)的实现

    起因: 近期项目中,提供了一些调用频率较高的api接口,需要保障服务器的稳定运行:需要对提供的接口进行限流控制.避免因客户端频繁的请求导致服务器的压力. 一.AspNetCoreRateLimit 介绍 AspNetCoreRateLimit 是一个ASP.NET Core速率限制的解决方案,旨在控制客户端根据IP地址或客户端ID向Web API或MVC应用发出的请求的速率.AspNetCoreRateLimit包含一个 IpRateLimitMiddleware 和 ClientRateLim

  • Redis数据库基础与ASP.NET Core缓存实现

    目录 基础 Redis库 连接Redis 能用redis干啥 Redis数据库存储 字符串 订阅发布 RedisValue ASP.NETCore缓存与分布式缓存 内存中的缓存 ASP.NETCore的内存缓存 在内存中缓存.存储数据 IMemoryCache MemoryCache 分布式缓存 IDistributedCache Redis缓存 基础 Redis 库 C# 下 Redis-Client 开源的库很多,有 BeetleX.Redis.csredis.Nhiredis.redis-

  • ASP.NET Core读取配置文件

    ASP.NET Core 中,可以使用 ConfigurationBuilder 对象来构建. 主要分为三部:配置数据源 -> ConfigurationBuilder -> 使用. 数据源可来自字典或配置文件. 数据源要么继承 IConfigurationSource ,要么从配置文件中读取. 1,来自字典 我们先使用字典存储键值对,来设置配置, test = 配置,然后使用 ConfigurationBuilder.Add() 方法添加数据源, Add 方法可以添加继承了 IConfigu

  • ASP.NET Core中使用滑动窗口限流的问题及场景分析

    目录 算法原理 漏检 太刚 算法实现 进程内即内存滑动窗口算法 基于Redis的滑动窗口算法 应用算法 1.安装Nuget包 2.使用中间件 滑动窗口算法用于应对请求在时间周期中分布不均匀的情况,能够更精确的应对流量变化,比较著名的应用场景就是TCP协议的流量控制,不过今天要说的是服务限流场景中的应用. 算法原理 这里假设业务需要每秒钟限流100次,先来看固定窗口算法的两个问题: 漏检 如下图所示,单看第1秒和第2秒,其请求次数都没有超过100,所以使用固定窗口算法时不会触发限流.但是第1秒的后

  • ASP.NET Core基于滑动窗口实现限流控制

    目录 前言: 二.固定窗口算法 三.滑动窗口算法 四.实现 六.使用 结论: 前言: 在实际项目中,为了保障服务器的稳定运行,需要对接口的可访问频次进行限流控制,避免因客户端频繁请求导致服务器压力过大. 而​AspNetCoreRateLimit是目前ASP.NET Core下最常用的限流解决方案. 查看它的实现代码,我发现它使用的固定窗口算法. var entry = await _counterStore.GetAsync(counterId, cancellationToken); if

  • ASP.NET Core中Cookie验证身份用法详解

    目录 添加配置 ASP.NETCore1.x ASP.NETCore2.x 创建身份认证Cookie ASP.NETCore1.x ASP.NETCore2.x Signingout(登出) ASP.NETCore1.x ASP.NETCore2.x 服务端变化反馈 ASP.NETCore1.x ASP.NETCore2.x Cookie设置选项 ASP.NETCore1.x ASP.NETCore2.x 持久Cookie ASP.NETCore1.x ASP.NETCore2.x 绝对到期时间

  • ASP.NET Core 使用Cookie验证身份的示例代码

    ASP.NET Core 1.x提供了通过Cookie 中间件将用户主体序列化为一个加密的Cookie,然后在后续请求中验证Cookie并重新创建主体,并将其分配给HttpContext.User属性.如果您要提供自己的登录界面和用户数据库,可以使用作为独立功能的Cookie中间件. ASP.NET Core 2.x的一个主要变化是不再存在Cookie中间件.取而代之的是在Startup.cs文件中的Configure方法中的调用UseAuthentication方法会添加设置HttpConte

  • .NET Core中的HttpClientFactory类用法详解

    一.HttpClient使用 在C#中,如果我们需要向某特定的URL地址发送Http请求的时候,通常会用到HttpClient类.会将HttpClient包裹在using内部进行声明和初始化,如下面的代码: using (var httpClient = new HttpClient()) { // 逻辑处理代码 } HttpClient类包含了许多有用的方法,使用上面的代码,可以满足绝大多数的需求,但是如果对其使用不当时,可能会出现意想不到的事情. 上面代码的技术范点:当你使用继承了IDisp

  • Asp.Net Core中WebSocket绑定的方法详解

    说明 Websocket是html5后的产物,对于asp.net core中也得到了支持,Asp.Net Core中WebScoket的操作使用基本上和Asp.net中相同,不同的是,绑定监听. Asp.Net Core2.0默认已经支持WebSocket,不需要另外安装Nuget包. 通过对HttpContext中的WebSockets.AcceptWebSocketAsync方法,接受WebSocket请求:并返回WebScoket对象. 下面话不多说了,来一起看看详细的介绍吧. 一.示例1

  • asp.net core中灵活的配置方式详解

    前言 asp.net core支持外部文件和命令行参数方式来配置系统运行所需要的配置信息,我们从下面两个常用场景来具体说下具体使用方法. 一.监听地址及端口配置 1,命令行方式 asp.net core系统通过命令行方式启动,使用的命令如下: dotnet run 上面的命令直接在源代码目录下执行,便可以编译程序并运行.那对于已经发布好的程序,就不能使用上面的指令了,应该使用下面的指令: dotnet 程序集文件名(程序集文件名就是程序发布后生成的dll文件) 上面两个指令都能够启动应用程序.程

  • ASP.NET Core 中的模型绑定操作详解

    ASP.Net Core的模型绑定是一个非常有用的功能.一般我们控制器处理Http请求的数据,是通过路由数据提供一个记录键,然后发布的表单域为模型提供一个值,这个过程很繁琐,并且容易出错.而模型绑定会自动化该过程,减少出错的概率.本文介绍下模型绑定中常用的一些操作指南. [BindProperty] .[BindProperties]属性.第一个属性是用于控制器或 PageModel 类的公共属性,从而使模型绑定以该属性为目标:第二个属性是.Net 2.1及以上版本所有,可以使模型绑定以该类的所

  • Asp.net Core中实现自定义身份认证的示例代码

    Asp.Net Core中虽然集成了许多常用的身份认证,但很多时候,我们还是需要实现自己的身份认证接口,本文这里就简单的介绍下如何实现自定义身份认证接口. 首先写一个简单的接口. [Authorize] [HttpGet] public object Foo() { return DateTime.Now.ToString(); } 由于有Authorize标记,访问函数体前会判断用户是否通过认证,由于这里没有通过认证,会的得到一个500错误. 自定义认证处理类: 实现一个IAuthentica

  • Python3网络爬虫中的requests高级用法详解

    本节我们再来了解下 Requests 的一些高级用法,如文件上传,代理设置,Cookies 设置等等. 1. 文件上传 我们知道 Reqeuests 可以模拟提交一些数据,假如有的网站需要我们上传文件,我们同样可以利用它来上传,实现非常简单,实例如下: import requests files = {'file': open('favicon.ico', 'rb')} r = requests.post('http://httpbin.org/post', files=files) print

  • JavaWeb中过滤器Filter的用法详解

    目录 过滤器Filter 处理顺序 使用场景 自定义过滤器 源码分析 FilterDef FilterMap 初始化过滤器 创建过滤器链 ApplicationFilterChain 执行过滤器链 过滤器Filter 过滤器通常对一些web资源进行拦截,做完一些处理器再交给下一个过滤器处理,直到所有的过滤器处理器,再调用servlet实例的service方法进行处理.过滤器可以对request进行处理也可以对response进行处理. 处理顺序 如果过滤器链顺序如上图所示,那么对request请

  • JSP中EL表达式的用法详解(必看篇)

    EL 全名为Expression Language EL 语法很简单,它最大的特点就是使用上很方便.接下来介绍EL主要的语法结构: ${sessionScope.user.sex} 所有EL都是以${为起始.以}为结尾的.上述EL范例的意思是:从Session的范围中,取得 用户的性别.假若依照之前JSP Scriptlet的写法如下: User user =(User)session.getAttribute("user"); String sex =user.getSex( );

随机推荐