.NetCore采取JWT方式进行身份认证

验证与授权

Authentication(身份认证)

认证是系统对请求的用户进行身份识别的过程。

Authorization (授权)

授权是对认证通过后的用户进行权限分配的过程。授权简单理解就是:识别认证后用户所拥有哪些权限,从而开放服务器相对应的资源;

我们通俗点来解释身份验证与授权:验证确认用户是否允许访问,授权给予登录后的用户指定权限标识(通过这个标识,服务端可允许用户进行访问和操作);

在进行讲解Jwt身份认证前我们来回一下过去我们在MVC、WebForm这些站点都是怎样进行身份认证的。

我想应该大多数都是基于Cookie、Form表单的身份验证方式吧。

Cookie验证方式的流程图如下:

上面流程就是服务端在接收用户登录请求后创建Cookie并保存在服务器上,然后通过Response.Cookies.Add将Cookie返回客户端。

客户端浏览器可以记住服务器返回的Cookie,记住后Cookie值会存储在客户端硬盘上,下次访问站点时候Http请求头会携带Cookie。

携带Cookie的请求到服务端后,服务端进行验证,验证通过后即可正返回请求的资源,否则会跳转到登录页面。

Cookie方式的缺点

了解到Cookie方式的验证流程后可以发现它是对Http请求强加了一层“会话”,让我们的Http请求携带与身份认证相关的标识(Cookie)。

那这种方式有什么不好的呢?我总结了下面几点:

1、对有多种客户端(APP、浏览器、Winform应用)请求的场景不好扩展;
2、对分布式架构的服务端不好扩展,客户端的请求不一定指向同一台服务器,每一台服务器都需存储针对已登录的用户Cookie;
3、跨域访问问题;

Jwt身份验证方式

在多终端,分布式架构的服务无所不在的今天,Cookie身份认证的方式显然是难以满足我们的,这个时候Jwt(Json Web Token)横空出世啦~

使用Jwt我们可以完美的解决上面的遗留问题(当然后面也会说到jwt本身存在的问题....)

我们先看下Jwt的身份验证流程:

根据流程图得知jwt是在返回Token给客户端后要求客户端在Http请求头里携带载有Jwt信息的Authorization对象。

服务端会通过密钥对Jwt信息进行解密和验证,验证通过后会返回客户端所请求的资源。

根据流程我们得知jwt至少依赖这几项:

1、服务端的密钥;

2、客户端请求需指定格式(请求头携带Token);

其中密钥是客户端接触不到的,客户端所拥有的其实就是服务端生成的Token,这个Token是由三部分组成:

1、Header(包含算法和Token的类型:jwt)

2、PayLoad(负载,可配置的一些标识数据,不要将敏感信息写入到PayLoad内)

3、验签

其中Header和PayLoad只是在服务端进行了base64转码,所以如果有人抓取了Http请求是可以轻易截取里面的数据,我们

使用过程中千万不要将一些敏感信息放置里面。想详细了解Jwt信息可以到官网看看,官网地址:https://jwt.io/

.Net Core进行Jwt身份认证

.NetCore上使用Jwt身份认证非常简单,我们在Startup.cs文件的ConfigureServices里加入以下代码:

 1   services.AddAuthentication(x =>
 2             {
 3                 x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
 4                 x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 5             }).AddJwtBearer(x =>
 6             {
 7                 //获取权限是否需要HTTPS
 8                 x.RequireHttpsMetadata = false;
 9                 //在成功的授权之后令牌是否应该存储在Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties中
10                 x.SaveToken = true;
11
12                 x.TokenValidationParameters = new TokenValidationParameters
13                 {
14                     //是否验证秘钥
15                     ValidateIssuerSigningKey = true,
16                     IssuerSigningKey = new SymmetricSecurityKey(key),
17                     ValidateIssuer = false,
18                     ValidateAudience = false
19                 };
20             });

在Startup里的Configure方法必须添加下面这行代码,且要求写在 app.UseMvc();前面。

app.UseAuthentication(); //引用身份认证服务

上面的关键代码是Startup里的代码。 它明确告知系统采取Jwt验证方式为默认的身份认证方式、秘钥的

生成方式,以及一些验证相关的参数配置。

OK,现在我们已经明确了验证方式了,那我们创建Token是在哪里创建的呢?

我们来看看下面代码:

 1         private TokenDto CreateToken(User user)
 2         {
 3             // JwtSecurityTokenHandler可以创建Token
 4             var tokenHandler = new JwtSecurityTokenHandler();
 5             var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
 6             DateTime tokenExpires = DateTime.Now.AddMinutes(3); //过期时间这里写死
 7             DateTime refRefreshTokenExpires = tokenExpires.AddMinutes(-1);
 8             var tokenDescriptor = new SecurityTokenDescriptor
 9             {
10                 Subject = new ClaimsIdentity(new Claim[]
11                 {
12                     //添加申明,申明可以自定义,可以无限扩展,对于后续的身份验证通过后的授权特别有用...
13                     new Claim(ClaimTypes.Name, user.Id.ToString()),
14                     new Claim("refRefreshTokenExpires",refRefreshTokenExpires.ToString()),
15                     new Claim("tokenExpires",tokenExpires.ToString())
16                 }),
17                 Expires = tokenExpires,
18                 IssuedAt = DateTime.Now, //Token发布时间
19                 Audience = "AuthTest", //接收令牌的受众
20                 //根据配置文件的私钥值设置Token
21                 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
22             };
23             var token = tokenHandler.CreateToken(tokenDescriptor);
24             user.Token = tokenHandler.WriteToken(token);
25             TokenDto output = Mapper.Map<TokenDto>(user);
26             output.RefRefreshToken = Guid.NewGuid().ToString();
27             output.RefRefreshTokenExpires = refRefreshTokenExpires.ToString("yyyy-MM-dd HH:mm:ss");
28             output.Token = user.Token;
29             UserRefreshTokenData(user, output);
30             return output;
31         }

上面代码是包含了 刷新Token和刷新Token时间的创建Token方法。

我在验证用户账号密码正确后即调用上面方法将Token返回给客户端,要求客户端在后续的API里必须携带Token来进行访问。

Token的有效时间我在上面写死了为三分钟,即三分钟后访问需授权的接口都会报http响应码为401的错误,如果需要解决则

要求客户端在刷新时间内,携带刷新Token值、刷新时间来调用 刷新Token接口获取 刷新后的Token值。

刷新Token方法;

 1    public TokenDto RefreshToken(TokenDto oldTokenDto)
 2         {
 3             TokenDto output = new TokenDto();
 4             //如果有刷新Token值对应的用户则刷新Token以及RefRefreshToken
 5             var user = _users.FirstOrDefault(p => p.RefRefreshToken == oldTokenDto.RefRefreshToken
 6                                             && Convert.ToDateTime(oldTokenDto.RefRefreshTokenExpires) > DateTime.Now);
 7             if (user != null)
 8             {
 9                 output = CreateToken(user);
10             }
11             return output;
12         }

至此,.NetCore采取JWT验证身份方式就写好了,包含了刷新Token。

对了,还没有总结JWT的劣势,劣势我捋了下面几点:

1、没有一个很方便的撤销已颁发的JWT令牌方法;

2、续签(刷新Token)增加了客户端的工作量(需要客户端在请求前验证刷新Token时间);

不过上面两个问题也不大,撤销令牌可以采取黑名单方式,至于第2点其实问题也不大

与前端约定好流程即可;

原文地址:https://www.cnblogs.com/hunanzp/p/10177145.html

时间: 2024-10-10 00:13:50

.NetCore采取JWT方式进行身份认证的相关文章

掌握基于 JWT 实现的 Token 身份认证

引语 最近正好在独立开发一个后台管理系统,涉及到了基于Token的身份认证,自己边学边用边做整理和总结,对基于JWT实现的Token的身份认证做一次相对比较全面的认识. 一.基于session的跨域身份验证 Internet服务无法与用户身份验证分开.一般过程如下. 用户向服务器发送用户名和密码. 验证服务器后,相关数据(如用户角色,登录时间等)将保存在当前会话中. 服务器向用户返回session_id,session信息都会写入到用户的Cookie. 用户的每个后续请求都将通过在Cookie中

计算机身份认证和消息认证的区别

一.基于秘密信息的身份认证方法 1.口令核对口令核对是系统为每一个合法用户建立一个用户名/口令对,当用户登录系统或使用某项功能时,提示用户输入自己的用户名和口令,系统通过核对用户输入的用户名.口令与系统内已有的合法用户的用户名/口令对(这些用户名/口令对在系统内是加密存储的)是否匹配,如与某一项用户名/口令对匹配,则该用户的身份得到了认证.缺点:其安全性仅仅基于用户口令的保密性,而用户口令一般较短且是静态数据,容易猜测,且易被攻击,采用窥探.字典攻击.穷举尝试.网络数据流窃听.重放攻击等很容易攻

哈希表 之 接入与身份认证技术概述

1 概述 随着信息化的高速发展,对国家.组织.公司或个人来说至关重要的信息越来越多的通过网络来进行存储.传输和处理,为获取这些关键信息的各种网络犯罪也对应急剧上升. 当前,网络安全在某种意义上已经成为一个事关国家安全.社会经济稳定的重大问题.得到越来越多的重视. 在网络安全中.身份认证技术作为第一道,甚至是最重要的一道防线.有着重要地位,可靠的身份认证技术能够确保信息仅仅被正确的"人"所訪问.身份认证技术提供了关于某个人或某个事物身份的保证.这意味着当某人(或某事)声称具有一个特别的身

基于STS和JWT的微服务身份认证

自 Martin Fowler 提出微服务架构的概念后,这个名词就一直比较流行,总是成为众多技术论坛和公众号的讨论热点.很多互联网和软件公司都在将原有的整体架构进行拆分,朝着微服务架构的方向进行迭代,而新的项目也几乎无一例外的成为了实践微服务架构的场所. 对于大多数有经验的工程师来说,将传统的异步函数调用直接改成 REST API 或者某种 RPC 并不是一件很困难的事,要面临的问题包括序列化,调用延时和版本等. 但服务接口之间的安全和身份认证(Authentication)问题往往比较棘手,而

基于http协议的api接口对于客户端的身份认证方式以及安全措施[转]

基于http协议的api接口对于客户端的身份认证方式以及安全措施 由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsessionid)来辨别客户端的身份的,当客户端进行登录服务器也会将登录信息存放在服务器并与客户端的cookie中的jsessionid关联起来,这样客户端再次访问我们就可以识别用户身份了. 但是对于api服务器,我们不能让访问者先登录再进行访问这样不安全,也不友好.所以一般情况我们都是需要客户端提供一个key(每个

api接口对于客户端的身份认证方式以及安全措施

转载 基于http协议的api接口对于客户端的身份认证方式以及安全措施 由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsessionid)来辨别客户端的身份的,当客户端进行登录服务器也会将登录信息存放在服务器并与客户端的cookie中的jsessionid关联起来,这样客户端再次访问我们就可以识别用户身份了. 但是对于api服务器,我们不能让访问者先登录再进行访问这样不安全,也不友好.所以一般情况我们都是需要客户端提供一个key

关于ASP.Net Core Web及API身份认证的解决方案

6月15日,在端午节前的最后一个工作日,想起有段日子没有写过文章了,倒有些荒疏了.今借夏日蒸蒸之气,偷得浮生半日悠闲.闲话就说到这里吧,提前祝大家端午愉快(屈原听了该不高兴了:))!.NetCore自发布以来,颇受关注,现在.Net Core2.0已经正式发布,边迫不及待的将.Net跨平台移植的工作进行到底.想来,也费不了多少事儿.我经常和同事们说,要敢于尝试新鲜事物,不阴损守旧,方能使自己不断进步,站在队伍的前列.下面就关于Asp.Net Core在Web 及API项目上身份认证的问题做下简单

Json Web Token身份认证

用户身份认证一般有5种方式 HTTP Basic authentication在发送请求时在HTTP头中加入authentication字段,将用Base64编码的用户名和密码作为值,每次发送请求的时候都要发送用户名和密码,实现比较简单. Cookies向后台发送用户名和密码,在用户名和密码通过验证后,保存返回的Cookie作为用户已经登录的凭证,每次请求时附带这个Cookie Signatures用户拿到服务器给的私钥,在发送请求前,将整个请求使用私钥来加密,发送的将是一串加密信息,此方式只适

RESTful Api 身份认证安全性设计

REST是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 HTTP 请求的 Method  之中. 详情可以阅读 http://mengkang.net/620.html . 而这篇文章则主要是讨论 RESTful Api 身份认证安全性设计. 没有绝对的安全,这个话题很深, 下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正. 由于 RESTfu