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"); + } +}