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