拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 用Java解码JWT令牌

用Java解码JWT令牌

白鹭 - 2021-11-24 577 0 0

1.概述

REST API安全性中经常使用JSON Web令牌(JWT)。尽管可以通过诸如Spring Security OAuth之类的框架来解析令牌,但我们还是希望以自己的代码处理令牌。

在本教程中,我们将译码并验证JWT的完整性

2. JWT令牌的结构

首先,让我们了解一下JWT令牌的结构:

  • 标头
  • payload (通常称为主体)
  • 签名

签名是可选的。有效的JWT令牌只能由标头和有效负载部分组成。但是,我们使用签名部分来验证标头和有效负载中安全授权的内容。

这些部分表示为以句点(‘.')分隔的base64编码字符串。通过设计,任何人都可以译码JWT令牌并读取标头和有效负载部分的内容。但是,我们需要访问用于创建签名的密钥以验证令牌的完整性。

最常见的是,JWT包含用户的“声明”。这些代表有关用户的数据,API可以使用这些数据来授予权限或跟踪提供令牌的用户。译码令牌可以使应用程序使用数据,而验证则可以使应用程序相信JWT是由受信任的源生成的。

让我们看看如何在Java中译码和验证令牌。

3.译码JWT令牌

我们可以使用内置的Java函数译码令牌。

首先,让我们将令牌分为几个部分:

String[] chunks = token.split("\\.");

我们应该注意,传递给String.split的正则表达式使用转义的'.'避免使用'。'的字符。意思是“任何字符”。

我们的chunks数组现在应该具有2或3个与JWT的部分相对应的元素。

接下来,让我们使用base64译码器对标头和有效负载部分进行译码:

Base64.Decoder decoder = Base64.getDecoder();



 String header = new String(decoder.decode(chunks[0]));

 String payload = new String(decoder.decode(chunks[1]));

让我们使用JWT令牌运行以下代码(我们可以在线译码以比较结果):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE

输出将为我们提供译码后的标头任何有效载荷:

{"alg":"HS256","typ":"JWT"} {"sub":"1234567890","name":"Baeldung User","iat":1516239022}

如果仅在JWT令牌中定义了标头和有效载荷部分,那么我们就可以完成并成功译码信息。

4.验证JWT令牌

接下来,我们可以验证标头和有效负载的完整性,以确保没有通过使用签名部分来更改它们。

4.1 依赖关系

为了进行验证,我们可以将jjwt添加到我们的pom.xml

<dependency>

 <groupId>io.jsonwebtoken</groupId>

 <artifactId>jjwt</artifactId>

 <version>0.7.0</version>

 </dependency>

我们应该注意,我们需要从版本0.7.0开始的该库版本。

4.2 配置签名算法和密钥规范

要开始验证有效负载和报头,我们既需要使用最初用于对令牌进行签名的签名算法,也需要密钥:

SignatureAlgorithm sa = HS256;

 SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName());

在此示例中,我们已将签名算法硬编码为HS256.但是,我们可以译码标头的JSON并读取alg字段以获取此值。

我们还应该注意,变量secretKey是密钥的String表示形式。我们可以通过其配置或通过发布JWT的服务公开的REST API将其提供给我们的应用程序。

4.3 执行验证

现在我们有了签名算法和密钥,我们可以开始执行验证了。让我们将标头和有效负载重组到一个未签名的JWT中,并用“.”将它们连接起来。分隔符:

String tokenWithoutSignature = chunks[0] + "." + chunks[1];

 String signature = chunks[2];

现在我们有了未签名的令牌和提供的签名。我们可以使用该库进行验证:

DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);



 if (!validator.isValid(tokenWithoutSignature, signature)) {

 throw new Exception("Could not verify JWT token integrity!");

 }

让我们分解一下。

首先,我们使用所选的算法和密码创建一个验证器。然后,我们为其提供未签名的令牌数据和所提供的签名。

然后。验证器将生成一个新签名,并将其与提供的签名进行比较。如果它们相等,那么我们已经验证了报头和有效载荷的完整性。

5.结论

在本教程中,我们研究了JWT的结构以及如何将其译码为JSON。
然后,我们使用一个库来使用其签名,算法和秘密密钥来验证令牌的完整性。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *