ID Token - JWT

我们来继续前两章(OAuth2 总结, 对OpenID Connect的理解)的讨论,进入对JWT的理解。先来简单回顾一下OAuth2和OpenID:

  1. OAuth 2.0 is a specification as to how to issue access tokens
  2. OpenID Connect is a specification as to how to issue ID tokens.

OpenID建立在OAuth之上,完成了认证和授权。而认证和授权的结果就体现在这个ID token之上,而这个ID token通常会是JWT。那么为什么会是JWT呢?我们通过以下几点来逐一解释。

那么既然要体现认证和授权,这个token中应该含有如下信息:

{
  "name": "sashimi",
  "id": "12345",
  "role": "admin",
  "nbf": "some timestamp"
}

JWTRFC 7519 给出了官方定义的一些字段:

  • iss - Issuer 签发人
  • sub - Subject 主题
  • aud - Audience 受众
  • exp - Expiration 过期时间
  • nbf - Not Before 生效时间
  • iat - Issued At 签发时间
  • jti - JWT ID 编号

当然也不限于此,可以根据自己的需要,添加其他字段。到此,我们可以看出JWT提供了ID token所需要的能力。一个完整的JTW是由三部分组成:Header,Payload,Signature。三者之间由.隔开,刚才提到的认证授权的字段就存在于Payload中。
Header中存放的是JTW的元数据,包含签名的算法以及token的类型,如下所示:

{
  "alg": "HS256",
  "typ": "JWT"
}

Signature部分是对前两部分的签名,防止数据篡改。首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

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

算出签名以后,把 Header、Payload、Signature三个部分经过base64序列化为三个字符串,再讲三个字符串由.为间隔拼接成一个字符串返回给客户端。

安全性

ID Token需要有足够的安全性,JWT是如何做到的呢?
刚看到了签名部分,签名的作用只是为了防止数据篡改,而JWT默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。比如认证服务器中使用私钥进行加密,把公钥分发给其他应用服务器,应用服务拿到加密后的token后用公钥解密,获取到JWT,再用签名的秘钥来验证数据是否经过的篡改。

其他备选?

我们来看看还有神马其他备选么?Simple Web Tokens (SWT)和Security Assertion Markup Language Tokens (SAML)。
JWT vs SAML:JWT基于json,而SAML基于XML,在大小上就有足够的优势,更适用于HTML和HTTP。
JWT vs SWT:在安全性上,SWT只支持对称加密,而JWT和SAML支持公私钥的加密方式。

到这里是不是可以看出JWT的优势呢~ OpenID connect + JWT 可以说是现在SSO的方案的一个重要备选方案。

题外话

作为一个mobile developer,也想在这里对比一下原先的简单token模式和SSO中的JWT:
在没有该机制前,我们通常会使用一个随机产生的字符串作为token,认证成功后返回给前端,之后前端的每个请求带上这个token。若后台服务的是个单体应用没有什么问题,请求来了,验证一下token是否有效即可,但当认证服务和其他的应用服务是分离的,怎么做呢?应用服务受到请求,再向认证服务发起一个请求来验证验证token是否合法,是否有权限访问该应用服务。这样做到没有什么问题,只是当服务变多时,比如微服务下,势必会造成认证服务器的压力过大。
在使用该机制后,客户端通过认证服务登录,获得这个JWT,之后其他应用服务自身便可以验证这个token的是否有效,是否有权访问。

看似完美,但也有它自身的问题,我们来看一个场景:权限变更。某用户原先是一个超级管理员,可以访问所有服务,并可进行任意的删除,更改操作,他在这个状态下拿到了JWT。随后,由于权限更改为普通管理员,便不应该具有所有权限,但此时他开始时的JWT被缓存在客户端仍然可用,其他应用服务也并无法知道这个用户的权限已经被更改,后果可想而知了。解决的方式无非是将这个token的有效时间设置的短一些。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前言 本文将首先概述基于cookie的身份验证方式和基于token的身份验证方式,在此基础上对两种验证进行比较。最...
    大蟒传奇阅读 38,677评论 16 285
  • 在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们...
    NewForMe阅读 11,829评论 0 5
  • 1. SAML断言 断言是一个包含零个或更多个由SAML权威做出的声明的信息包。 SAML断言通常与由 元素表示的...
    WebSSO阅读 5,303评论 0 1
  • 诗人眼中,四季都是美的。 尤其秋天。 虽然我不是诗人, 文采也一般, 但我有一双发现美的眼睛。 今天立冬。 办公桌...
    平凡中的淡然阅读 2,271评论 0 0
  • [1]根据我的推算,父亲学会骑自行车时候大概有五十五六岁了。 在上世纪八十年代,“三转一响”本来是一个家庭的奢侈品...
    杨木艺阅读 5,229评论 0 18

友情链接更多精彩内容