.Net Core官方的 JWT 授权验证
什么是JWT?
JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为JSON对象。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对对JWT进行签名。
尽管可以对JWT进行加密以提供双方之间的保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏在其他方的面前。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。由于缺乏安全性,所以不能把如密码等敏感信息放在令牌中。
什么时候应该使用JWT?
以下是JSON Web令牌有用的一些情况:
授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。
信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。
JWT结构是什么?
JSON Web令牌以紧凑的形式由三部分组成,这些部分由点(.
)分隔,分别是:
- 标头
- 有效载荷
- 签名
因此,JWT通常如下所示。
xxxxx.yyyyy.zzzzz
标头:通常由两部分组成,令牌类型和使用的签名算法。
{
"alg": "HS256",
"typ": "JWT"
}
有效载荷:有三种说明类型,预定义声明、公共声明和私有声明。声明名称仅是三个字符,因为JWT是紧凑的
- 预定义声明:包括iss(发出者), exp(到期时间), sub(主题), aud(受众)等,是推荐的但是不是强制的可以没有。
- 公共声明:公共声明,这个部分可以随便定义,但是要注意和 IANA JSON Web Token 冲突。
- 私有声明:这个部分是共享被认定信息中自定义部分。
签名:要创建签名部分,您必须获取编码的标头,编码的有效负载,机密,标头中指定的算法,并对其进行签名。
例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名用于验证消息在此过程中没有更改,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者是它所说的真实身份。
组合在一起如下为输出是三个由点分隔的Base64-URL字符串:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUyMDAiLCJhdWQiOlsiYXBpIiwiYXBpIl0sIkd1aWQiOiIzM2NhZmJkNS1jZWEyLTRjOWMtYWZlYS01MDYyZjM3YWUyOTAiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOlsic3lzdGVtIiwiYWRtaW4iXSwiZXhwIjoxNjA2NjU2NjI0fQ.
JvDHuowbOnWiyxMIFc9gG5rw1LSSc0xx68L31oRfxS0
如何使用JWT
每当用户想要访问受保护的路由或资源时,用户代理都应发送JWT,通常使用承载模式在Authorization标头中发送JWT 。标头的内容应如下所示:
Authorization: Bearer <token>
在某些情况下,这可以是无状态授权机制。服务器的受保护路由将在Authorization
标头中检查有效的JWT ,如果存在,则将允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库中某些操作的需求,尽管这种情况并非总是如此。
如果令牌是在Authorization
标头中发送的,则跨域资源共享(CORS)不会成为问题,因为它不使用cookie。
下图显示了如何获取JWT并将其用于访问API或资源:
- 应用程序或客户端向授权服务器请求授权。这是通过不同的授权流程之一执行的。例如,典型的符合OpenID Connect的Web应用程序将
/oauth/authorize
使用授权代码流通过端点。 - 授予授权后,授权服务器会将访问令牌返回给应用程序。
- 该应用程序使用访问令牌来访问受保护的资源(例如API)。
请注意,使用签名的令牌,令牌中包含的所有信息都会暴露给用户或其他方,即使他们无法更改它。这意味着您不应将机密信息放入令牌中。
.net core的JWT验证授权
我们直接新建一个.net core webapi的项目,我这里版本是3.1的
1. 先使用nuget安装:Microsoft.AspNetCore.Authentication.JwtBearer。注意版本和.net core版本的兼容。net5的支持5.0.0+的版本,否则就用对应可以用的低版本吧。
2. 在appsettings.json配置文件中写好我们的 JWT 的配置参数如下:
"Jwt": {
"Secret": "your-256-bit-secret",
"Iss": "https://localhost:44355",
"Aud": "api"
}
3. 在Startup.cs的ConfigureServices方法中添加授权认证如下:
var jwtConfig = Configuration.GetSection("Jwt");
//生成密钥
var symmetricKeyAsBase64 = jwtConfig.GetValue<string>("Secret");
var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
var signingKey = new SymmetricSecurityKey(keyByteArray);
//认证参数
services.AddAuthentication("Bearer")
.AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,//是否验证签名,不验证的画可以篡改数据,不安全
IssuerSigningKey = signingKey,//解密的密钥
ValidateIssuer = true,//是否验证发行人,就是验证载荷中的Iss是否对应ValidIssuer参数
ValidIssuer = jwtConfig.GetValue<string>("Iss"),//发行人
ValidateAudience = true,//是否验证订阅人,就是验证载荷中的Aud是否对应ValidAudience参数
ValidAudience = jwtConfig.GetValue<string>("Aud"),//订阅人
ValidateLifetime = true,//是否验证过期时间,过期了就拒绝访问
ClockSkew = TimeSpan.Zero,//这个是缓冲过期时间,也就是说,即使我们配置了过期时间,这里也要考虑进去,过期时间+缓冲,默认好像是7分钟,你可以直接设置为0
RequireExpirationTime = true,
};
});
在Configure方法中添加 app.UseAuthentication() 和 app.UseAuthorization() 注意位置需要放置的位置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>{ endpoints.MapControllers();});
}
4. 生成jwt令牌,在默认生成的控制器 WeatherForecastController 中添加如下生成令牌的方法:
[HttpPost]
public IActionResult Authenticate()
{
var jwtConfig = Configuration.GetSection("Jwt");
//秘钥,就是标头,这里用Hmacsha256算法,需要256bit的密钥
var securityKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.GetValue<string>("Secret"))), SecurityAlgorithms.HmacSha256);
//Claim,JwtRegisteredClaimNames中预定义了好多种默认的参数名,也可以像下面的Guid一样自己定义键名.
//ClaimTypes也预定义了好多类型如role、email、name。Role用于赋予权限,不同的角色可以访问不同的接口
//相当于有效载荷
var claims = new Claim[] {
new Claim(JwtRegisteredClaimNames.Iss,jwtConfig.GetValue<string>("Iss")),
new Claim(JwtRegisteredClaimNames.Aud,jwtConfig.GetValue<string>("Aud")),
new Claim("Guid",Guid.NewGuid().ToString("D")),
new Claim(ClaimTypes.Role,"system"),
new Claim(ClaimTypes.Role,"admin"),
};
SecurityToken securityToken = new JwtSecurityToken(
signingCredentials: securityKey,
expires: DateTime.Now.AddMinutes(2),//过期时间
claims: claims
);
//生成jwt令牌
return Content(new JwtSecurityTokenHandler().WriteToken(securityToken));
}
5. 使用jwt控制接口的访问,我们在一个接口上添加一个特性 [Authorize(Roles ="admin")],表示需要有admin这个角色的jwt令牌才能访问,没有roles参数的话表示只要是可用的令牌就可以访问,多个role角色可以叠加多个特性:
[HttpGet]
[Authorize(Roles = "admin")]
[Authorize(Roles = "system")]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
6.测试,然后我们用postman就可以测试了,可以看到非常成功有数据。
进阶
认证的时候可以添加事件,如下面的认证失败事件、接收参数事件可以获取url上的参数作为令牌而不是通过http的请求头的Authorization。
services.AddAuthentication("Bearer")
.AddJwtBearer(o =>
{
o.Events = new JwtBearerEvents()
{
OnMessageReceived = context =>
{
context.Token = context.Request.Query["access_token"];
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
// 如果过期,则把<是否过期>添加到,返回头信息中
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
.Net Core官方的 JWT 授权验证的更多相关文章
- 【从零开始搭建自己的.NET Core Api框架】(四)实战!带你半个小时实现接口的JWT授权验证
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- ASP.NET CORE API Swagger+IdentityServer4授权验证
简介 本来不想写这篇博文,但在网上找到的文章博客都没有完整配置信息,所以这里记录下. 不了解IdentityServer4的可以看看我之前写的入门博文 Swagger 官方演示地址 源码地址 配置Id ...
- asp.core 同时兼容JWT身份验证和Cookies 身份验证两种模式
在实际使用中,可能会遇到,aspi接口验证和view页面的登录验证情况.asp.core 同样支持两种兼容. 首先在startup.cs 启用身份验证. var secrityKey = new Sy ...
- NetCoreApi框架搭建三、JWT授权验证)
1.首先还是粘贴大神的链接 虽然说大神的博客已经讲得很详细了,但是此处还是自己动手好点. 首先配置Startup Swagger的验证 2.新建一个项目存放tokenmodel和生成token并且存入 ...
- ASP.NET Core搭建多层网站架构【10-使用JWT进行授权验证】
2020/01/31, ASP.NET Core 3.1, VS2019, Microsoft.AspNetCore.Authentication.JwtBearer 3.1.1 摘要:基于ASP.N ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十四║ Vuex + JWT 实现授权验证登录
壹周回顾 哈喽,又是元气满满的一个周一,又与大家见面了,周末就是团圆节了,正好咱们的前后端也要团圆了,为什么这么说呢,因为以后的开发可能就需要前后端一起了,两边也终于会师了,还有几天Vue系列就基本告 ...
- .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证
.Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...
- ASP.NET Core WebApi基于JWT实现接口授权验证
一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...
- asp.net core 3.1多种身份验证方案,cookie和jwt混合认证授权
开发了一个公司内部系统,使用asp.net core 3.1.在开发用户认证授权使用的是简单的cookie认证方式,然后开发好了要写几个接口给其它系统调用数据.并且只是几个简单的接口不准备再重新部署一 ...
随机推荐
- android 下的 handler Message
研究了下android下的 handler message 实现原理: new handler() 的时候 从ThreadLocal里面 获取当前线程下的 Looper实例下的 MessageQu ...
- 4G DTU数据传输终端的功能介绍
4G DTU是基于4G网络的自动化数据传输终端,是一种物联网无线数据传输设备,使用公用运营商的4G网络为用户提供无线远距离数据传输功能,使用工业级32位的高性能通信处理器和工业级无线模块,以嵌入式实时 ...
- Java学习的第三十天
1.遇到打印文件使用打印流PrintStream 使用PrintStream写入数据 2.没有问题 3.明天学习用RandomAccessFile随机访问文件
- Java中的微信支付(3):API V3对微信服务器响应进行签名验证
1. 前言 牢记一句话:公钥加密,私钥解密:私钥加签,公钥验签. 微信支付V3版本前两篇分别讲了如何对请求做签名和如何获取并刷新微信平台公钥,本篇将继续展开如何对微信支付响应结果的验签. 2. 为什么 ...
- 835. Image Overlap —— weekly contest 84
Image Overlap Two images A and B are given, represented as binary, square matrices of the same size. ...
- SSM实现文件上传
1.导入上传需要的jar包 commons-fileupload-1.3.3.jar commons-io-2.6.jar 2.创建 index.jsp <%@ page contentType ...
- MySQL全面瓦解6:查询的基本操作
概述 提到查询,就回到我们第四篇的SQL语言分类了,DQL(Data QueryLanguage),也就是数据查询语言,实际就是从数据库中获取数据的一种命令方式.我们给数据库发送一个查询语句的命令,数 ...
- 简单red5+obs推流实现直播系统开发,具体设置介绍
前言:随便搞搞,先放一张效果图,
- MySql Binlog 说明 & Canal 集成MySql的更新异常说明 & MySql Binlog 常用命令汇总
文章来源于本人的印象笔记,如出现格式问题可访问该链接查看原文 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录 背景介绍 开启MySq ...
- 二:Tomcat与登录
在使用Tomcat部署服务器之前我们需要写一个页面登录的HTML文本 该文本如下 <!DOCTYPE html> <html> <head> <meta ch ...