.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或资源:

  1. 应用程序或客户端向授权服务器请求授权。这是通过不同的授权流程之一执行的。例如,典型的符合OpenID Connect的Web应用程序将/oauth/authorize使用授权代码流通过端点。
  2. 授予授权后,授权服务器会将访问令牌返回给应用程序。
  3. 该应用程序使用访问令牌来访问受保护的资源(例如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官方JWT授权验证内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ASP.NET Core学习之使用JWT认证授权详解

    概述 认证授权是很多系统的基本功能 , 在以前PC的时代 , 通常是基于cookies-session这样的方式实现认证授权 , 在那个时候通常系统的用户量都不会很大, 所以这种方式也一直很好运行, 随着现在都软件用户量越来越大, 系统架构也从以前垂直扩展(增加服务器性能) -> 水平扩展(增加服务器数量) cookies-session 工作方式 客户端提交用户信息 -> 服务器识别用户 -> 服务端保存用户信息 -> 返回session-id客户端 -> 客户端保存ses

  • Asp.Net Core基于JWT认证的数据接口网关实例代码

    前言 近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对前后端分离的数据服务支持,于是想到我一直做.Net开发,问我是否对.Net Core有所了解?能不能做个简单Demo出来看看?我说,分道扬镳之后我不是调用别人的接口就是提供接口给别人调用,于是便有了以下示例代码. 示例要求能演示获取Token及如何使用该Token访问数据资源,在Demo中实现

  • .NET core 3.0如何使用Jwt保护api详解

    摘要: 本文演示如何向有效用户提供jwt,以及如何在webapi中使用该token通过JwtBearerMiddleware中间件对用户进行身份认证. 认证和授权区别? 首先我们要弄清楚认证(Authentication)和授权(Authorization)的区别,以免混淆了.认证是确认的过程中你是谁,而授权围绕是你被允许做什么,即权限.显然,在确认允许用户做什么之前,你需要知道他们是谁,因此,在需要授权时,还必须以某种方式对用户进行身份验证. 什么是JWT? 根据维基百科的定义,JSON WE

  • 浅谈ASP.NET Core 中jwt授权认证的流程原理

    1,快速实现授权验证 什么是 JWT ?为什么要用 JWT ?JWT 的组成? 这些百度可以直接找到,这里不再赘述. 实际上,只需要知道 JWT 认证模式是使用一段 Token 作为认证依据的手段. 我们看一下 Postman 设置 Token 的位置. 那么,如何使用 C# 的 HttpClient 访问一个 JWT 认证的 WebAPI 呢? 下面来创建一个 ASP.NET Core 项目,尝试添加 JWT 验证功能. 1.1 添加 JWT 服务配置 在 Startup.cs 的 Confi

  • ASP.NET Core使用JWT认证授权的方法

    demo地址: https://github.com/william0705/JWTS 名词解析 认证 : 识别用户是否合法 授权: 赋予用户权限 (能访问哪些资源) 鉴权: 鉴定权限是否合法 Jwt优势与劣势 优势 1. 无状态 token 存储身份验证所有信息 , 服务端不需要保存用户身份验证信息, 减少服务端压力 , 服务端更容易水平扩展, 由于无状态, 又会导致它最大缺点 , 很难注销 2. 支持跨域访问 Cookie是不允许垮域访问的,token支持 3. 跨语言 基于标准化的 JSO

  • 利用JWT如何实现对API的授权访问详解

    什么是JWT JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各个系统之间用JSON作为对象安全地传输信息,并且可以保证所传输的信息不会被篡改. 「JWT」由三部分构成 信息头:指定了使用的签名算法 声明部分:其中也可以包含超时时间 基于指定的算法生成的签名 通过这三部分信息,API 服务端可以根据「JWT」信息头和声明部分的信息重新生成签名.之所以可以这样做,是因为生成签名需要的秘钥存放在服务器端. jwtauth.New("HS2

  • .net core webapi jwt 更为清爽的认证详解

    我的方式非主流,控制却可以更加灵活,喜欢的朋友,不妨花一点时间学习一下 jwt认证分为两部分,第一部分是加密解密,第二部分是灵活的应用于中间件,我的处理方式是将获取token放到api的一个具体的controller中,将发放token与验证分离,token的失效时间,发证者,使用者等信息存放到config中. 1.配置: 在appsettings.json中增加配置 "Jwt": { "Issuer": "issuer",//随意定义 &quo

  • asp net core 2.1中如何使用jwt(从原理到精通)

    为什么使用 Jwt 最近,移动开发的劲头越来越足,学校搞的各种比赛都需要用手机 APP 来撑场面,所以,作为写后端的,很有必要改进一下以往的基于 Session 的身份认证方式了,理由如下: 移动端经常要保持长时间(1 到 2 星期)在线,但是 Session 却不好在服务端保存这么久,虽然可以持久化到数据库,但是还是挺费资源 移动端往往不是使用的网页技术,所以藏在 Cookie 里面的 SessionId 不是很方便的传递给服务端 服务端暴露给客户端的接口往往是 RESTful 风格的,这是一

  • asp.net core集成JWT的步骤记录

    [什么是JWT] JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT令牌在api接口中校验用户的身份以确认用户是否有访问api的权限. JWT中包含了身份认证必须的参数以及用户自定义的参数,JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名. [什么时候应该使用JSON Web令牌?] 授权:这是使用JWT的最常见方案.一旦用户登录

  • ASP.Net Core3.0中使用JWT认证的实现

    JWT认证简单介绍 关于Jwt的介绍网上很多,此处不在赘述,我们主要看看jwt的结构. JWT主要由三部分组成,如下: HEADER.PAYLOAD.SIGNATURE HEADER 包含token的元数据,主要是加密算法,和签名的类型,如下面的信息,说明了 加密的对象类型是JWT,加密算法是HMAC SHA-256 {"alg":"HS256","typ":"JWT"} 然后需要通过BASE64编码后存入token中 eyJ

随机推荐