Oauth2系列9:JWT令牌各种实现

编程入门 行业动态 更新时间:2024-10-24 04:37:36

Oauth2系列9:JWT<a href=https://www.elefans.com/category/jswz/34/1771317.html style=令牌各种实现"/>

Oauth2系列9:JWT令牌各种实现

传送门

Oauth2系列1:初识Oauth2

Oauth2系列2:授权码模式

Oauth2系列3:接入前准备

Oauth2系列4:密码模式

Oauth2系列5:客户端凭据模式

Oauth2系列6:隐式模式

Oauth2系列7:授权码和访问令牌的颁发流程是怎样实现的?

Oauth2系列8:何谓JWT令牌?

什么是JWT令牌

官方网站地址:JSON Web Tokens - jwt.io

在上一节里面,讨论过jwt令牌。里面给出了各种语言及相对的多种实现。所以这里面就仔细看一下java版本的实现!

JAVA版本的实现

官方版本给出了7个库实现,分别是

  • java-jwt
  • jose4j
  • nimbus-jose-jwt
  • jjwt-root
  • fusionauth-jwt
  • vertx-auth-jwt
  • inverno-security-jose

具体可以查看=Java

jose4j

jose是比较流行的java库,可以先看下一下它的Wiki(机译过来的,哈哈)

jose.4.j库是JWT和jose规范套件的开源(Apache2.0)实现。它是用Java编写的,仅依赖于JCA API进行加密。

JSON Web令牌(JWT)是一种简洁、URL安全的方式,用于表示双方之间要传输的声明。JWT是OpenID Connect中的身份令牌格式,它还广泛用于OAuth 2.0和许多其他需要压缩消息安全性的上下文中。

JWT代码示例页面显示了如何使用此库轻松生成和使用JWT。

JOSE是Javascript对象签名和加密的缩写,是开发JSON Web签名(JWS)、JSON Web加密(JWE)和JSON Web密钥(JWK)规范的IETF工作组。JWS和JWE使用JSON和base64url编码以(相对)简单、紧凑和web安全的格式保护消息,而JWK定义了加密密钥的JSON表示。JWS、JWE和JWK的实际算法在JSON Web算法(JWA)中定义。

获取库版本

以上一个工程为例,所有的实现都放在auth认证的jwt包下面,引入pom坐标,0.9.0为最新版本

<dependency><groupId>org.bitbucket.b_c</groupId><artifactId>jose4j</artifactId><version>0.9.0</version></dependency>

快速生成与验证jwt

生成密钥对

/*** 创建密钥对* @return* @throws JoseException*/public static RsaJsonWebKey genRsaJsonWebKey() throws JoseException{// 生成一个RSA密钥对,该密钥对将用于JWT的签名和验证,包装在JWK中RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);// 给JWK一个密钥IDrsaJsonWebKey.setKeyId("k1");return rsaJsonWebKey;}

生成jwt令牌

/*** t生成jwt令牌* @return* @throws JoseException*/public static String producing(RsaJsonWebKey rsaJsonWebKey) throws JoseException{// 创建声明,也就是JWT的内容JwtClaims claims = new JwtClaims();// 创建令牌并签名的人claims.setIssuer("Issuer");// 令牌将发送给谁claims.setAudience("Audience");// 令牌到期时间(10分钟后)claims.setExpirationTimeMinutesInTheFuture(10);// 令牌的唯一标识符claims.setGeneratedJwtId();// 颁发/创建令牌的时间(现在)claims.setIssuedAtToNow();// 令牌尚未生效的时间(2分钟前)claims.setNotBeforeMinutesInThePast(2);// 主题/主体是关于谁的令牌claims.setSubject("subject");// 可以添加有关主题的其他声明/属性claims.setClaim("email", "mail@example");List<String> groups = Arrays.asList("group-one", "other-group", "group-three");// 多值声明也可以工作,最终将成为一个JSON数组claims.setStringListClaim("groups", groups);// JWT是JWS和/或JWE,其中JSON声明为有效负载。// 在本例中,它是一个JWS,因此我们创建了一个JsonWebSignature对象。JsonWebSignature jws = new JsonWebSignature();// JWS的有效负载是JWT声明的JSON内容jws.setPayload(claims.toJson());// JWT使用私钥签名jws.setKey(rsaJsonWebKey.getPrivateKey());// 在这个示例中,我们只有一个密钥,但使用密钥ID有助于促进顺利的密钥滚动过程jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());// 在JWT/JWS上设置完整性保护声明的签名算法jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);String jwt = jws.getCompactSerialization();return jwt;}

消费令牌

/*** 验证jwt令牌* @param jwt* @param key* @return* @throws MalformedClaimException*/public static JwtClaims consuming(String jwt, Key key) throws MalformedClaimException{JwtConsumer jwtConsumer = new JwtConsumerBuilder()// JWT必须有到期时间.setRequireExpirationTime()// 在验证基于时间的声明以解释时钟偏差时允许一些余地.setAllowedClockSkewInSeconds(30)// JWT必须有主题声明.setRequireSubject()// JWT需要由谁签发.setExpectedIssuer("Issuer")// JWT的目标用户.setExpectedAudience("Audience")// 使用公钥验证签名.setVerificationKey(key)// 仅允许给定上下文中的预期签名算法.setJwsAlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256).build();try{// 验证JWT并将其处理至索赔JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);return jwtClaims;}catch (InvalidJwtException e){// 是否过期if (e.hasExpired()){System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());}if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID)){System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());}}return null;}

写一个main方法测试一下

public static void main(String[] args) throws Exception{RsaJsonWebKey rsaJsonWebKey = genRsaJsonWebKey();String jwt = producing(rsaJsonWebKey);JwtClaims jwtClaims = consuming(jwt, rsaJsonWebKey.getKey());System.out.println(jwtClaims);}

 看下打印,从里面可以清晰的看到jwt生成相关的信息,及最后解析出来的JwtClaims,消费方可以直接从里面获取数据了,即表示jwt验证完成

20:37:07.792 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.UnsecuredNoneAlgorithm(none|null) registered for alg algorithm none
20:37:08.046 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.HmacUsingShaAlgorithm$HmacSha256(HS256|HmacSHA256) registered for alg algorithm HS256
20:37:08.046 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.HmacUsingShaAlgorithm$HmacSha384(HS384|HmacSHA384) registered for alg algorithm HS384
20:37:08.047 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.HmacUsingShaAlgorithm$HmacSha512(HS512|HmacSHA512) registered for alg algorithm HS512
20:37:08.050 [main] DEBUG org.jose4j.jws.EdDsaAlgorithm - EdDSA via EdDSA is NOT available from the underlying JCE (org.jose4j.lang.JoseException: Unable to get an implementation of algorithm name: EdDSA; caused by: java.security.NoSuchAlgorithmException: EdDSA Signature not available).
20:37:08.050 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - EdDSA is unavailable so will not be registered for alg algorithms.
20:37:08.052 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.EcdsaUsingShaAlgorithm$EcdsaP256UsingSha256(ES256|SHA256withECDSA) registered for alg algorithm ES256
20:37:08.054 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.EcdsaUsingShaAlgorithm$EcdsaP384UsingSha384(ES384|SHA384withECDSA) registered for alg algorithm ES384
20:37:08.055 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.EcdsaUsingShaAlgorithm$EcdsaP521UsingSha512(ES512|SHA512withECDSA) registered for alg algorithm ES512
20:37:08.070 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.EcdsaUsingShaAlgorithm$EcdsaSECP256K1UsingSha256(ES256K|SHA256withECDSA) registered for alg algorithm ES256K
20:37:08.071 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.RsaUsingShaAlgorithm$RsaSha256(RS256|SHA256withRSA) registered for alg algorithm RS256
20:37:08.071 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.RsaUsingShaAlgorithm$RsaSha384(RS384|SHA384withRSA) registered for alg algorithm RS384
20:37:08.072 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - org.jose4j.jws.RsaUsingShaAlgorithm$RsaSha512(RS512|SHA512withRSA) registered for alg algorithm RS512
20:37:08.073 [main] DEBUG org.jose4j.jws.RsaUsingShaAlgorithm$RsaPssSha256 - PS256 via SHA256withRSAandMGF1 is NOT available from the underlying JCE (org.jose4j.lang.JoseException: Unable to get an implementation of algorithm name: SHA256withRSAandMGF1; caused by: java.security.NoSuchAlgorithmException: SHA256withRSAandMGF1 Signature not available).
20:37:08.073 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - PS256 is unavailable so will not be registered for alg algorithms.
20:37:08.074 [main] DEBUG org.jose4j.jws.RsaUsingShaAlgorithm$RsaPssSha384 - PS384 via SHA384withRSAandMGF1 is NOT available from the underlying JCE (org.jose4j.lang.JoseException: Unable to get an implementation of algorithm name: SHA384withRSAandMGF1; caused by: java.security.NoSuchAlgorithmException: SHA384withRSAandMGF1 Signature not available).
20:37:08.074 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - PS384 is unavailable so will not be registered for alg algorithms.
20:37:08.075 [main] DEBUG org.jose4j.jws.RsaUsingShaAlgorithm$RsaPssSha512 - PS512 via SHA512withRSAandMGF1 is NOT available from the underlying JCE (org.jose4j.lang.JoseException: Unable to get an implementation of algorithm name: SHA512withRSAandMGF1; caused by: java.security.NoSuchAlgorithmException: SHA512withRSAandMGF1 Signature not available).
20:37:08.075 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->JsonWebSignatureAlgorithm - PS512 is unavailable so will not be registered for alg algorithms.
20:37:08.075 [main] DEBUG org.jose4j.jwa.AlgorithmFactoryFactory - JWS signature algorithms: [none, HS256, HS384, HS512, ES256, ES384, ES512, ES256K, RS256, RS384, RS512]
20:37:08.079 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.RsaKeyManagementAlgorithm$Rsa1_5(RSA1_5|RSA/ECB/PKCS1Padding) registered for alg algorithm RSA1_5
20:37:08.079 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.RsaKeyManagementAlgorithm$RsaOaep(RSA-OAEP|RSA/ECB/OAEPWithSHA-1AndMGF1Padding) registered for alg algorithm RSA-OAEP
20:37:08.100 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.RsaKeyManagementAlgorithm$RsaOaep256(RSA-OAEP-256|RSA/ECB/OAEPWithSHA-256AndMGF1Padding) registered for alg algorithm RSA-OAEP-256
20:37:08.100 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.DirectKeyManagementAlgorithm(dir|null) registered for alg algorithm dir
20:37:08.102 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.AesKeyWrapManagementAlgorithm$Aes128(A128KW|AESWrap) registered for alg algorithm A128KW
20:37:08.103 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AESWrap is 128
20:37:08.103 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - A192KW is unavailable so will not be registered for alg algorithms.
20:37:08.103 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AESWrap is 128
20:37:08.104 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - A256KW is unavailable so will not be registered for alg algorithms.
20:37:08.107 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.EcdhKeyAgreementAlgorithm(ECDH-ES|ECDH) registered for alg algorithm ECDH-ES
20:37:08.108 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.EcdhKeyAgreementWithAesKeyWrapAlgorithm$EcdhKeyAgreementWithAes128KeyWrapAlgorithm(ECDH-ES+A128KW|N/A) registered for alg algorithm ECDH-ES+A128KW
20:37:08.110 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AESWrap is 128
20:37:08.110 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - ECDH-ES+A192KW is unavailable so will not be registered for alg algorithms.
20:37:08.112 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AESWrap is 128
20:37:08.112 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - ECDH-ES+A256KW is unavailable so will not be registered for alg algorithms.
20:37:08.114 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.Pbes2HmacShaWithAesKeyWrapAlgorithm$HmacSha256Aes128(PBES2-HS256+A128KW|n/a) registered for alg algorithm PBES2-HS256+A128KW
20:37:08.114 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AESWrap is 128
20:37:08.114 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - PBES2-HS384+A192KW is unavailable so will not be registered for alg algorithms.
20:37:08.115 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AESWrap is 128
20:37:08.115 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - PBES2-HS512+A256KW is unavailable so will not be registered for alg algorithms.
20:37:08.138 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - org.jose4j.jwe.AesGcmKeyEncryptionAlgorithm$Aes128Gcm(A128GCMKW|AES/GCM/NoPadding) registered for alg algorithm A128GCMKW
20:37:08.139 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AES/GCM/NoPadding is 128
20:37:08.139 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - A192GCMKW is unavailable so will not be registered for alg algorithms.
20:37:08.140 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AES/GCM/NoPadding is 128
20:37:08.140 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->KeyManagementAlgorithm - A256GCMKW is unavailable so will not be registered for alg algorithms.
20:37:08.140 [main] DEBUG org.jose4j.jwa.AlgorithmFactoryFactory - JWE key management algorithms: [RSA1_5, RSA-OAEP, RSA-OAEP-256, dir, A128KW, ECDH-ES, ECDH-ES+A128KW, PBES2-HS256+A128KW, A128GCMKW]
20:37:08.143 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->ContentEncryptionAlgorithm - org.jose4j.jwe.AesCbcHmacSha2ContentEncryptionAlgorithm$Aes128CbcHmacSha256(A128CBC-HS256|AES/CBC/PKCS5Padding) registered for enc algorithm A128CBC-HS256
20:37:08.144 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AES/CBC/PKCS5Padding is 128
20:37:08.144 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->ContentEncryptionAlgorithm - A192CBC-HS384 is unavailable so will not be registered for enc algorithms.
20:37:08.144 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AES/CBC/PKCS5Padding is 128
20:37:08.145 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->ContentEncryptionAlgorithm - A256CBC-HS512 is unavailable so will not be registered for enc algorithms.
20:37:08.146 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->ContentEncryptionAlgorithm - org.jose4j.jwe.AesGcmContentEncryptionAlgorithm$Aes128Gcm(A128GCM|AES/GCM/NoPadding) registered for enc algorithm A128GCM
20:37:08.147 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AES/GCM/NoPadding is 128
20:37:08.147 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->ContentEncryptionAlgorithm - A192GCM is unavailable so will not be registered for enc algorithms.
20:37:08.147 [main] DEBUG org.jose4j.jwe.CipherStrengthSupport - max allowed key length for AES/GCM/NoPadding is 128
20:37:08.147 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->ContentEncryptionAlgorithm - A256GCM is unavailable so will not be registered for enc algorithms.
20:37:08.148 [main] DEBUG org.jose4j.jwa.AlgorithmFactoryFactory - JWE content encryption algorithms: [A128CBC-HS256, A128GCM]
20:37:08.149 [main] DEBUG org.jose4j.jwa.AlgorithmFactory->CompressionAlgorithm - org.jose4j.zip.DeflateRFC1951CompressionAlgorithm@7f9fcf7f registered for zip algorithm DEF
20:37:08.149 [main] DEBUG org.jose4j.jwa.AlgorithmFactoryFactory - JWE compression algorithms: [DEF]
20:37:08.149 [main] DEBUG org.jose4j.jwa.AlgorithmFactoryFactory - Initialized jose4j in 359ms
JWT Claims Set:{iss=Issuer, aud=Audience, exp=1665146827, jti=lqn2i0wvh4xkGJlWxq3-AA, iat=1665146227, nbf=1665146107, sub=subject, email=mail@example, groups=[group-one, other-group, group-three]}

如果是同一个应用,公私钥都在一块,刚才的代码是没有什么问题的。如果是授权系统颁发给其它系统验证,那理论上公私钥是分开的,有一个下发的过程,即提前生成好密钥对,下发公钥给应用系统,授权服务持有私钥,上面的代码可以改造如下:

/*** t生成jwt令牌* @return* @throws JoseException*/public static String producing(String privateKey, String keyId) throws JoseException{// 创建声明,也就是JWT的内容JwtClaims claims = new JwtClaims();// 创建令牌并签名的人claims.setIssuer("Issuer");// 令牌将发送给谁claims.setAudience("Audience");// 令牌到期时间(10分钟后)claims.setExpirationTimeMinutesInTheFuture(10);// 令牌的唯一标识符claims.setGeneratedJwtId();// 颁发/创建令牌的时间(现在)claims.setIssuedAtToNow();// 令牌尚未生效的时间(2分钟前)claims.setNotBeforeMinutesInThePast(2);// 主题/主体是关于谁的令牌claims.setSubject("subject");// 可以添加有关主题的其他声明/属性claims.setClaim("email", "mail@example");List<String> groups = Arrays.asList("group-one", "other-group", "group-three");// 多值声明也可以工作,最终将成为一个JSON数组claims.setStringListClaim("groups", groups);// JWT是JWS和/或JWE,其中JSON声明为有效负载。// 在本例中,它是一个JWS,因此我们创建了一个JsonWebSignature对象。JsonWebSignature jws = new JsonWebSignature();// JWS的有效负载是JWT声明的JSON内容jws.setPayload(claims.toJson());// JWT使用私钥签名jws.setKey(new RsaJsonWebKey(JsonUtil.parseJson(privateKey)).getPrivateKey());// 在这个示例中,我们只有一个密钥,但使用密钥ID有助于促进顺利的密钥滚动过程jws.setKeyIdHeaderValue(keyId);// 在JWT/JWS上设置完整性保护声明的签名算法jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);String jwt = jws.getCompactSerialization();return jwt;}/*** 验证jwt令牌* @param jwt* @param publicKey* @return* @throws MalformedClaimException*/public static JwtClaims consuming(String jwt, String publicKey) throws MalformedClaimException, JoseException{JwtConsumer jwtConsumer = new JwtConsumerBuilder()// JWT必须有到期时间.setRequireExpirationTime()// 在验证基于时间的声明以解释时钟偏差时允许一些余地.setAllowedClockSkewInSeconds(30)// JWT必须有主题声明.setRequireSubject()// JWT需要由谁签发.setExpectedIssuer("Issuer")// JWT的目标用户.setExpectedAudience("Audience")// 使用公钥验证签名.setVerificationKey(new RsaJsonWebKey(JsonUtil.parseJson(publicKey)).getPublicKey())// 仅允许给定上下文中的预期签名算法.setJwsAlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256).build();try{// 验证JWT并将其处理至索赔JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);return jwtClaims;}catch (InvalidJwtException e){System.err.println("Invalid JWT! " + e);// 是否过期if (e.hasExpired()){System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());}if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID)){System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());}}return null;}public static void main(String[] args) throws Exception{RsaJsonWebKey rsaJsonWebKey = genRsaJsonWebKey();String publicKey = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
//        System.out.println(publicKey);String privateKey = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
//        System.out.println(privateKey);String jwt = producing(privateKey, rsaJsonWebKey.getKeyId());JwtClaims jwtClaims = consuming(jwt, publicKey);System.out.println(jwtClaims);}

Java JWT

Java JWT是JSON Web令牌(JWT)的Java实现-RFC 7519

它还支持Android版本的库, JWTDecode.Android

JDK版本

Java 8、11和17支持此库

获取库版本

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.1.0</version>
</dependency>

创建并签署令牌

首先需要通过调用JWT.create()来创建JWTCreator实例。使用生成器定义令牌需要的自定义声明。最后,获取String标记call sign()并传递Algorithm实例。

对称加密

可以选择用对称的加密算法HS256来签名令牌,如下,key为"secret",内容为"auth0"

/*** 用HS256算法创建token* @return*/public static String genHsToken(){Algorithm algorithm = Algorithm.HMAC256("secret");String token = JWT.create().withIssuer("auth0").sign(algorithm);return token;}

可以写一个main方法,打印一下生成的token,类似如下格式

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.izVguZPRsBQ5Rqw6dhMvcIwy8_9lQnrO3vpxGwPCuzs

把它放到jwt工具里面,会展示对应的信息,header+payload+sign

 检验令牌

首先需要通过调用JWT.require()创建JWTVerifier实例,并传递Algorithm实例。如果您需要令牌具有特定的Claim值,请使用生成器来定义它们。方法build()返回的实例是可重用的,因此您可以定义它一次,然后使用它来验证不同的令牌。最后调用验证器verifier.verify()传递令牌。

 public static void verifyToken(String token){Algorithm algorithm = Algorithm.HMAC256("secret");JWTVerifier jwtVerifier = JWT.require(algorithm).withIssuer("auth0").build();jwtVerifier.verify(token);}

这里用的密钥都是一样的为"secret",如果令牌检验不过,会抛出异常,比如密钥不对

com.auth0.jwt.exceptions.SignatureVerificationException: The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA256

更多推荐

Oauth2系列9:JWT令牌各种实现

本文发布于:2024-03-08 21:15:32,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1722396.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:令牌   系列   JWT

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!