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方法会添加设置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.csConfigureServices方法中将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.csConfigureServices方法中使用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属性是互斥的。

原文:《Using Cookie Authentication without ASP.NET Core Identity》https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x
翻译:Sweet Tang
本文地址:<http://www.cnblogs.com/tdfblog/p/aspnet-core-security-authentication-cookie.html >

相关文章: 

  • .NET Core 2.0 正式发布信息汇总

  • .NET Standard 2.0 特性介绍和使用指南

  • .NET Core 2.0 的dll实时更新、https、依赖包变更问题及解决

  • .NET Core 2.0 特性介绍和使用指南

  • Entity Framework Core 2.0 新特性

  • 体验 PHP under .NET Core

  • .NET Core 2.0使用NLog

  • 升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

  • 解决Visual Studio For Mac Restore失败的问题

  • ASP.NET Core 2.0 特性介绍和使用指南

  • .Net Core下通过Proxy 模式 使用 WCF

  • .NET Core 2.0 开源Office组件 NPOI

  • ASP.NET Core Razor页面 vs MVC

  • Razor Page–Asp.Net Core 2.0新功能  Razor Page介绍

原文地址:http://www.cnblogs.com/inday/p/razor-page-in-asp-net-core-2.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jzoj1264,P2866-乱头发节,糟糕的一天Bad Hair Day【单调栈】

正题 评测记录&#xff1a;https://www.luogu.org/recordnew/lists?uid52918&pidP2866 大意 一个cici是在他距离他后面第一个比他的hh大中间的间隔。求ci" role="presentation" style="position: relative;">cici的和 解题思路 我们可以发…

Node.JS第二讲笔记

大家好&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂package包包结构包其实就是一个压缩文件&#xff0c;解压之后还原为目录&#xff0c;符合规范的目录&#xff0c;应该包含如下文件&#xff1a;package.json:描述文件bin&#xff1a;可执行的二进制文件lib&#…

面试-线程池的成长之路

转载自 面试-线程池的成长之路 背景 相信大家在面试过程中遇到面试官问线程的很多&#xff0c;线程过后就是线程池了。从易到难&#xff0c;都是这么个过程&#xff0c;还有就是确实很多人在工作中接触线程池比较少&#xff0c;最多的也就是创建一个然后往里面提交线程&…

jzoj1265-Round Numbers【数位统计】

正题 大意 求一个闭区间内二进制0的个数大于等于1的个数的数的数量。 解题思路 我们将二进制考虑成01串 我们先不考虑有前导零的情况&#xff1a; 在kk个空位中放i" role="presentation" style="position: relative;">ii个0&#xff0c;别的都…

asp.net core MVC 过滤器之ActionFilter过滤器(二)

简介 Action过滤器将在controller的Action执行之前和之后执行相应的方法。 实现一个自定义Action过滤器 自定义一个全局异常过滤器需要实现IActionFilter接口 public class ActionFilter : IActionFilter { public void OnActionExecuted(ActionExecutedContext context) …

【最全最详细】publiccms使用教程

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂拉取项目&#xff08;项目部署阶段&#xff09;1.首先需要从gitee中拉取项目&#xff0c;地址为&#xff1a;public cms项目地址 &#xff0c;在idea中点击文件--》新建--》来自版本控制的项…

NIO、Netty

https://bright-boy.gitee.io/technical-notes/#/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/netty

学习 Spring Boot 知识看这一篇就够了

转载自 学习 Spring Boot 知识看这一篇就够了 从2016年因为工作原因开始研究 Spring Boot &#xff0c;先后写了很多关于 Spring Boot 的文章&#xff0c;发表在技术社区、我的博客和我的公号内。粗略的统计了一下总共的文章加起来大概有六十多篇了&#xff0c;其中一部分是在…

jzoj1266,P1879-[USACO06NOV]玉米田Corn Fields【状态压缩,dp】

正题 评测记录&#xff1a;https://www.luogu.org/recordnew/lists?uid52918&pidP1879 大意 有n*m的矩阵&#xff0c;有些地方可以放&#xff0c;有些不可以放&#xff0c;不可以相邻的放&#xff0c;求放置方法总数。 解题思路 先用二进制表示每一行的是否可以放置的状…

越努力越幸运,三年了!!!

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”今天非常的开心&#xff0c;因为考了三年的驾照终于考完了。在大厅候考的时候&#xff0c;从10.40等到了1.40,坐在下面能看到LED上有自己的名字&#xff0c;但是前面等待的有200多人………

为什么我们要使用Async、Await关键字

前不久&#xff0c;在工作中由于默认&#xff08;xihuan&#xff09;使用Async、Await关键字受到了很多质问&#xff0c;所以由此引发这篇博文“为什么我们要用Async/Await关键字”&#xff0c;请听下面分解&#xff1a; Async/Await关键字 Visual Studio&#xff08;.net fra…

go web

模块&#xff1a;go mod init webDemo 设置web服务器 方法一&#xff1a; http.ListenAndServe("localhost:8080", nil)方法二&#xff1a; server : http.Server{Addr: "localhost:8080",Handler: nil,} server.ListenAndServe()例 package mainimpor…

一次惊险的跳槽面试经历(阿里/美团/头条/网易/有赞...)

转载自 一次惊险的跳槽面试经历&#xff08;阿里/美团/头条/网易/有赞...) 每次说因为生活成本的时候面试官都会很惊奇&#xff0c;难道有我们这里贵&#xff1f;好想直接给出下面这张图&#xff0c;厦门的房价真的好贵好贵好贵。。。 面试过程 有兴趣加入阿里的欢迎发简历…

利用bladex+avue实现一对多的关系

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”今天&#xff0c;记录一篇技术文章吧&#xff0c;也是解决了好久才解决掉的&#xff08;说来也惭愧&#xff09;。涉及技术前端&#xff1a;vue&#xff0c;element ui后端框架&#xff…

jzoj1267-路障【最短路,SPFA】

正题 大意 一张无向图&#xff0c;求次短路。 解题思路 我们先求出最短路并且求出点1和点n到每个点的距离&#xff0c;然后枚举边&#xff0c;将第一个点离点1的距离&#xff0c;和第二个点离点n的距离加上边权如果不是最短路就记录&#xff0c;然后取最小值。 IOI赛制不需要…

.NET中的高性能应用

本文要点 .NET自4.0以来得到了大幅的性能提升&#xff0c;很值得重新考虑一下基于旧版本.NET框架所做的假定。在讨论性能时垃圾回收是个重复出现的主题&#xff0c;它带来了许多CLR和语言的提升&#xff0c;比如引用返回和ValueTask在内存分配上更细粒度度量的性能分析API会成…

go 数组 切片 映射

文章目录数组切片映射数组 package mainimport "fmt"func main() {fmt.Println("array coding........")//var array [5]int//array[2] 2//var array [5]int{0, 1, 2, 3, 4}//array : [5]int{0, 1, 2, 3, 4}array : [...]int{0, 1, 2, 3, 4}//array : […

利用bladex+avue实现下拉数据源展示

“ 大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;????雄雄的小课堂???? ”昨天给大家整理了下如何使用bladex实现多表查询的方法&#xff0c;今天我们趁热打铁&#xff0c;顺便看看下拉列表的实现。 需求 我们经常会有这样的需求&#xff0c;…

汇编语言(一)之反转字符串输出

BASED ADDRESSING反转输出 程序运行&#xff1a; 代码&#xff1a; datas segmentstring db BASED ADDRESSING$ count dw $-string-1 ;计算string的长度&#xff0c;$为当前地址&#xff0c;-1为去掉字符串结束符$srcsTip db SRC string:$ dstsTip db 0…

2018/7/17-纪中某C组题【jzoj4024,jzoj4025,jzoj2136,jzoj2137】

前言 今天第一道题调了一会就好了&#xff0c;然后一直在调第二道题&#xff0c;然后也没调出来。赛后之后发现第2道题我想的是正解&#xff0c;结果依旧调了很久。其他都还好。 今日分数 Rankperson分数4zyc27014xxy18018hjq15018xjq15018lw15023hzb12023蒟蒻12029lrz110 正…