diff --git a/spring-auth-1/complete/build.gradle b/spring-auth-1/complete/build.gradle index 612af60e..a5370b8f 100644 --- a/spring-auth-1/complete/build.gradle +++ b/spring-auth-1/complete/build.gradle @@ -15,8 +15,9 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'io.jsonwebtoken:jjwt:0.9.1' - implementation 'javax.xml.bind:jaxb-api:2.3.1' + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.rest-assured:rest-assured:5.3.1' diff --git a/spring-auth-1/complete/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java b/spring-auth-1/complete/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java index d1a75c38..e415789f 100644 --- a/spring-auth-1/complete/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java +++ b/spring-auth-1/complete/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java @@ -1,17 +1,30 @@ package cholog.auth.infrastructure; -import io.jsonwebtoken.*; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import java.security.Key; +import java.util.Base64; +import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import java.util.Date; - @Component public class JwtTokenProvider { - @Value("${security.jwt.token.secret-key}") - private String secretKey; - @Value("${security.jwt.token.expire-length}") - private long validityInMilliseconds; + private final Key secretKey; + private final long validityInMilliseconds; + + public JwtTokenProvider( + @Value("${security.jwt.token.secret-key}") String rawSecretKey, + @Value("${security.jwt.token.expire-length}") Long validityInMilliseconds + ) { + final byte[] keyBytes = Base64.getDecoder().decode(rawSecretKey); + this.secretKey = Keys.hmacShaKeyFor(keyBytes); + this.validityInMilliseconds = validityInMilliseconds; + } + public String createToken(String payload) { Claims claims = Jwts.claims().setSubject(payload); @@ -22,21 +35,30 @@ public String createToken(String payload) { .setClaims(claims) .setIssuedAt(now) .setExpiration(validity) - .signWith(SignatureAlgorithm.HS256, secretKey) + .signWith(secretKey) .compact(); } public String getPayload(String token) { - return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); + validateToken(token); + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token) + .getBody() + .getSubject(); } - public boolean validateToken(String token) { + private void validateToken(String token) { try { - Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); + Jws claims = Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token); - return !claims.getBody().getExpiration().before(new Date()); + claims.getBody().getExpiration(); } catch (JwtException | IllegalArgumentException e) { - return false; + throw new RuntimeException("Invalid token"); } } } diff --git a/spring-auth-1/complete/src/main/java/cholog/auth/ui/TokenLoginController.java b/spring-auth-1/complete/src/main/java/cholog/auth/ui/TokenLoginController.java index 59def57b..e821ecf2 100644 --- a/spring-auth-1/complete/src/main/java/cholog/auth/ui/TokenLoginController.java +++ b/spring-auth-1/complete/src/main/java/cholog/auth/ui/TokenLoginController.java @@ -45,7 +45,7 @@ public ResponseEntity tokenLogin(@RequestBody TokenRequest tokenR * ex) request sample *

* GET /members/me/token HTTP/1.1 - * authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE2MTAzNzY2NzIsImV4cCI6MTYxMDM4MDI3Mn0.Gy4g5RwK1Nr7bKT1TOFS4Da6wxWh8l97gmMQDgF8c1E + * authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE3NTA0MTY1MzksImV4cCI6MTc1MDQyMDEzOX0.mhaPDrphpRE9mE1YEZreOmDjZCapBrFe-K4SZvXMlAY * accept: application/json */ @GetMapping("/members/me/token") diff --git a/spring-auth-1/complete/src/main/resources/application.properties b/spring-auth-1/complete/src/main/resources/application.properties index dad5b3cf..bc60a822 100644 --- a/spring-auth-1/complete/src/main/resources/application.properties +++ b/spring-auth-1/complete/src/main/resources/application.properties @@ -1,2 +1,2 @@ -security.jwt.token.secret-key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.ih1aovtQShabQ7l0cINw4k1fagApg3qLWiB8Kt59Lno -security.jwt.token.expire-length=3600000 \ No newline at end of file +security.jwt.token.secret-key=/BWxvVt/eMsTVSq+RI9kRCrZKK38KNGIWi7ilxCg9So= +security.jwt.token.expire-length=3600000 diff --git a/spring-auth-1/initial/build.gradle b/spring-auth-1/initial/build.gradle index 612af60e..a5370b8f 100644 --- a/spring-auth-1/initial/build.gradle +++ b/spring-auth-1/initial/build.gradle @@ -15,8 +15,9 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'io.jsonwebtoken:jjwt:0.9.1' - implementation 'javax.xml.bind:jaxb-api:2.3.1' + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.rest-assured:rest-assured:5.3.1' diff --git a/spring-auth-1/initial/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java b/spring-auth-1/initial/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java index d1a75c38..e415789f 100644 --- a/spring-auth-1/initial/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java +++ b/spring-auth-1/initial/src/main/java/cholog/auth/infrastructure/JwtTokenProvider.java @@ -1,17 +1,30 @@ package cholog.auth.infrastructure; -import io.jsonwebtoken.*; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import java.security.Key; +import java.util.Base64; +import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import java.util.Date; - @Component public class JwtTokenProvider { - @Value("${security.jwt.token.secret-key}") - private String secretKey; - @Value("${security.jwt.token.expire-length}") - private long validityInMilliseconds; + private final Key secretKey; + private final long validityInMilliseconds; + + public JwtTokenProvider( + @Value("${security.jwt.token.secret-key}") String rawSecretKey, + @Value("${security.jwt.token.expire-length}") Long validityInMilliseconds + ) { + final byte[] keyBytes = Base64.getDecoder().decode(rawSecretKey); + this.secretKey = Keys.hmacShaKeyFor(keyBytes); + this.validityInMilliseconds = validityInMilliseconds; + } + public String createToken(String payload) { Claims claims = Jwts.claims().setSubject(payload); @@ -22,21 +35,30 @@ public String createToken(String payload) { .setClaims(claims) .setIssuedAt(now) .setExpiration(validity) - .signWith(SignatureAlgorithm.HS256, secretKey) + .signWith(secretKey) .compact(); } public String getPayload(String token) { - return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); + validateToken(token); + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token) + .getBody() + .getSubject(); } - public boolean validateToken(String token) { + private void validateToken(String token) { try { - Jws claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); + Jws claims = Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token); - return !claims.getBody().getExpiration().before(new Date()); + claims.getBody().getExpiration(); } catch (JwtException | IllegalArgumentException e) { - return false; + throw new RuntimeException("Invalid token"); } } } diff --git a/spring-auth-1/initial/src/main/java/cholog/auth/ui/TokenLoginController.java b/spring-auth-1/initial/src/main/java/cholog/auth/ui/TokenLoginController.java index ed0f81ff..32e0a7f1 100644 --- a/spring-auth-1/initial/src/main/java/cholog/auth/ui/TokenLoginController.java +++ b/spring-auth-1/initial/src/main/java/cholog/auth/ui/TokenLoginController.java @@ -46,7 +46,7 @@ public ResponseEntity tokenLogin() { * ex) request sample *

* GET /members/me/token HTTP/1.1 - * authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE2MTAzNzY2NzIsImV4cCI6MTYxMDM4MDI3Mn0.Gy4g5RwK1Nr7bKT1TOFS4Da6wxWh8l97gmMQDgF8c1E + * authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE3NTA0MTY1MzksImV4cCI6MTc1MDQyMDEzOX0.mhaPDrphpRE9mE1YEZreOmDjZCapBrFe-K4SZvXMlAY * accept: application/json */ @GetMapping("/members/me/token") diff --git a/spring-auth-1/initial/src/main/resources/application.properties b/spring-auth-1/initial/src/main/resources/application.properties index dad5b3cf..bc60a822 100644 --- a/spring-auth-1/initial/src/main/resources/application.properties +++ b/spring-auth-1/initial/src/main/resources/application.properties @@ -1,2 +1,2 @@ -security.jwt.token.secret-key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.ih1aovtQShabQ7l0cINw4k1fagApg3qLWiB8Kt59Lno -security.jwt.token.expire-length=3600000 \ No newline at end of file +security.jwt.token.secret-key=/BWxvVt/eMsTVSq+RI9kRCrZKK38KNGIWi7ilxCg9So= +security.jwt.token.expire-length=3600000