diff --git a/jjwt/pom.xml b/jjwt/pom.xml
index aa238fafb5..9d38d1b0e9 100644
--- a/jjwt/pom.xml
+++ b/jjwt/pom.xml
@@ -41,6 +41,12 @@
jjwt
${jjwt.version}
+
+
+ org.assertj
+ assertj-core
+ test
+
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java
new file mode 100644
index 0000000000..922d5c0ce5
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java
@@ -0,0 +1,46 @@
+package io.jsonwebtoken.jjwtfun.util;
+
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator;
+
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Base64;
+
+import static io.jsonwebtoken.SignatureAlgorithm.HS256;
+
+public class JWTDecoderUtil {
+
+ public static String decodeJWTToken(String token) {
+ Base64.Decoder decoder = Base64.getDecoder();
+
+ String[] chunks = token.split("\\.");
+
+ String header = new String(decoder.decode(chunks[0]));
+ String payload = new String(decoder.decode(chunks[1]));
+
+ return header + " " + payload;
+ }
+
+ public static String decodeJWTToken(String token, String secretKey) throws Exception {
+ Base64.Decoder decoder = Base64.getDecoder();
+
+ String[] chunks = token.split("\\.");
+
+ String header = new String(decoder.decode(chunks[0]));
+ String payload = new String(decoder.decode(chunks[1]));
+
+ String tokenWithoutSignature = chunks[0] + "." + chunks[1];
+ String signature = chunks[2];
+
+ SignatureAlgorithm sa = HS256;
+ SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName());
+
+ DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
+
+ if (!validator.isValid(tokenWithoutSignature, signature)) {
+ throw new Exception("Could not verify JWT token integrity!");
+ }
+
+ return header + " " + payload;
+ }
+}
diff --git a/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java
new file mode 100644
index 0000000000..3103a6c8a3
--- /dev/null
+++ b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java
@@ -0,0 +1,32 @@
+package io.jsonwebtoken.jjwtfun.util;
+
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class JWTDecoderUtilUnitTest {
+
+ private final static String SIMPLE_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9";
+ private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE";
+
+ @Test
+ void givenSimpleToken_whenDecoding_thenStringOfHeaderPayloadAreReturned() {
+ assertThat(JWTDecoderUtil.decodeJWTToken(SIMPLE_TOKEN))
+ .contains(SignatureAlgorithm.HS256.getValue());
+ }
+
+ @Test
+ void givenSignedToken_whenDecodingWithInvalidSecret_thenIntegrityIsNotValidated() {
+ assertThatThrownBy(() -> JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "BAD_SECRET"))
+ .hasMessage("Could not verify JWT token integrity!");
+ }
+
+ @Test
+ void givenSignedToken_whenDecodingWithValidSecret_thenIntegrityIsValidated() throws Exception {
+ assertThat(JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "MySecretKey"))
+ .contains("Baeldung User");
+ }
+}