JJWT相关笔记

JWT构成

JWT是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串 第一部分称为头部(header),第二部分称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

header

jwt的头部承载两部分信息:声明类型,这里是jwt、声明加密的算法(通常直接使用 HMAC SHA256)。对其进行base64加密(可以是对称加密),得到第一部分

payload

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:标准中注册的声明、公共的声明、私有的声明。对其进行base64加密,得到第二部分

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择(标准中注册的声明)

  • iss: jwt签发者
  • sub: jwt所面向,使用jwt的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须大于签发时间
  • nbf: 定义在指定时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

除以上默认字段外,还可以自定义私有字段,可以用来存一些必要但非敏感的信息

对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将重要信息放入JWT的有效负载或报头元素中(header和payload都是base64编码。盐secret是用于签名的,所以前面两部分没太大的安全性)

载荷部分存在两个属性:payload和claims。两个属性均可作为载荷,jjwt中二者只能设置其一,如果同时设置,在终端方法compact() 中将抛出异常

signature

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:header (base64后的)、payload (base64后的)、secret(盐,不可泄漏)。

base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,就构成了jwt的第三部分。

JWT特点

JWT的特点是无状态的,所以无法解决主动过期及续期的问题(续期实际上是重新颁发token)

JwtBuilder

String jwt = Jwts.builder()
 // 这里指定了加密算法和盐secret
      .signWith(secret, SignatureAlgorithm.HS512)
  // 加入ID确保生成的 Token 都不一致
      .setId(IdUtil.simpleUUID())
  // 配置私有的声明。解密后可通过jwt.get()获取
      .claim(AUTHORITIES_KEY, authentication.getName())
  // 这个就是上面的sub。还可以设置些别的。在将jwt解密出claim后,可通过claims.getSubject()获取
      .setSubject(authentication.getName())
  // 设置颁发时间
      .setIssuedAt(curDate)
  // 设置过期时间,
    // .setExpiration(expirationDate)
      .compact();

compact() 生成JWT。过程如下:

  1. 载荷校验,如果builder中Claims属性为空,则创建DefaultClaims对象,并把键值放入;如果Claims属性不为空,获取之后判断键值,存在则更新,不存在则直接放入。
  2. 获取key。如果是keyBytes则通过keyBytes及算法名生成key对象。
  3. 将所使用签名算法写入header。如果使用压缩,将压缩算法写入header。
  4. 将Json形式的header转为bytes,再Base64编码
  5. 将Json形式的claims转为bytes,如果需要压缩则压缩,再进行Base64编码
  6. 拼接header和claims。如果签名key为空,则不进行签名(末尾补分隔符” . “);如果签名key不为空,以拼接的字符串作为参数,按照指定签名算法进行签名计算签名部分 sign(String jwtWithoutSignature),签名部分同样也会进行Base64编码。
  7. 返回完整JWT

jjwt实现的 DefaultJwtSigner 提供了一个带工厂参数的构造方法。并将jjwt实现的 DefaultSignerFactory静态实例传入,根据不同的签名算法创建对应的签名器进行签名。

有关配置构建器的信息。使用指定的元素和属性来构建令牌。

NameTypeDefaultDescription
audiencesstring要包含在 JSON Web 令牌的受众声明中的可信受众列表。
claimsstring指定要包含在令牌中的声明的逗号分隔列表。具体见上面载荷部分
contentEncryptionAlgorithmA256GCM指定加密算法,用于将 JWT 纯文本加密以生成 JWE 密文。 A256GCM 将 AES GCM 算法与 256 位的密钥配合使用,以将 JWE 的 JWT 纯文本加密。
expiresInSeconds具有秒精度的时间段-1指示令牌到期时间(按秒计)。优先于到期。. 指定后跟时间单位的正整数,时间单位可以是小时 (h)、分钟 (m) 或秒 (s)。例如,以 30s 的形式指定 30 秒。可将多个值包括在单个条目中。例如,1m30s 相当于 90 秒。
expiry具有小时精度的时间段2h指示令牌到期时间(按小时计)。优先使用 ExpiresInSeconds(如果存在)。. 指定后跟时间单位的正整数,时间单位可以是小时 (h)。例如,以 12h 的形式指定 12 小时。
idstringdefaultJWT此标识用来标识 JWT 构建器。如果未指定标识值,那么不会处理构建器。该标识必须是 URL-safe 字符串。如果未指定颁发者配置属性,那么该标识用作颁发者值的一部分。JwtBuilder API 使用此标识来确定要用来构造 JWT 的构建器配置。
issuerstring颁发者是使用 HTTP 或 HTTPS 方案的 URL(区分大小写),其中包含方案、主机及(可选的)端口号和路径部分。
jti布尔型false指示是否生成令牌的唯一标识。
jwkEnabled布尔型false指示是否使用 JWK 对令牌进行签名。
keyAliasstring密钥别名,用于查找使用非对称算法对令牌进行签名所需的专用密钥。
keyManagementKeyAlgorithmRSA-OAEP指定加密算法,用于将 JWE 的内容加密密钥加密。 RSA-OAEP 使用 RSAES OAEP 算法可将 JWE 的内容加密密钥加密。
keyManagementKeyAliasstring这是密钥管理密钥的公用密钥别名,用于将 JWE 的内容加密密钥加密。
keyStoreRef对顶级 keyStore 元素的引用(字符串)。密钥库,包含使用非对称算法对令牌进行签名所必需的专用密钥。
nbfOffset具有秒精度的时间段-1标识接受 JWT 以进行处理时的时间。值必须为 NumericDate 对象。. 指定后跟时间单位的正整数,时间单位可以是小时 (h)、分钟 (m) 或秒 (s)。例如,以 30s 的形式指定 30 秒。可将多个值包括在单个条目中。例如,1m30s 相当于 90 秒。
scopestring指定 OAuth 作用域的空格分隔列表。
sharedKey可逆向编码的密码(字符串)指定将用于生成共享密钥的字符串。可采用明文或更安全的编码格式存储该值。请将 securityUtility 工具与编码选项配合使用以对共享密钥进行编码。
signatureAlgorithmES256ES384ES512HS256HS384HS512RS256RS384RS512RS256指定将用于对 JWT 令牌进行签名的签名算法。 ES256 ES384 ES512 HS256 HS384 HS512 RS256 RS384 RS512
trustStoreRef对顶级 keyStore 元素的引用(字符串)。密钥库,包含在验证 JWT 令牌的签名时必需的公用密钥。

Leave a Reply

Your email address will not be published. Required fields are marked *

lWoHvYe 无悔,专一