From 65c91c5aef4b74e25e30422b45dc4b491880d972 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 13 Sep 2022 19:17:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96JWT=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=AF=86=E5=88=ABheader=E4=B8=AD=E7=9A=84=E7=AE=97=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=8F=AF=E8=87=AA=E5=AE=9A=E4=B9=89header?= =?UTF-8?q?=E4=B8=ADkey=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/jwt/JWT.java | 17 ++++++-- .../main/java/cn/hutool/jwt/JWTHeader.java | 4 +- .../java/cn/hutool/jwt/IssueI5QRUOTest.java | 39 +++++++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100755 hutool-jwt/src/test/java/cn/hutool/jwt/IssueI5QRUOTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 45c9d46f1..1701441c4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### 🐣新特性 * 【core 】 BooleanUtil的andOfWrap和orOfWrap()忽略null(issue#2599@Github) +* 【jwt 】 优化JWT自动识别header中的算法,并可自定义header中key的顺序(issue#I5QRUO@Gitee) ### 🐞Bug修复 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java b/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java index a8b4e15fd..e7214aa48 100755 --- a/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java +++ b/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java @@ -112,12 +112,17 @@ public class JWT implements RegisteredPayload { } /** - * 设置密钥,默认算法是:HS256(HmacSHA256) + * 设置密钥,如果头部指定了算法,直接使用,否则默认算法是:HS256(HmacSHA256) * * @param key 密钥 * @return this */ public JWT setKey(byte[] key) { + // 检查头信息中是否有算法信息 + final String claim = (String) this.header.getClaim(JWTHeader.ALGORITHM); + if (StrUtil.isNotBlank(claim)) { + return setSigner(JWTSignerUtil.createSigner(claim, key)); + } return setSigner(JWTSignerUtil.hs256(key)); } @@ -309,9 +314,15 @@ public class JWT implements RegisteredPayload { public String sign(JWTSigner signer) { Assert.notNull(signer, () -> new JWTException("No Signer provided!")); + // 检查tye信息 + final String type = (String) this.header.getClaim(JWTHeader.TYPE); + if (StrUtil.isBlank(type)) { + this.header.setClaim(JWTHeader.TYPE, "JWT"); + } + // 检查头信息中是否有算法信息 - final String claim = (String) this.header.getClaim(JWTHeader.ALGORITHM); - if (StrUtil.isBlank(claim)) { + final String algorithm = (String) this.header.getClaim(JWTHeader.ALGORITHM); + if (StrUtil.isBlank(algorithm)) { this.header.setClaim(JWTHeader.ALGORITHM, AlgorithmUtil.getId(signer.getAlgorithm())); } diff --git a/hutool-jwt/src/main/java/cn/hutool/jwt/JWTHeader.java b/hutool-jwt/src/main/java/cn/hutool/jwt/JWTHeader.java index 914f6248f..a63c3d711 100755 --- a/hutool-jwt/src/main/java/cn/hutool/jwt/JWTHeader.java +++ b/hutool-jwt/src/main/java/cn/hutool/jwt/JWTHeader.java @@ -32,9 +32,7 @@ public class JWTHeader extends Claims { /** * 构造,初始化默认(typ=JWT) */ - public JWTHeader() { - setClaim(TYPE, "JWT"); - } + public JWTHeader() {} /** * 增加“kid”头信息 diff --git a/hutool-jwt/src/test/java/cn/hutool/jwt/IssueI5QRUOTest.java b/hutool-jwt/src/test/java/cn/hutool/jwt/IssueI5QRUOTest.java new file mode 100755 index 000000000..45fc07b8e --- /dev/null +++ b/hutool-jwt/src/test/java/cn/hutool/jwt/IssueI5QRUOTest.java @@ -0,0 +1,39 @@ +package cn.hutool.jwt; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class IssueI5QRUOTest { + + @Test + public void createTokenTest(){ + // https://jwt.io/ + + // 自定义header顺序 + final Map header = new LinkedHashMap(){ + { + put(JWTHeader.ALGORITHM, "HS384"); + put(JWTHeader.TYPE, "JWT"); + } + }; + + final Map payload = new LinkedHashMap(){ + { + put("sub", "1234567890"); + put("name", "John Doe"); + put("iat", 1516239022); + } + }; + + final String token = JWTUtil.createToken(header, payload, "123456".getBytes()); + Assert.assertEquals("eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9." + + "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ." + + "3Ywq9NlR3cBST4nfcdbR-fcZ8374RHzU50X6flKvG-tnWFMalMaHRm3cMpXs1NrZ", token); + + final boolean verify = JWT.of(token).setKey("123456".getBytes()).verify(); + Assert.assertTrue(verify); + } +}