diff --git a/jhipster-modules/README.md b/jhipster-modules/README.md index 11c3d5397f..2aae8a5697 100644 --- a/jhipster-modules/README.md +++ b/jhipster-modules/README.md @@ -1,7 +1,5 @@ ## JHipster -This module contains articles about JHipster. - -### Relevant articles: - +This module contains articles about JHipster. +Relevant articles are listed in the nested module folders. diff --git a/jhipster-modules/jhipster-microservice/car-app/pom.xml b/jhipster-modules/jhipster-microservice/car-app/pom.xml index 87c289cb46..069a1f6848 100644 --- a/jhipster-modules/jhipster-microservice/car-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/car-app/pom.xml @@ -29,7 +29,7 @@ 3.21.0-GA 1.0.0 1.1.0 - 0.7.0 + 0.12.3 1.0.0 3.6 2.0.0 @@ -216,7 +216,7 @@ io.jsonwebtoken - jjwt + jjwt-api ${jjwt.version} diff --git a/jhipster-modules/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java b/jhipster-modules/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java index 3908bfa8f3..028f34e3f0 100644 --- a/jhipster-modules/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java +++ b/jhipster-modules/jhipster-microservice/car-app/src/main/java/com/car/app/security/jwt/TokenProvider.java @@ -70,7 +70,7 @@ public class TokenProvider { public Authentication getAuthentication(String token) { Claims claims = Jwts.parser() - .setSigningKey(secretKey) + .setSigningKey(secretKey).build() .parseClaimsJws(token) .getBody(); @@ -86,7 +86,7 @@ public class TokenProvider { public boolean validateToken(String authToken) { try { - Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken); + Jwts.parser().setSigningKey(secretKey).build().parseClaimsJws(authToken); return true; } catch (SignatureException e) { log.info("Invalid JWT signature."); diff --git a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml index f660463026..43f9b046c7 100644 --- a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml @@ -28,7 +28,7 @@ 3.21.0-GA 1.0.0 1.1.0 - 0.7.0 + 0.12.3 1.0.0 3.6 2.0.0 @@ -215,7 +215,7 @@ io.jsonwebtoken - jjwt + jjwt-api ${jjwt.version} diff --git a/jhipster-modules/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java b/jhipster-modules/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java index 47a5bf75af..38cee99e01 100644 --- a/jhipster-modules/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java +++ b/jhipster-modules/jhipster-microservice/dealer-app/src/main/java/com/dealer/app/security/jwt/TokenProvider.java @@ -70,7 +70,7 @@ public class TokenProvider { public Authentication getAuthentication(String token) { Claims claims = Jwts.parser() - .setSigningKey(secretKey) + .setSigningKey(secretKey).build() .parseClaimsJws(token) .getBody(); @@ -86,7 +86,7 @@ public class TokenProvider { public boolean validateToken(String authToken) { try { - Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken); + Jwts.parser().setSigningKey(secretKey).build().parseClaimsJws(authToken); return true; } catch (SignatureException e) { log.info("Invalid JWT signature."); diff --git a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml index 7c95704da7..90d703b8c7 100644 --- a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml @@ -31,7 +31,7 @@ 3.21.0-GA 1.0.0 1.1.0 - 0.7.0 + 0.12.3 1.0.0 3.6 2.0.0 @@ -243,7 +243,7 @@ io.jsonwebtoken - jjwt + jjwt-api ${jjwt.version} diff --git a/jhipster-modules/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java b/jhipster-modules/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java index 5ffb55f33e..14d343c0d7 100644 --- a/jhipster-modules/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java +++ b/jhipster-modules/jhipster-microservice/gateway-app/src/main/java/com/gateway/security/jwt/TokenProvider.java @@ -70,7 +70,7 @@ public class TokenProvider { public Authentication getAuthentication(String token) { Claims claims = Jwts.parser() - .setSigningKey(secretKey) + .setSigningKey(secretKey).build() .parseClaimsJws(token) .getBody(); @@ -86,7 +86,7 @@ public class TokenProvider { public boolean validateToken(String authToken) { try { - Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken); + Jwts.parser().setSigningKey(secretKey).build().parseClaimsJws(authToken); return true; } catch (SignatureException e) { log.info("Invalid JWT signature."); diff --git a/jhipster-modules/jhipster-monolithic/pom.xml b/jhipster-modules/jhipster-monolithic/pom.xml index bb82c819c4..f1ee479756 100644 --- a/jhipster-modules/jhipster-monolithic/pom.xml +++ b/jhipster-modules/jhipster-monolithic/pom.xml @@ -122,7 +122,7 @@ io.jsonwebtoken - jjwt + jjwt-api ${jjwt.version} @@ -897,7 +897,7 @@ 3.21.0-GA 1.0.0 1.1.0 - 0.7.0 + 0.12.3 1.1.3 3.6 2.0.0 diff --git a/jhipster-modules/jhipster-monolithic/src/main/java/com/baeldung/security/jwt/TokenProvider.java b/jhipster-modules/jhipster-monolithic/src/main/java/com/baeldung/security/jwt/TokenProvider.java index 3ba4d7c793..095663065b 100644 --- a/jhipster-modules/jhipster-monolithic/src/main/java/com/baeldung/security/jwt/TokenProvider.java +++ b/jhipster-modules/jhipster-monolithic/src/main/java/com/baeldung/security/jwt/TokenProvider.java @@ -70,7 +70,7 @@ public class TokenProvider { public Authentication getAuthentication(String token) { Claims claims = Jwts.parser() - .setSigningKey(secretKey) + .setSigningKey(secretKey).build() .parseClaimsJws(token) .getBody(); @@ -86,7 +86,7 @@ public class TokenProvider { public boolean validateToken(String authToken) { try { - Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken); + Jwts.parser().setSigningKey(secretKey).build().parseClaimsJws(authToken); return true; } catch (SignatureException e) { log.info("Invalid JWT signature."); diff --git a/persistence-modules/spring-jpa-2/pom.xml b/persistence-modules/spring-jpa-2/pom.xml index 9abf888fb2..c20c43912b 100644 --- a/persistence-modules/spring-jpa-2/pom.xml +++ b/persistence-modules/spring-jpa-2/pom.xml @@ -54,8 +54,8 @@ io.jsonwebtoken - jjwt - 0.9.1 + jjwt-api + 0.12.3 diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java index 00db7eebc4..42eab1d6de 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java @@ -30,7 +30,7 @@ public class AuthenticationService { if (token != null) { String user = Jwts.parser() .setSigningKey(SIGNINGKEY) - .parseClaimsJws(token.replace(PREFIX, "")) + .build().parseClaimsJws(token.replace(PREFIX, "")) .getBody() .getSubject(); if (user != null) { @@ -48,9 +48,11 @@ public class AuthenticationService { } String tenant = Jwts.parser() .setSigningKey(SIGNINGKEY) - .parseClaimsJws(token.replace(PREFIX, "")) + .build().parseClaimsJws(token.replace(PREFIX, "")) .getBody() - .getAudience(); + .getAudience() + .iterator() + .next(); return tenant; } } diff --git a/security-modules/jjwt/pom.xml b/security-modules/jjwt/pom.xml index 3ea4a46b8a..3693eaf9c4 100644 --- a/security-modules/jjwt/pom.xml +++ b/security-modules/jjwt/pom.xml @@ -35,13 +35,23 @@ io.jsonwebtoken - jjwt + jjwt-api + ${jjwt.version} + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + + + io.jsonwebtoken + jjwt-jackson ${jjwt.version} - 0.7.0 + 0.12.3 \ No newline at end of file diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java index e453f33d5e..c0f176034e 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java @@ -66,7 +66,7 @@ public class WebSecurityConfig { // CsrfFilter already made sure the token matched. Here, we'll make sure it's not expired try { Jwts.parser() - .setSigningKeyResolver(secretService.getSigningKeyResolver()) + .setSigningKeyResolver(secretService.getSigningKeyResolver()).build() .parseClaimsJws(token.getToken()); } catch (JwtException e) { // most likely an ExpiredJwtException, but this will handle any diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java index 3d157827d1..1c29a753b6 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/DynamicJWTController.java @@ -4,7 +4,7 @@ import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.impl.compression.CompressionCodecs; +import io.jsonwebtoken.impl.compression.DeflateCompressionAlgorithm; import io.jsonwebtoken.jjwtfun.model.JwtResponse; import io.jsonwebtoken.jjwtfun.service.SecretService; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +38,7 @@ public class DynamicJWTController extends BaseController { public JwtResponse dynamicBuildercompress(@RequestBody Map claims) throws UnsupportedEncodingException { String jws = Jwts.builder() .setClaims(claims) - .compressWith(CompressionCodecs.DEFLATE) + .compressWith(new DeflateCompressionAlgorithm()) .signWith(SignatureAlgorithm.HS256, secretService.getHS256SecretBytes()) .compact(); return new JwtResponse(jws); diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java index 1ca0973c33..4975385398 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/SecretsController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.security.NoSuchAlgorithmException; import java.util.Map; import static org.springframework.web.bind.annotation.RequestMethod.GET; @@ -23,7 +24,7 @@ public class SecretsController extends BaseController { } @RequestMapping(value = "/refresh-secrets", method = GET) - public Map refreshSecrets() { + public Map refreshSecrets() throws NoSuchAlgorithmException { return secretService.refreshSecrets(); } diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java index efafa4b1b7..4ff71a620e 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/StaticJWTController.java @@ -42,7 +42,7 @@ public class StaticJWTController extends BaseController { public JwtResponse parser(@RequestParam String jwt) throws UnsupportedEncodingException { Jws jws = Jwts.parser() - .setSigningKeyResolver(secretService.getSigningKeyResolver()) + .setSigningKeyResolver(secretService.getSigningKeyResolver()).build() .parseClaimsJws(jwt); return new JwtResponse(jws); @@ -53,7 +53,7 @@ public class StaticJWTController extends BaseController { Jws jws = Jwts.parser() .requireIssuer("Stormpath") .require("hasMotorcycle", true) - .setSigningKeyResolver(secretService.getSigningKeyResolver()) + .setSigningKeyResolver(secretService.getSigningKeyResolver()).build() .parseClaimsJws(jwt); return new JwtResponse(jws); diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java index 4426a4b9b0..958d6fb48f 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/service/SecretService.java @@ -6,12 +6,14 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SigningKeyResolver; import io.jsonwebtoken.SigningKeyResolverAdapter; import io.jsonwebtoken.impl.TextCodec; -import io.jsonwebtoken.impl.crypto.MacProvider; import io.jsonwebtoken.lang.Assert; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; +import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; + +import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; @@ -28,7 +30,7 @@ public class SecretService { }; @PostConstruct - public void setup() { + public void setup() throws NoSuchAlgorithmException { refreshSecrets(); } @@ -42,32 +44,34 @@ public class SecretService { public void setSecrets(Map secrets) { Assert.notNull(secrets); - Assert.hasText(secrets.get(SignatureAlgorithm.HS256.getValue())); - Assert.hasText(secrets.get(SignatureAlgorithm.HS384.getValue())); - Assert.hasText(secrets.get(SignatureAlgorithm.HS512.getValue())); + Assert.hasText(secrets.get(SignatureAlgorithm.HS256.getJcaName())); + Assert.hasText(secrets.get(SignatureAlgorithm.HS384.getJcaName())); + Assert.hasText(secrets.get(SignatureAlgorithm.HS512.getJcaName())); this.secrets = secrets; } public byte[] getHS256SecretBytes() { - return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS256.getValue())); + return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS256.getJcaName())); } public byte[] getHS384SecretBytes() { - return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS384.getValue())); + return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS384.getJcaName())); } public byte[] getHS512SecretBytes() { - return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS512.getValue())); + return TextCodec.BASE64.decode(secrets.get(SignatureAlgorithm.HS512.getJcaName())); } - public Map refreshSecrets() { - SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256); - secrets.put(SignatureAlgorithm.HS256.getValue(), TextCodec.BASE64.encode(key.getEncoded())); - key = MacProvider.generateKey(SignatureAlgorithm.HS384); - secrets.put(SignatureAlgorithm.HS384.getValue(), TextCodec.BASE64.encode(key.getEncoded())); - key = MacProvider.generateKey(SignatureAlgorithm.HS512); - secrets.put(SignatureAlgorithm.HS512.getValue(), TextCodec.BASE64.encode(key.getEncoded())); + public Map refreshSecrets() throws NoSuchAlgorithmException { + SecretKey key = KeyGenerator.getInstance(SignatureAlgorithm.HS256.getJcaName()).generateKey(); + secrets.put(SignatureAlgorithm.HS256.getJcaName(), TextCodec.BASE64.encode(key.getEncoded())); + + key = KeyGenerator.getInstance(SignatureAlgorithm.HS384.getJcaName()).generateKey(); + secrets.put(SignatureAlgorithm.HS384.getJcaName(), TextCodec.BASE64.encode(key.getEncoded())); + + key = KeyGenerator.getInstance(SignatureAlgorithm.HS512.getJcaName()).generateKey(); + secrets.put(SignatureAlgorithm.HS512.getJcaName(), TextCodec.BASE64.encode(key.getEncoded())); return secrets; } } diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java index 0fbf7637dd..2fc97b0b51 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java @@ -1,12 +1,14 @@ package io.jsonwebtoken.jjwtfun.util; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.Jwts; 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 { @@ -21,26 +23,19 @@ public class JWTDecoderUtil { return header + " " + payload; } - public static String decodeJWTToken(String token, String secretKey) throws Exception { - Base64.Decoder decoder = Base64.getUrlDecoder(); + public static boolean isTokenValid(String token, String secretKey) throws Exception { + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), SignatureAlgorithm.HS256.getJcaName()); - String[] chunks = token.split("\\."); + JwtParser jwtParser = Jwts.parser() + .verifyWith(secretKeySpec) + .build(); - 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!"); + try { + jwtParser.parse(token); + } catch (Exception e) { + throw new Exception("Could not verify JWT token integrity!", e); } - return header + " " + payload; + return true; } } diff --git a/security-modules/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java b/security-modules/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java index 3103a6c8a3..4cdfdc59ba 100644 --- a/security-modules/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java +++ b/security-modules/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java @@ -1,16 +1,16 @@ 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; +import static org.junit.jupiter.api.Assertions.assertTrue; class JWTDecoderUtilUnitTest { private final static String SIMPLE_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9"; - private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE"; + private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.6h_QYBTbyKxfMq3TGiAhVI416rctV0c0SpzWxVm-0-Y"; @Test void givenSimpleToken_whenDecoding_thenStringOfHeaderPayloadAreReturned() { @@ -20,13 +20,13 @@ class JWTDecoderUtilUnitTest { @Test void givenSignedToken_whenDecodingWithInvalidSecret_thenIntegrityIsNotValidated() { - assertThatThrownBy(() -> JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "BAD_SECRET")) + assertThatThrownBy(() -> JWTDecoderUtil. + isTokenValid(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"); + assertTrue(JWTDecoderUtil.isTokenValid(SIGNED_TOKEN, "randomSecretWithSome!!CharacterS!")); } }