前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用cookie来做身份认证

使用cookie来做身份认证

作者头像
_淡定_
修改于 2018-08-27 17:25:43
修改于 2018-08-27 17:25:43
3.6K0
举报
文章被收录于专栏:dotnet & javadotnet & java

文章是msdn的官方文档,链接在这里。其实也有中文的文档,这里还是想做一个记录。

文章有asp.net core 2.x 和1.x 版本,我这里就忽略1.x了。

下面先说几点额外的东西有助于理解。

Authentication 和 Authorization

这里先讲一下Authentication和Authorization两个词的区别。

Authentication:认证。

Authorization:授权。

简单来说,认证是用来证明一个人的身份,比如说他是一个学生,一个老师,一个boss,那么就需要这么一个认证。授权是用来表示这个用户能做什么事情,比如admin可以修改删除数据,normal user只能查看数据。

Issuer 和 Audience

Issuer:发行者,这里来说就是 cookie 是谁分发的。

Audience:听众,这个 cookie 的受众是谁。

正文

就像你前面看到认证相关的主题,Asp.net core Identity 是一个创建用户和维护用户登录的完备的认证解决方案。但有时你可能也想要自己的基于cookie的认证方式。你可以在不使用Asp.net core Identity的情况下使用cookie来实现一种独立的认证服务。

示例源码在这里

因为我们这里只是做一个demo程序,所以写死一个假设的用户Maria Rodriguez到系统里面。邮箱相关的用户名是“maria.rodriguez@contoso.com”,密码任意。用户通过Pages/Account/Login.cshtml.cs文件中的AuthenticateUser方法做认证。现实环境中应该基于数据库

更多如何从ASP.net Core 1.x 到2.0的信息参考这里.

想使用ASP.net Core Identity,参考这里.

配置

如果程序没有使用Microsoft.AspNetCore.App元程序包,给程序引用一下Microsoft.AspNetCore.Authentication.Cookies(版本≥2.1.0)。

ConfigureServices中,通过AuthenticationAddCookie方法添加一下认证服务。

代码语言:txt
AI代码解释
复制
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();

传给AddAuthenticationAuthenticationScheme值设置了程序默认使用的认证方案。

AuthenticationScheme在你有多个 cookie 认证实例或者你系统用某种特定的方案来做认证的时候是非常有用的。设置成为CookieAuthenticationDefaults.AuthenticationScheme就表示用‘Cookies’来作为一个方案。你可以设置任意的 string 类型的值来区分不同的方案。

Configure方法中,使用UseAuthentication来调用认证中间件用于设置HttpContext.User属性。应在UseMvcWithDefaultRouteUseMvc 方法之前调用UseAuthentication方法。

AddCookie 设置选项

大致是这么设置:

代码语言:txt
AI代码解释
复制
services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.ClaimsIssuer = "test";
        options.ClaimsIssuer = "aa";
        //以及其他...
    });

具体详细的通过CookieAuthenticationOptions来设置相关的选项。着重看几个关键的设置,比如 AccessDeniedPath, LoginPath, LogoutPath, Domain, Name,ExpireTimeSpan

选项

描述

AccessDeniedPath

HttpContext.ForbidAsync触发302时的跳转地址,默认/Account/AccessDenied

ClaimsIssuer

用于设置 cookie 的Issuer 属性。

Cookie.Domain

cookie的有效域。默认是请求的服务器名。浏览器只会给符合的服务器发送 cookie。你可能会希望设置这个值来调整他的作用域。举个例子,设置成.contoso.com他的作用域就包括contoso.com,www.contoso.com,staging.www.contoso.com等。

Cookie.Expiration

获取或设置cookie的有效期。core 2.1+不建议使用。建议是使用ExpireTimeSpan来设置 cookie 的失效时间。

Cookie.HttpOnly

设置 cookie 是否是只能被服务器访问,默认 true,可以设置成 false 给客户端js 脚本访问,但是有可能会造成XSS(跨站脚本攻击)。

Cookie.Name

cookie 的名字。

Cookie.Path

用来隔离同一个服务器下面的不同站点。比如站点是运行在/app1下面,设置这个属性为/app1,那么这个 cookie 就只在 app1下有效。

Cookie.SameSite

表示浏览器是否允许 cookie 被附加到相同的站点。有几种枚举:SameSiteMode.Strict,只允许相同的站点。SameSiteMode.Lax允许以安全的 http方式附加到不同站点或相同站点。为了支持 OAuth 认证,需要设置成SameSiteMode.Lax

Cookie.SecurePolicy

设置是否只允许 https。

DataProtectionProvider

用于设置创建TicketDataFormat(在表格最后)

Events

设置一些时间的处理程序。比如OnSignedIn,OnSigningOut等,默认是不做任何操作。

EventsType

Events的类型。

ExpireTimeSpan

设置存储在 cookie 里面的认证票据的过期时间。服务端会验证加密的 ticket 的有效性。在设置了IsPersistent之后也能在 Set-Cookie 头里面返回。默认的过期时间是14天。

LoginPath

HttpContext.ChallengeAsync方法触发302跳转时候的地址。假设设置成/account/login,比如当前访问/secure 返回401,那么会跳转地址/account/login?returnUrl=/secure,当 login 页面生成一个新的登录身份之后,浏览器会跳转到 secure 页面。默认值是/Account/login

LogoutPath

登出地址。

ReturnUrlParameter

登录或登出之后页面可以做一个跳转,这个跳转地址作为一个参数传过去,这个就用来设置这个参数的名字。

SessionStore

用来保存跨站点请求的身份信息。设置了之后只有 session 的标识符会发送到客户端。当身份标识比较多的时候可以用。

SlidingExpiration

滑动过期。标识一个有新的过期时间的新 cookie是否可以被动态的分发。可以在SignInAsync方法里面使用AuthenticationProperties。使用绝对的 cookie 有效期时间来增加应用的安全性。举个例子:`await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,

new ClaimsPrincipal(claimsIdentity),

new AuthenticationProperties

{

IsPersistent = true,

ExpiresUtc = DateTime.UtcNow.AddMinutes(20)

});` |

| TicketDataFormat | |

| Validate | 验证当前 option是否是有效的。 |

Cookie Policy Middleware

Cookie 策略中间件。用于设置应用的 cookie的兼容性。和顺序有关,只会影响程序管道他后面的设置。如下方式使用。

代码语言:txt
AI代码解释
复制
app.UseCookiePolicy(cookiePolicyOptions);

CookiePolicyOptions提供了程序全局特性相关的设置。并且可以在 cookie 添加或者删除的时候挂钩一些处理程序。 有以下一些属性。

属性

描述

设置 cookie 是否是只能通过服务器访问的。默认是HttpOnlyPolicy.None

一个返回 bool 的函数,如果返回 true 会在弹出一个页面让用户确认使用 cookie

(这个文档上也没说。。。)

同站点策略,默认是SameSiteMode.Lax, Asp.net Core2.0+ 可用。

cookie 被追加的时候调用。

cookie 被删除的时候调用。

标识 cookie 是否必须是https.

创建一个认证 cookie

创建一个包含用户信息的 cookie需要构造一个ClaimsPrincipal。用户信息会被序列化然后保存在cookie 里面。

用必要的 Claim来构造一个ClaimsIdentity,然后调用 SignInAsync 方法。

代码语言:txt
AI代码解释
复制
var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("FullName", user.FullName),
    new Claim(ClaimTypes.Role, "Administrator"),
};

var claimsIdentity = new ClaimsIdentity(
    claims, CookieAuthenticationDefaults.AuthenticationScheme);

var authProperties = new AuthenticationProperties
{
    //AllowRefresh = <bool>,
    // Refreshing the authentication session should be allowed.

    //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
    //cookie 的绝对过期时间,会覆盖ExpireTimeSpan的设置。

    //IsPersistent = true,
    //表示 cookie 是否是持久化的以便它在不同的 request 之间传送。设置了ExpireTimeSpan或ExpiresUtc是必须的。

    //IssuedUtc = <DateTimeOffset>,
    //  凭证认证的时间。

    //RedirectUri = <string>
    //http 跳转的时候的路径。
};

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity), 
    authProperties);

SignInAsync方法创建一个加密过的 cookie 然后把他添加到当前的 response 中。没有设置AuthenticationScheme的话会使用默认的 scheme。

加密是基于asp.net core 的Data Protection系统实现的,所以,如果程序是部署在多台机器或者做了负载均衡上的话,需要配置 data protection(和当年 asp.net 里面的类似。)

登出

SignOutAsync用来登出当前用户并且删除 cookie。代码如下。

代码语言:txt
AI代码解释
复制
await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);

登录和登出需要使用相同的方案名称。也就是一样的AuthenticationScheme。

对后台的改变作出反应

当 cookie 被创建之后,它就成了身份标识的唯一来源。即使在后台禁用了当前用户,因为 已经分发的cookie 无法知晓,所以用户依旧可以保持登录状态直到 cookie 失效。

ValidatePrincipal事件可以用来拦截或者覆盖 cookie 的身份验证。这可以减少被收回权限的用户对系统损害的风险。可以通过如下方式实现这个功能。

首先修改一下 SignInAsync 方法里面获取到的用户相关的 claim。

代码语言:txt
AI代码解释
复制
var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("LastChanged", {数据库的值})//增加一个LastChanged,然后记录一下值
};

var claimsIdentity = new ClaimsIdentity(
    claims, 
    CookieAuthenticationDefaults.AuthenticationScheme);

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity));

然后创建一个CustomCookieAuthenticationEvents继承自CookieAuthenticationEvents

代码语言:txt
AI代码解释
复制
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private readonly IUserRepository _userRepository;

    public CustomCookieAuthenticationEvents(IUserRepository userRepository)
    {
        // 从DI 里面获取用户相关的.
        _userRepository = userRepository;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        var userPrincipal = context.Principal;

        // 查找上面的LastChanged相关的claim.
        var lastChanged = (from c in userPrincipal.Claims
                           where c.Type == "LastChanged"
                           select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !_userRepository.ValidateLastChanged(lastChanged))//调用的ValidateLastChanged来判断这个lastChanged 相关的额 cookie是否是一个有效的cookie
        {
            context.RejectPrincipal();//拒绝这个 cookie

            await context.HttpContext.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);// 自动登出
        }
    }
    //其他的方法,都可以设置
    public override Task SignedIn(CookieSignedInContext context)
    {
        return base.SignedIn(context);
    }
}

然后通过EventsType来调用这个设置,然后注入这个CustomCookieAuthenticationEvents

代码语言:txt
AI代码解释
复制
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

services.AddScoped<CustomCookieAuthenticationEvents>();

考虑一种情况,如果说这个用户更新了之后不影响系统的安全,可以考虑替换context.RejectPrincipal()context.ReplacePrincipal,并且设置context.ShouldRenew=true来无损的更新用户的principal。

上面的实现方法会在每个请求的时候都触发,所以会对系统的性能造成一定的影响。

持久化 cookie

你可能想要持久化 cookie 让他可以在浏览器的不同进程之间使用。cookie 的持久化应该用类似在界面上显示“记住我”的复选框,然后让用户点击的方式来实现。其他类似的机制也行。

下面的代码用来实现 cookie 持久化。

代码语言:txt
AI代码解释
复制
await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

如果 cookie 在浏览器关闭期间过期了,浏览器会在下次启动的时候自动删除 cookie。

AuthenticationPropertiesMicrosoft.AspNetCore.Authentication命名空间里面。

绝对过期时间

可以用ExpiresUtc来设置绝对过期时间,但必须同时设置IsPersistent,否者这个这个参数会被忽略,同时,这个 cookie 只是当前回话有效。

当在 SignInAsync 方法里面设置了ExpiresUtc,它会覆盖CookieAuthenticationOptions设置了的ExpireTimeSpan

下面的代码设置了一个20min 有效期的持久化 cookie,其他有效期相关的设置都会被忽略。

代码语言:txt
AI代码解释
复制
await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

最后就是感慨一下,msdn 好强大。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
.NET core3.1使用cookie进行身份认证
一个系统,用户身份认证少不了,ASP.NET Core提供完整的解决方案Identity,用户创建和维护登录名;也提供能cookie和JwtBearer认证方案,当然你可以使用第三方认证Oauth、openId。项目没有采用前后端分离,是一个标准的mvc项目,所以本文采用系统提供的cookie认证 记录一下简单认证流程,(1)使用用户账号密码进行登录,验证合法登录(2)确认合法身份之后,会颁发一个认证票据(加密)会携带与该用户相关的身份、权限以及其他信息。(3)退出。
李明成
2020/08/28
1.3K0
理解ASP.NET Core - Cookie 的身份认证
链接:cnblogs.com/xiaoxiaotank/p/15811749.html
郑子铭
2022/03/22
1K0
理解ASP.NET Core - Cookie 的身份认证
在 ASP.NET Core 应用中使用 Cookie 进行身份认证
身份认证是网站最基本的功能,最近因为业务部门的一个需求,需要对一个已经存在很久的小工具网站进行改造,因为在逐步的将一些离散的系统迁移至 .NET Core,所以趁这个机会将这个老的 .NET Framework 4.0 的项目进行升级
程序员宇说
2021/02/04
1.4K0
在 ASP.NET Core 应用中使用 Cookie 进行身份认证
ASP.NET Core 中基于 Cookie 的身份鉴权实现
在 ASP.NET Core 应用中,基于 Cookie 的身份鉴权是一种常见的身份验证方式,特别适用于传统的 Web 应用程序。Cookie 能够在用户的浏览器中存储身份验证数据,从而在用户访问应用的不同页面时保持登录状态。
郑子铭
2025/03/11
840
ASP.NET Core 中基于 Cookie 的身份鉴权实现
ASP.NET Core Cookie 认证
Cookie 认证是ASP.NET Core用来实现客户自定义认证逻辑,没有使用ASP.NET Core Identity
郑子铭
2023/12/13
2570
ASP.NET Core Cookie 认证
ASP.NET Core Authentication系列(二)实现认证、登录和注销
在上一篇文章介绍ASP.NET Core Authentication的三个重要概念,分别是Claim, ClaimsIdentity, ClaimsPrincipal,以及claims-base authentication是怎么工作的。
梁规晓
2020/11/05
3.5K0
ASP.NET Core Authentication系列(二)实现认证、登录和注销
.Net Core系列教程(四)—— 基础身份认证
在ASP.NET 4.5及之前的版本,可以使用FormsAuthenticationTicket来做基础身份认证,现在到了.Net Core中,发现原来的FormsAuthenticationTicket不能用了,其实在.Net Core中,依然可以使用基础身份认证,下面是使用方法。因为这是在具体项目中使用的,会多出一些其他的代码,请自行忽略。
徐大嘴
2019/03/21
2.5K0
.net core实践系列之SSO-同域实现
SSO的系列还是以.Net Core作为实践例子与大家分享,SSO在Web方面复杂度分同域与跨域。本篇先分享同域的设计与实现,跨域将在下篇与大家分享。
陈珙
2018/10/15
1.7K0
ASP.NET Core Authentication and Authorization
最近把一个Asp .net core 2.0的项目迁移到Asp .net core 3.1,项目启动的时候直接报错:
MJ.Zhou
2020/04/08
1.2K0
ASP.NET Core Authentication and Authorization
【asp.net core 系列】13 Identity 身份验证入门
通过前两篇我们实现了如何在Service层如何访问数据,以及如何运用简单的加密算法对数据加密。这一篇我们将探索如何实现asp.net core的身份验证。
程序员小高
2020/06/24
1K0
asp.net core 3.1多种身份验证方案,cookie和jwt混合认证授权
开发了一个公司内部系统,使用asp.net core 3.1。在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据。并且只是几个简单的接口不准备再重新部署一个站点,所以就直接在MVC的项目里面加了一个API区域用来写接口。这时候因为是接口所以就不能用cookie方式进行认证,得加一个jwt认证,采用多种身份验证方案来进行认证授权。
SpringSun
2020/08/11
5K0
asp.net core 3.1多种身份验证方案,cookie和jwt混合认证授权
ASP.NET Core快速入门(第6章:ASP.NET Core MVC)--学习笔记
课程链接:http://video.jessetalk.cn/course/explore
郑子铭
2021/01/13
2.3K0
ASP.NET Core快速入门(第6章:ASP.NET Core MVC)--学习笔记
ASP.NET Core快速入门(第5章:认证与授权)--学习笔记
课程链接:http://video.jessetalk.cn/course/explore
郑子铭
2021/01/13
1.4K0
ASP.NET Core快速入门(第5章:认证与授权)--学习笔记
实现基于dotnetcore的扫一扫登录功能
第一次写博客,前几天看到.netcore的认证,就心血来潮想实现一下基于netcore的一个扫一扫的功能,实现思路构思大概是web端通过cookie认证进行授权,手机端通过jwt授权,web端登录界面通过signalr实现后端通讯,通过二维码展示手机端扫描进行登录.源码地址:点我
呆呆
2021/10/09
1.8K0
ASP.NET Core 6框架揭秘实例演示[40]:基于角色的授权
ASP.NET应用并没有对如何定义授权策略做硬性规定,所以我们完全根据用户具有的任意特性(如性别、年龄、学历、所在地区、宗教信仰、政治面貌等)来判断其是否具有获取目标资源或者执行目标操作的权限,但是针对角色的授权策略依然是最常用的。角色(或者用户组)实际上就是对一组权限集的描述,将一个用户添加到某个角色之中就是为了将对应的权限赋予该用户。在《使用最简洁的代码实现登录、认证和注销》中,我们提供了一个用来演示登录、认证和注销的程序,现在我们在此基础上添加基于“角色授权的部分”。(本文提供的示例演示已经同步到《ASP.NET Core 6框架揭秘-实例演示版》)
蒋金楠
2023/07/10
3290
ASP.NET Core 6框架揭秘实例演示[40]:基于角色的授权
ASP.NET Core 对Controller进行单元测试
单元测试对我们的代码质量非常重要。很多同学都会对业务逻辑或者工具方法写测试用例,但是往往忽略了对Controller层写单元测试。我所在的公司没见过一个对Controller写过测试的。今天来演示下如果对Controller进行单元测试。以下内容默认您对单元测试有所了解,比如如何mock一个接口。在这里多叨叨一句,面向接口的好处,除了能够快速的替换实现类(其实大部分接口不会有多个实现),最大的好处就是可以进行mock,可以进行单元测试。
MJ.Zhou
2020/06/23
2K0
ASP.NET Core 和 ASP.NET Framework 共享 Identity 身份验证
  .NET Core 已经热了好一阵子,1.1版本发布后其可用性也越来越高,开源、组件化、跨平台、性能优秀、社区活跃等等标签再加上“微软爸爸”主推和大力支持,尽管现阶段对比.net framework还是比较“稚嫩”,但可以想象到它光明的前景。作为 .net 开发者你是否已经开始尝试将项目迁移到 .net core 上?这其中要解决的一个较大的问题就是如何让你的 .net core 和老 .net framework 站点实现身份验证兼容! 1、第一篇章 我们先来看看 .net core 中对 id
捷义
2018/05/14
2.1K0
.net core 认证与授权(一)
.net core web并不是一个非常新的架构,很多文章提及到认证与授权这个过程,但是一般都会提及到里面的方法怎么用的,而不是模拟一个怎样的过程,所以我打算记录自己的理解。 什么是认证?我们大学毕业有学士证书和毕业证书,来证明你是一个学士。 什么是授权,比如说你被认证是我的朋友后,你可以拿着这个身份,可以进入我的朋友圈看动态。 那么.net core 的认证与授权是一个什么样的过程,在这里提出简单模式是我给你颁发了证书,证明了你的身份,然后呢,你可以拿到你的身份卡之后,你要经过验证,得到授权,然后进入中华人民共和国,就是这个过程。 正文部分均为我的理解,可能存在误差,如果不对请指正。
梁规晓
2020/02/19
6830
.net core 认证与授权(一)
使用Microsoft.AspNetCore.TestHost进行完整的功能测试
  Microsoft.AspNetCore.TestHost是可以用于Asp.net Core 的功能测试工具。很多时候我们一个接口写好了,单元测试什么的也都ok了,需要完整调试一下,检查下单元测试未覆盖到的代码是否有bug。步骤为如下:程序打个断点->F5运行->通常需要登录个测试账号->查找要调试api的入口->获得断点开始调试=>代码报错?很多时候需要停止调试修改->回到第一步。如此反复循环,做着重复的工作,Microsoft.AspNetCore.TestHost正是为了解决这个问题,它可以让你使用xTest或者MSTest进行覆盖整个HTTP请求生命周期的功能测试。
顾翔
2019/12/11
9390
使用Microsoft.AspNetCore.TestHost进行完整的功能测试
ASP.NET Core 6框架揭秘实例演示[39]:使用最简洁的代码实现登录、认证和注销
认证是一个确定请求访问者真实身份的过程,与认证相关的还有其他两个基本操作——登录和注销。ASP.NET Core利用AuthenticationMiddleware中间件完成针对请求的认证,并提供了用于登录、注销以及“质询”的API,本篇文章利用它们使用最简单的代码实现这些功能。(本文提供的示例演示已经同步到《ASP.NET Core 6框架揭秘-实例演示版》)
蒋金楠
2023/07/10
3430
ASP.NET Core 6框架揭秘实例演示[39]:使用最简洁的代码实现登录、认证和注销
推荐阅读
相关推荐
.NET core3.1使用cookie进行身份认证
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档