[01-jwt]C# JWT基础知识详解

本文章内容翻译自JWT官网,并融入了部分笔者的思想内容。希望给其他小伙伴在学习这部分内容时带来一定的帮助。

一、什么是JWT?

JWT是简写,全称是JSON Web Token。

JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑(Compact)自包含(Self-contained)的方式,用于在各方之间以JSON对象的形式安全传输信息。此信息可以验证和信任,因为它是经过数字签名的。JWT可以使用密钥(使用HMAC算法)或使用RSAECDSA的公钥/私钥对进行签名。

下面进一步解释这个定义中的一些概念:

·紧凑(Compact):由于它的大小,它可以通过 URL、POST 参数或 HTTP 标头内部发送。此外,由于它的大小,它的传输速度很快。

·自包含(Self-contained):有效载荷(后面介绍)中包含有关用户的所有必需信息,可以避免多次查询数据库。

虽然JWT可以加密以在各方之间提供保密性,但我们将重点专注于签名令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌会向其他方隐藏这些声明。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是签署它的一方。

二、什么时候应该使用 JSON Web Token?

以下是一些JSON Web token非常有用的场景:

  1. 授权(Authorization):这是使用JWT最常见的场景。用户登录后,每个后续请求都将包含JWT,从而允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用JWT的一项功能,因为它的开销很小,并且能够在不同的域中轻松使用。
  2. 信息交换(Information Exchange):JSON Web Token是在各方之间安全传输信息的好方法。因为可以对 JWT 进行签名(例如,使用公钥/私钥对),所以您可以确定发件人就是他们所说的那个人。此外,由于使用标头有效载荷计算签名,您还可以验证该令牌内容有没有被篡改过。

三、JSON Web Token 结构是什么?

JWT的结构是紧凑的(之前在第一部分定义中说过),在其紧凑的形式中,JSON Web token由三部分组成,三部分由点(.)分隔,它们是:

  • 标头(Header)
  • 有效载荷(Payload)
  • 签名(Signature)

因此,JWT结构通常如下所示:

xxxxx.yyyyy.zzzzz

接下来,让我们把不同的部分分解一下。

1、标头(Header)

标头通常由两部分组成:

  1. 令牌的类型,即JWT
  2. 正在使用的签名算法,例如HMAC SHA256或RSA。

例如:

{
    "alg": "HS256",  //签名算法

    "typ": "JWT"  //类型
}

然后,对标头这个 JSON进行Base64Url编码,用以形成 JWT 的第一部分

2、有效载荷(Payload)

令牌的第二部分是有效载荷,其中包含声明。声明是关于实体(通常是用户)和附加数据的陈述。声明分为三种类型:

  1. 注册(registered)声明
  2. 公开(public)声明
  3. 私有(private )声明
  • 注册声明(Registered claims):这些是一组预定义的声明,它们不是强制性的,但建议使用,以提供一组有用的、可互操作的声明。其中一些是: iss(发行人) exp(到期时间) sub(主题)aud(受众)等。
请注意,声明名称只有三个字符长,因为JWT是紧凑的。
  • 公开声明(Public claims):这些可以由使用 JWT 的人随意定义。但是为了避免冲突,它们应该在IANA JSON Web Token Registry中定义,或者定义为包含抗冲突命名空间的 URI。
  • 私人声明(Private claims):这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公共声明。

一个有效载荷的示例可能是下面这个样子:

{
    "iss": "xx网站",  //发行人

    "name": "张欧昊辰",  //全名

    "email": "mwstars@163.com",   //邮箱

    "admin": true  //是否是管理员
}

然后,对有效载荷这个JSON进行Base64Url编码,用以形成 JWT的第二部分

  • 请注意,对于已签名的令牌,此信息虽然受到保护以防篡改,但任何人都可以读取。除非已加密,否则请勿将机密信息放入 JWT 的有效载荷或标头元素中。

3、签名(Signature)

要创建签名部分,必须获取编码的标头、编码的有效载荷、密钥、标头中指定的算法,并对其进行签名。

例如,如果想使用 HMAC SHA256 算法,签名将通过以下方式创建:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

签名用于验证消息在此过程中有没有被更改过,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者就是它所说的那个人。

4、把所有的放在一起

输出是三个用点分隔的 Base64-URL 字符串,可以在 HTML 和 HTTP 环境中轻松传递,同时与基于 XML 的标准(如 SAML)相比更紧凑。

下面显示了一个 JWT,该 JWT 具有先前的标头和有效载荷编码,并使用密钥签名。

四、JSON Web Token是如何工作?

在身份验证中,当用户使用其凭据成功登录时,将返回一个 JSON Web Token。由于令牌是凭据,因此必须非常小心以防止出现安全问题。通常,不应将令牌保留超过所设置的过期时间。

由于缺乏安全性,也不应该在浏览器存储中存储敏感的会话数据。

每当用户想要访问受保护的路由或资源时,用户代理应该发送 JWT,通常在Authorization标头中使用Bearer模式。

标头的内容应如下所示:

Authorization: Bearer <token>

在某些情况下,这可以是一种无状态授权验证机制,因为用户状态永远不会保存在服务器内存中。服务器的受保护路由将检查Authorization标头中是否存在有效的 JWT,如果存在,则允许用户访问受保护的资源。由于 JWT 是自包含的,所有必要的信息都在那里,减少了返回和转发到数据库的需要。

这允许完全依赖无状态的数据 API,甚至可以向下游服务发出请求。如果令牌在Authorization标头中发送,则跨域资源共享 (CORS) 不会成为问题,因为它不使用 cookie。

JSON Web 令牌的工作原理

特别注意,使用签名令牌时,令牌中包含的所有信息都会向用户或其他方公开,即使他们无法更改,这也并不意味着可以将敏感信息或者秘密信息等放入令牌中。

五、为什么我们应该使用 JSON Web Token?

下面我们谈一谈JSON Web Tokens (JWT)Simple Web Tokens (SWT)Security Assertion Markup Language Tokens (SAML)相比的优势:

  1. 由于 JSON 不像 XML 那样冗长,因此在对其进行编码时,它的大小也更小,这使得 JWT 比 SAML 更紧凑。这使得 JWT 成为在 HTML 和 HTTP 环境中传递的不错选择。
  2. 安全方面,SWT 只能通过使用 HMAC 算法的共享密钥进行对称签名。但是,JWT 和 SAML 令牌可以使用 X.509 证书形式的公钥/私钥对进行签名。与签署 JSON 的简单性相比,使用 XML 数字签名签署 XML 而不引入隐蔽的安全漏洞是非常困难的。
  3. JSON 解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML 没有自然的文档到对象映射。这使得使用 JWT 比使用 SAML 断言更容易。
  4. 关于使用,JWT 用于 Internet 规模。这突出了 JSON Web Token在多个平台(尤其是移动平台)上客户端处理的便利性。

 下图为编码的 JWT 和编码的 SAML 的长度比较。

比较编码的 JWT 和编码的 SAML 的长度


The End……

posted @ 2022-02-11 16:21  张欧昊辰  阅读(531)  评论(0编辑  收藏  举报