ASP.Net Core实战——身份认证(JWT鉴权)
踩坑不背锅,.NET Core 试深浅
- 关于鉴权认证
- 什么是鉴权认证
- 常见鉴权方式
- 关于JWT认证
- JWT认证流程
- JWT组成
- JWT实践
关于鉴权认证
什么是鉴权认证
鉴权(authentication)是指验证用户是否拥有访问系统的权利。传统的鉴权是通过密码来验证的。这种方式的前提是,每个获得密码的用户都已经被授权。在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请。这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份。
为了克服这种鉴权方式的缺点,需要一个更加可靠的鉴权方式。目前的主流鉴权方式是利用认证授权来验证数字签名的正确与否。
常见鉴权方式
Session机制 Session 是一种HTTP存储机制,Session对象存储特定用户会话所需的属性及配置信息,目的是为无状态的HTTP提供的持久机制,把 User 信息存储到 Session 里。可以理解为一张短期通行证,给请求用户颁发短期证件,每次门岗检查短期卡号在备案名册中,允许通行,因为 SID 的不可预测性,暂且认为是安全的。
JWT机制
JWT即JSON Web Tokens,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519),他可以用来安全的传递信息,因为传递的信息是经过加密算法加密过得。相当于一张长期通行证,给请求用户颁发长期证件,每次检查证件人信息,正确允许通行。
OAuth2机制 OAuth的英文全称是Open Authorization,它是一种开放授权协议,由认证机构分别为服务与用户颁发凭证,用户授权服务使用凭证,接着服务使用此凭证去认证合法性,最终得到目标数据,如同调兵遣将时使用的两片虎符,由皇庭下发授权。
关于JWT认证
JWT认证流程
通过上图,我们可以看到它的授权流程
- 客户端通过请求服务端登录认证接口
- 服务端用秘密创建JWT
- 服务端将JWT返回浏览器
- 客户端在授权报头上发送JWT
- 服务端检查JWT签名从JWT获取用户信息
- 服务端向客户端发送响应
JWT组成
官网 https://jwt.io/
JSON Web Tokens(JWT)有三部分构成:Header、Payload、VERIFY SIGNATURE,用英文句点分割(.) ,一般看起来例如:aaaaaaa.bbbbbbb.ccccccc。
Header 头信息,通常包含两部分:
- type: 代表token的类型,这里使用的是JWT类型。
- alg: 代表使用的算法,例如HMAC SHA256或RSA.
Payload 荷载信息,它包含一些声明Claim(实体的描述,例:用户信息和其他的一些元数据),声明分三类:
- Reserved Claims,这是一套预定义的声明,并不是必须的,这是一套易于使用、操作性强的声明。包括:iss(issuer)、exp(expiration time)、sub(subject)、aud(audience)等
- Plubic Claims,
- Private Claims,交换信息的双方自定义的声明
VERIFY SIGNATURE 由头信息+荷载信息+密钥 组合之后进行加密得到,如使用的是HMAC SHA256算法,大致流程类似于: HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)。VERIFY SIGNATURE字段被用来确认JWT信息的发送者是谁,并保证信息没有被修改。
JWT实践
想要实现JWT认证,需要做好两方面,Token令牌的签发与真实性验证。 首先准备一个用户信息对象(存放从数据库中查询到的相关信息)。
public class Tokens{/// <summary>/// ID/// </summary>public string ID{ get; set; }/// <summary>/// 名称/// </summary>public string Login_name { get; set; }/// <summary>/// 手机/// </summary>public string Phone { get; set; }/// <summary>/// 邮箱/// </summary>public string Email { get; set; }/// <summary>/// 身份/// </summary>public string Sub { get; set; }}
接下来,使用以上部分信息生成Token
// 密钥,注意不能太短(这个是我在网上随便生成的)public static string secretKey { get; set; } = @"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMniN23tMkxBh6j3vCQ5c4JqsZ8p8NqNqeCjNQPDga9RtIFCt3/5n4aIyUaA0ONVMOHEt33g8EoayVZMKQGf4aPjConiAXYUYy540fs8r9l0oJyHWx+5at0nkKFfTtpgppXQRjWiWyeOq3RX9jhsdFKBPqbugZW4yjlt1QlSWaQtAgMBAAECgYEAm9vNt0w8XKrqtQQteDnyd2kvoBWdIN3lnMvjjfhOErAdjv2W9XIeOps36PpiSl/m0SYyEzipykxLzBgYQGzSoXgZwp91lmUKxVpCi6QgZU+VCR5q+Tr4BuLmi7GsJE0EwcpdC6jnOwbZXdhClLaQgRiiLPbiLw+CADbiHQqaRoECQQD0sE6VOqPW2eqPHH6mqaqy+owU0UiBCkW8xfBKqR74ufgnCveDLrfE+vxIqVBU1HN+/LqKZ1rPEkqPdjAUJk3pAkEA0zdYs12mu+as3araCPrnAppsZRRGizVKmKVB074W63NZ7SiXsEqDBj3fp1oeGo2OiKWCnjEmmtzpIvfVbzjlpQJBAOTQPhwUgwO2Mj7z0Ye+n47Q9s+8yYVJ+t7FZqgasIi9N04jVkPJGzZL0kGMez9okDyOz03/yo5bN3gieGFPVIkCQQCAMt2xsKwc7HwL50GDpdZFLDmSeGYA5I2sbNGxlXUP3+m7GqJHLFKunSt8xiPzdewHYH4RSj/mSyNuSALSCTTJAkBBN7BWA39VyvJDALVYqHDKNx0r5BwSTVk8wJvn7KKzB1YdVZrl/pIIi+uPbZwBJA80QXJu4sjCyc5XBzgQdsiv";// 生成JWT字符串public static string GetJWT(Tokens tokenModel){var claims = new List<Claim>{new Claim(JwtRegisteredClaimNames.Jti,tokenModel.Login_name),// 令牌颁发时间new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),// 过期时间 100秒new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),new Claim(JwtRegisteredClaimNames.Iss,"API"), // 签发者new Claim(JwtRegisteredClaimNames.Aud,"User") // 接收者};// 密钥var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));var creds = new SigningCredentials(key, SecurityAlgorithms.RsaSha512);JwtSecurityToken jwt = new JwtSecurityToken(claims: claims,// 声明的集合//expires: .AddSeconds(36), // token的有效时间signingCredentials: creds);var handler = new JwtSecurityTokenHandler();// 生成 jwt字符串var strJWT = handler.WriteToken(jwt);return strJWT;}
在这里会需要引用几个包:
- Microsoft.IdentityModel.Tokens;
- System.IdentityModel.Tokens.Jwt;
- System.Security.Claims;
在Startup 注册Authentication服务与中间件
服务
//添加jwt验证:services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = true,//是否验证IssuerValidateAudience = true,//是否验证AudienceValidateLifetime = true,//是否验证失效时间ValidateIssuerSigningKey = true,//是否验证SecurityKeyValidAudience = "User",//AudienceValidIssuer = "API",//Issuer,这两项和后面签发jwt的设置一致ClockSkew = TimeSpan.Zero, // // 默认允许 300s 的时间偏移量,设置为0IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenHelper.secretKey))//拿到SecurityKey};});
中间件
app.UseAuthentication();
在这里需要注意:签发者与接受者的对应
然后在Controller上加上关键代码,这样对应该路由的请求都会进行Authentication,当你的都头文件包含正确的Token就可以正常返回。
最后,在Swagger中试验一下
首先修改Swagger的 options 内容
//开启权限小锁options.OperationFilter<AddResponseHeadersFilter>();options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();//在header中添加token,传递到后台options.OperationFilter<SecurityRequirementsOperationFilter>();options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme{Description = "JWT授权(数据将在请求头中进行传递)直接在下面框中输入Bearer {token}(注意两者之间是一个空格) \"",Name = "Authorization",//jwt默认的参数名称In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)Type = SecuritySchemeType.ApiKey});
运行,我们可以在SwaggerUI页面看到多出来一个小锁Authorize
当请求没有携带Token,返回错误信息
先请求Token
点击上面的小锁Authorize,填入刚刚获取的Token信息(依据提示,在前面加上 Bearer+space)
然后就可以看到接口标签上的小锁是认证状态了,再次请求接口,就能正确获取数据。
仅仅简单的使用JWT鉴权认证,有更好的想法欢迎留言指导
ASP.Net Core实战——身份认证(JWT鉴权)相关推荐
- ASP.NET Core的身份认证框架IdentityServer4(4)- 支持的规范
原文:ASP.NET Core的身份认证框架IdentityServer4(4)- 支持的规范 IdentityServer实现以下规范: OpenID Connect OpenID Connect ...
- ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释
ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释 原文:ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释 IdentityS ...
- 关于身份认证和鉴权过程
关于身份认证和鉴权过程 开机信令流程 总结: 附 重要消息内容举例 LTE NAS EMM Plain OTA Outgoing Message -- Attach request Msg(含PDN ...
- ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露
一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...
- ASP.NET Core的身份认证框架IdentityServer4--入门【转】
原文地址 Identity Server 4是IdentityServer的最新版本,它是流行的OpenID Connect和OAuth Framework for .NET,为ASP.NET Cor ...
- ASP.NET Core的身份认证框架IdentityServer4--(5)自定义用户登录(通过接口登录,无UI版本)...
官网接口详解文档地址:文档地址 (PS:可通过接口名称搜索相应接口信息.) 源码地址:https://github.com/YANGKANG01/IdentityServer4-IdentityAut ...
- php 身份认证 claim,asp.net core cookie身份认证view视图中读取/读取User.Claims中的值实例...
假设claim如下,q为查询出来的用户表结果集 var claims = new List(){ new Claim("UserId", q.Id.ToString()), new ...
- ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法
ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法 一.前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类 ...
- 微服务架构下的安全认证与鉴权
微服务架构下的安全认证与鉴权 转载自:https://mp.weixin.qq.com/s/qBJ_257IWn3cctqmKfJ7FQ 作者:王海龙,来自:EAWorld 现任普元云计算架构师,毕业 ...
最新文章
- Google人体图像分割模型Bodypix再次更新,针对Coral开发板优化,720p/30fps流畅运行...
- issubclass和isinstance 反射 内置方法(魔术方法)
- oracle快照太旧含义,全解ORA-1555快照太旧错误原理及解决方案
- 按钮点击_如何设置微信小程序按钮点击事件?
- java sqlserver 死锁_sqlserver数据库发生死锁处理
- Java实现hsql_java – 从类创建HSQL创建表查询
- swift(不同设备适配详解)
- 多个中间件_小T说:消息中间件,为什么用RabbitMQ及支持的场景
- 计算机毕业设计安卓旅游APP源码
- 机房维护 网拷_利用网络还原系统(远志)快速维护机房
- AUTOSAR接口类型及访问规则
- python获取b站视频封面及弹幕
- 程序员技能树的分层分级方法
- Python:实现ternary search三元搜索算法(附完整源码)
- Win10怎么默认用Windows照片查看程序打开图片
- 首个Nginx windows Stable 版--轻量级Web服务器Nginx 0.7.59
- 德克萨斯长角牛 --最短路径
- 未来十年的音视频,教科书级别的Android音视频开发教程,学完我成功“挤进”了抖音音视频开发岗
- 创建签名文件jks 乱码
- 【PTA】帅到没朋友(C语言)
热门文章
- 羊毛地毯可以用水洗吗
- 【校招VIP】产品经理之明确活动目的
- windows server 2008 R2无法共享文件夹,无法启用网络发现。
- 数据重塑_Google是否会重塑电话
- 计算机64位只有2g,电脑插了4G内存,但只有2G左右可以用,为什么 WIN7 64位
- 苹果计算机的桌面图是什么情况,苹果电脑开机后,只能显示电脑桌面,桌面图标都不能显示。怎么办?...
- c语言编译器error,KEIL C编译器常见警告与错误信息的解决办法
- 腾讯视频采集规则+发布模块(基于火车头全站采集与发布站点教程)
- 视频教程-Kali Linux 网络安全渗透测试-渗透测试
- unraid教程贴备忘