From b5e1cd08147f07b255322a127ee3ce48ed286a91 Mon Sep 17 00:00:00 2001 From: vitalii Date: Wed, 29 Jul 2020 14:20:19 +0300 Subject: [PATCH] implemented generating jwt --- .../authentication/config/AuthConfig.java | 15 +++++ .../authentication/config/JwtConfig.java | 16 +++++ .../model/jwt/JwtUserIdentity.java | 15 +++++ .../service/jwt/JWTGenerator.java | 60 +++++++++++++++++++ .../app/src/main/resources/application.yml | 7 ++- 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/AuthConfig.java create mode 100644 modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/JwtConfig.java create mode 100644 modules/authentication/server-java/src/main/java/com/sysgears/authentication/model/jwt/JwtUserIdentity.java create mode 100644 modules/authentication/server-java/src/main/java/com/sysgears/authentication/service/jwt/JWTGenerator.java diff --git a/modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/AuthConfig.java b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/AuthConfig.java new file mode 100644 index 0000000000..c4bc32017a --- /dev/null +++ b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/AuthConfig.java @@ -0,0 +1,15 @@ +package com.sysgears.authentication.config; + +import io.jsonwebtoken.security.Keys; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.security.Key; + +@Configuration +public class AuthConfig { + @Bean + public Key jwtSecretKey(JwtConfig config) { + return Keys.hmacShaKeyFor(config.getSecret().getBytes()); + } +} diff --git a/modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/JwtConfig.java b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/JwtConfig.java new file mode 100644 index 0000000000..eb1d3621af --- /dev/null +++ b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/config/JwtConfig.java @@ -0,0 +1,16 @@ +package com.sysgears.authentication.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Getter +@Setter +@Configuration +@ConfigurationProperties("jwt") +public class JwtConfig { + private String secret; + private long accessTokenExpirationInSec; + private long refreshTokenExpirationInSec; +} diff --git a/modules/authentication/server-java/src/main/java/com/sysgears/authentication/model/jwt/JwtUserIdentity.java b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/model/jwt/JwtUserIdentity.java new file mode 100644 index 0000000000..2b33f306ed --- /dev/null +++ b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/model/jwt/JwtUserIdentity.java @@ -0,0 +1,15 @@ +package com.sysgears.authentication.model.jwt; + +import lombok.Data; + +@Data +public class JwtUserIdentity { + private final int id; + private final String username; + private final String passwordHash; + private final String role; + private final Boolean isActive; + private final String email; + private final String firstName; + private final String lastName; +} diff --git a/modules/authentication/server-java/src/main/java/com/sysgears/authentication/service/jwt/JWTGenerator.java b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/service/jwt/JWTGenerator.java new file mode 100644 index 0000000000..3f05dd3e54 --- /dev/null +++ b/modules/authentication/server-java/src/main/java/com/sysgears/authentication/service/jwt/JWTGenerator.java @@ -0,0 +1,60 @@ +package com.sysgears.authentication.service.jwt; + +import com.sysgears.authentication.config.JwtConfig; +import com.sysgears.authentication.model.jwt.JwtUserIdentity; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.security.Key; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Service +@RequiredArgsConstructor +public class JWTGenerator { + private final Key secretKey; + private final JwtConfig jwtConfig; + + //todo: need to separate generation and parsing JWT. + public String generateToken(JwtUserIdentity identity) { + Map claims = new HashMap<>(); + claims.put("identity", identity); + log.debug("Generating new access JWT for user {}", identity.getId()); + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(Date.from(Instant.now())) + .setExpiration(Date.from(Instant.now().plus(jwtConfig.getAccessTokenExpirationInSec(), ChronoUnit.SECONDS))) + .setHeaderParam("typ", "JWT") + .signWith(secretKey, SignatureAlgorithm.HS256) + .compact(); + } + + public String generateRefreshToken(JwtUserIdentity identity) { + Map claims = new HashMap<>(); + claims.put("id", identity.getId()); + log.debug("Generating new refresh JWT for user {}", identity.getId()); + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(Date.from(Instant.now())) + .setExpiration(Date.from(Instant.now().plus(jwtConfig.getRefreshTokenExpirationInSec(), ChronoUnit.SECONDS))) + .setHeaderParam("typ", "JWT") + .signWith(secretKey, SignatureAlgorithm.HS256) + .compact(); + } + + + public String getAllClaimsFromToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token) + .toString(); + } +} diff --git a/packages/server-java/app/src/main/resources/application.yml b/packages/server-java/app/src/main/resources/application.yml index 252a451ff3..987e5e892a 100644 --- a/packages/server-java/app/src/main/resources/application.yml +++ b/packages/server-java/app/src/main/resources/application.yml @@ -32,4 +32,9 @@ graphiql: enabled: true endpoint: subscriptions: /graphql - mapping: /graphiql \ No newline at end of file + mapping: /graphiql + +jwt: + secret: "676918AB4D29BFE59CCB943F3C09F5CC8FB3A8511E23E502B67DE95AB9A9D00C" + access-token-expiration-in-sec: 3600 + refresh-token-expiration-in-sec: 604800 \ No newline at end of file