我的编程空间,编程开发者的网络收藏夹
学习永远不晚

.NET Core怎么实现Cookie和JWT混合认证、授权

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

.NET Core怎么实现Cookie和JWT混合认证、授权

本篇内容介绍了“.NET Core怎么实现Cookie和JWT混合认证、授权”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前言

为防止JWT Token被窃取,我们将Token置于Cookie中,但若与第三方对接,调用我方接口进行认证、授权此时仍需将Token置于请求头,通过实践并联系理论,我们继续开始整活!首先我们实现Cookie认证,然后再次引入JWT,最后在结合二者使用时联系其他我们可能需要注意的事项

Cookie认证

在startup中我们添加cookie认证服务,如下:

services.AddAuthentication(options =>{    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;}).AddCookie(options =>{    options.ExpireTimeSpan = TimeSpan.FromMinutes(1);    options.Cookie.Name = "user-session";    options.SlidingExpiration = true;});

接下来则是使用认证和授权中间件,注意将其置于路由和终结点终结点之间,否则启动也会有明确异常提示

app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseEndpoints(endpoints =>{  ......});

我们给出测试视图页,并要求认证即控制器添加特性

[Authorize]public class HomeController : Controller{    public IActionResult Index()    {        return View();    }}

当进入首页,未认证默认进入account/login,那么接下来创建该视图

public class AccountController : Controller{    [AllowAnonymous]    public IActionResult Login()    {      return View();    }    ......}

我们启动程序先看看效果

.NET Core怎么实现Cookie和JWT混合认证、授权

如上图,自动跳转至登录页,此时我们点击模拟登录按钮,发起请求去模拟登录(发起ajax请求代码就占不用篇幅给出了)

/// <summary>/// 模拟登录/// </summary>/// <returns></returns>[HttpPost][AllowAnonymous]public async Task<IActionResult> TestLogin(){    var claims = new Claim[]    {      new Claim(ClaimTypes.Name, "Jeffcky"),    };    var claimsIdentity = new ClaimsIdentity(claims, "Login");    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));    return Ok();}

上述无非就是构建身份以及该身份下所具有的身份属性,类似个人身份证唯一标识个人,身份证上各个信息即表示如上声明,同时呢,肯定要调用上下文去登录,在整个会话未过期之前,根据认证方案获取对应处理方式,最后将相关信息进行存储等等,有兴趣的童鞋可以去了解其实现细节哈

.NET Core怎么实现Cookie和JWT混合认证、授权

当我们请求过后,再次访问首页,将看到生成当前会话信息,同时我们将会话过期设置为1分钟,在1分钟内未进行会话,将自动重定向至登录页,注意如上标注并没有值,那么这个值可以设置吗?当然可以,在开始配置时我们并未给出,那么这个属性又代表什么含义呢?

options.Cookie.MaxAge = TimeSpan.FromMinutes(2);

那么结合ExpireTimeSpan和MaxAge使用,到底代表什么意思呢?我们暂且撇开滑动过期设置

ExpireTimeSpan表示用户身份认证票据的生命周期,它是认证cookie的有效负载,存储的cookie值是一段加密字符串,在每次请求时,web应用程序都会根据请求对其进行解密

MaxAge控制着cookie的生命周期,若cookie过期,浏览器将会自动清除,如果没有设置该值,实质上它的生命周期就是ExpireTimeSpan,那么它到底有何意义呢?

上述我们设置票据的生命周期为1分钟,同时我们控制cookie的生命周期为2分钟,若在2分钟内关闭浏览器或重启web应用程序,此时cookie生命周期并未过期,所以仍将处于会话状态即无需登录,若未设置MaxAge,关闭浏览器或重启后将自动清除其值即需登录,当然一切前提是未手动清除浏览器cookie

问题又来了,在配置cookie选项中,还有一个也可以设置过期的属性

options.Cookie.Expiration = TimeSpan.FromMinutes(3);

当配置ExpireTimeSpan或同时配置MaxAge时,无需设置Expiration,因为会抛出异常

.NET Core怎么实现Cookie和JWT混合认证、授权

JWT认证

上述已经实现Cookie认证,那么在与第三方进行对接时,我们要使用JWT认证,我们又该如何处理呢?首先我们添加JWT认证服务

.AddJwtBearer(options =>{    options.TokenValidationParameters = new TokenValidationParameters    {      ValidateIssuerSigningKey = true,      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456")),      ValidateIssuer = true,      ValidIssuer = "http://localhost:5000",      ValidateAudience = true,      ValidAudience = "http://localhost:5001",      ValidateLifetime = true,      ClockSkew = TimeSpan.FromMinutes(5)    };});

将JWT Token置于cookie中,此前文章已有讲解,这里我们直接给出代码,先生成Token

private string GenerateToken(Claim[] claims){    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456"));    var token = new JwtSecurityToken(      issuer: "http://localhost:5000",      audience: "http://localhost:5001",      claims: claims,      notBefore: DateTime.Now,      expires: DateTime.Now.AddMinutes(5),      signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)    );    return new JwtSecurityTokenHandler().WriteToken(token);}

在登录方法中,将其写入响应cookie中,如下这般

/// <summary>/// 模拟登录/// </summary>/// <returns></returns>[HttpPost][AllowAnonymous]public async Task<IActionResult> TestLogin(){    var claims = new Claim[]    {      new Claim(ClaimTypes.Name, "Jeffcky"),    };    var claimsIdentity = new ClaimsIdentity(claims, "Login");    Response.Cookies.Append("x-access-token", GenerateToken(claims),      new CookieOptions()      {        Path = "/",        HttpOnly = true      });    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); return Ok();}

那么JWT是如何验证Token的呢?默认是从请求去取Bearer Token值,若成功取到这赋值给如下context.Token,所以此时我们需要手动从cookie中取出token并赋值

options.Events = new JwtBearerEvents{    OnMessageReceived = context =>    {        var accessToken = context.Request.Cookies["x-access-token"];        if (!string.IsNullOrEmpty(accessToken))        {            context.Token = accessToken;        }        return Task.CompletedTask;    }};

一切已就绪,接下来我们写个api接口测试验证看看

[Authorize("Bearer")][Route("api/[controller]/[action]")][ApiController]public class JwtController : ControllerBase{    [HttpGet]    public IActionResult Test()    {      return Ok("test jwt");    }}

思考一下,我们通过Postman模拟测试,会返回401吗?结果会是怎样的呢?

.NET Core怎么实现Cookie和JWT混合认证、授权

问题不大,主要在于该特性参数为声明指定策略,但我们需要指定认证方案即scheme,修改成如下:

.NET Core怎么实现Cookie和JWT混合认证、授权

如此在与第三方对接时,请求返回token,后续将token置于请求头中即可验证通过,同时上述取cookie中token并手动赋值,对于对接第三方则是多余,不过是为了诸多其他原因而已

[Authorize(AuthenticationSchemes = "Bearer,Cookies")]

注意混合认证方案设置存在顺序,后者将覆盖前者即如上设置,此时将走cookie认证

.NET Core怎么实现Cookie和JWT混合认证、授权

滑动过期思考扩展

若我们实现基于Cookie滑动过期,同时使用signalr进行数据推送,势必存在问题,因为会一直刷新会话,那么将导致会话永不过期问题,从安全层面角度考虑,我们该如何处理呢?

我们知道票据生命周期存储在上下文AuthenticationProperties属性中,所以在配置Cookie选项事件中我们可以进行自定义处理

public class CookieAuthenticationEventsExetensions : CookieAuthenticationEvents{    private const string TicketIssuedTicks = nameof(TicketIssuedTicks);    public override async Task SigningIn(CookieSigningInContext context)    {        context.Properties.SetString(          TicketIssuedTicks,          DateTimeOffset.UtcNow.Ticks.ToString());        await base.SigningIn(context);    }    public override async Task ValidatePrincipal(      CookieValidatePrincipalContext context)    {        var ticketIssuedTicksValue = context          .Properties.GetString(TicketIssuedTicks);        if (ticketIssuedTicksValue is null ||          !long.TryParse(ticketIssuedTicksValue, out var ticketIssuedTicks))        {          await RejectPrincipalAsync(context);          return;        }        var ticketIssuedUtc =          new DateTimeOffset(ticketIssuedTicks, TimeSpan.FromHours(0));        if (DateTimeOffset.UtcNow - ticketIssuedUtc > TimeSpan.FromDays(3))        {          await RejectPrincipalAsync(context);          return;        }        await base.ValidatePrincipal(context);    }    private static async Task RejectPrincipalAsync(      CookieValidatePrincipalContext context)    {        context.RejectPrincipal();        await context.HttpContext.SignOutAsync();    }}

在添加Cookie服务时,有对应事件选项,使用如下

options.EventsType = typeof(CookieAuthenticationEventsExetensions);

扩展事件实现表示在第一次会话到当前时间截止超过3天,则自动重定向至登录页,最后将上述扩展事件进行注册即可

“.NET Core怎么实现Cookie和JWT混合认证、授权”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

.NET Core怎么实现Cookie和JWT混合认证、授权

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

.NET Core怎么实现Cookie和JWT混合认证、授权

本篇内容介绍了“.NET Core怎么实现Cookie和JWT混合认证、授权”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言为防止JWT
2023-06-26

ASP.NET Core 6.0怎么添加JWT认证和授权功能

本篇内容介绍了“ASP.NET Core 6.0怎么添加JWT认证和授权功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!相关名词Authe
2023-06-30

SpringBoot中怎么实现安全认证和授权

在Spring Boot中,可以使用Spring Security实现安全认证和授权。Spring Security是一个强大且高度可定制的框架,可以帮助我们轻松地实现各种安全功能,包括用户认证、用户授权、密码加密、会话管理等。以下是在S
SpringBoot中怎么实现安全认证和授权
2024-03-07

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录