From 5d422e16086eefce1b905787517a1a1b2c5d133f Mon Sep 17 00:00:00 2001 From: litoral05 Date: Wed, 3 Jun 2026 14:08:00 +0100 Subject: [PATCH] Add jwt token generation --- pom.xml | 19 +++++++++ .../BackendGatewayApplication.java | 6 ++- .../backend_gateway/auth/AuthService.java | 10 ++++- .../auth/dto/LoginResponse.java | 2 + .../security/JwtProperties.java | 26 ++++++++++++ .../backend_gateway/security/JwtService.java | 42 +++++++++++++++++++ src/main/resources/application.yaml | 6 ++- 7 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/litoralregas/backend_gateway/security/JwtProperties.java create mode 100644 src/main/java/com/litoralregas/backend_gateway/security/JwtService.java diff --git a/pom.xml b/pom.xml index 4b6c18c..68ef2fe 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,25 @@ org.springframework.boot spring-boot-starter-webflux + + io.jsonwebtoken + jjwt-api + 0.12.7 + + + + io.jsonwebtoken + jjwt-impl + 0.12.7 + runtime + + + + io.jsonwebtoken + jjwt-jackson + 0.12.7 + runtime + diff --git a/src/main/java/com/litoralregas/backend_gateway/BackendGatewayApplication.java b/src/main/java/com/litoralregas/backend_gateway/BackendGatewayApplication.java index ac16304..e56c415 100644 --- a/src/main/java/com/litoralregas/backend_gateway/BackendGatewayApplication.java +++ b/src/main/java/com/litoralregas/backend_gateway/BackendGatewayApplication.java @@ -1,12 +1,16 @@ package com.litoralregas.backend_gateway; import com.litoralregas.backend_gateway.gateway.ProxyProperties; +import com.litoralregas.backend_gateway.security.JwtProperties; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; @SpringBootApplication -@EnableConfigurationProperties(ProxyProperties.class) +@EnableConfigurationProperties({ + ProxyProperties.class, + JwtProperties.class +}) public class BackendGatewayApplication { public static void main(String[] args) { diff --git a/src/main/java/com/litoralregas/backend_gateway/auth/AuthService.java b/src/main/java/com/litoralregas/backend_gateway/auth/AuthService.java index cf402a8..6ab6ad8 100644 --- a/src/main/java/com/litoralregas/backend_gateway/auth/AuthService.java +++ b/src/main/java/com/litoralregas/backend_gateway/auth/AuthService.java @@ -2,6 +2,7 @@ package com.litoralregas.backend_gateway.auth; import com.litoralregas.backend_gateway.auth.dto.LoginRequest; import com.litoralregas.backend_gateway.auth.dto.LoginResponse; +import com.litoralregas.backend_gateway.security.JwtService; import com.litoralregas.backend_gateway.user.UserEntity; import com.litoralregas.backend_gateway.user.UserRepository; import org.springframework.security.crypto.password.PasswordEncoder; @@ -12,13 +13,16 @@ public class AuthService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; + private final JwtService jwtService; public AuthService( UserRepository userRepository, - PasswordEncoder passwordEncoder + PasswordEncoder passwordEncoder, + JwtService jwtService ) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; + this.jwtService = jwtService; } public LoginResponse login(LoginRequest request) { @@ -39,7 +43,11 @@ public class AuthService { throw new InvalidCredentialsException(); } + String accessToken = jwtService.generateToken(user); + return new LoginResponse( + accessToken, + "Bearer", user.getId(), user.getClient().getId(), user.getClient().getName(), diff --git a/src/main/java/com/litoralregas/backend_gateway/auth/dto/LoginResponse.java b/src/main/java/com/litoralregas/backend_gateway/auth/dto/LoginResponse.java index 69c856b..ef33bd6 100644 --- a/src/main/java/com/litoralregas/backend_gateway/auth/dto/LoginResponse.java +++ b/src/main/java/com/litoralregas/backend_gateway/auth/dto/LoginResponse.java @@ -3,6 +3,8 @@ package com.litoralregas.backend_gateway.auth.dto; import com.litoralregas.backend_gateway.user.UserRole; public record LoginResponse( + String accessToken, + String tokenType, Long userId, Long clientId, String clientName, diff --git a/src/main/java/com/litoralregas/backend_gateway/security/JwtProperties.java b/src/main/java/com/litoralregas/backend_gateway/security/JwtProperties.java new file mode 100644 index 0000000..bafaa3f --- /dev/null +++ b/src/main/java/com/litoralregas/backend_gateway/security/JwtProperties.java @@ -0,0 +1,26 @@ +package com.litoralregas.backend_gateway.security; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "jwt") +public class JwtProperties { + + private String secret; + private long expirationMinutes; + + public String getSecret() { + return secret; + } + + public long getExpirationMinutes() { + return expirationMinutes; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public void setExpirationMinutes(long expirationMinutes) { + this.expirationMinutes = expirationMinutes; + } +} \ No newline at end of file diff --git a/src/main/java/com/litoralregas/backend_gateway/security/JwtService.java b/src/main/java/com/litoralregas/backend_gateway/security/JwtService.java new file mode 100644 index 0000000..94ea165 --- /dev/null +++ b/src/main/java/com/litoralregas/backend_gateway/security/JwtService.java @@ -0,0 +1,42 @@ +package com.litoralregas.backend_gateway.security; + +import com.litoralregas.backend_gateway.user.UserEntity; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Service; + +import javax.crypto.SecretKey; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.Date; + +@Service +public class JwtService { + + private final JwtProperties jwtProperties; + + public JwtService(JwtProperties jwtProperties) { + this.jwtProperties = jwtProperties; + } + + public String generateToken(UserEntity user) { + Instant now = Instant.now(); + Instant expiresAt = now.plusSeconds(jwtProperties.getExpirationMinutes() * 60); + + return Jwts.builder() + .subject(user.getUsername()) + .claim("userId", user.getId()) + .claim("clientId", user.getClient().getId()) + .claim("role", user.getRole().name()) + .issuedAt(Date.from(now)) + .expiration(Date.from(expiresAt)) + .signWith(getSigningKey()) + .compact(); + } + + private SecretKey getSigningKey() { + return Keys.hmacShaKeyFor( + jwtProperties.getSecret().getBytes(StandardCharsets.UTF_8) + ); + } +} \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 182d354..f4e6c57 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -23,4 +23,8 @@ gateway: proxy: backend-base-url: http://10.100.1.2:18450 connect-timeout: 3s - response-timeout: 10s \ No newline at end of file + response-timeout: 10s + +jwt: + secret: your-super-long-secret-key-change-me + expiration-minutes: 1440 \ No newline at end of file