Compare commits
11 Commits
6659140440
..
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 0bb25521a1 | |||
| 8de3e42576 | |||
| d5ef831efc | |||
| 15e73677c4 | |||
| a72ee91bd4 | |||
| 102e906b36 | |||
| 45419f23c1 | |||
| 2203b0f2c3 | |||
| 4b67ba9995 | |||
| 5d422e1608 | |||
| 04f4732da1 |
@@ -31,3 +31,5 @@ build/
|
|||||||
|
|
||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
.env
|
||||||
|
|||||||
Binary file not shown.
@@ -72,6 +72,25 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.12.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.12.7</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.12.7</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
package com.litoralregas.backend_gateway;
|
package com.litoralregas.backend_gateway;
|
||||||
|
|
||||||
import com.litoralregas.backend_gateway.gateway.ProxyProperties;
|
import com.litoralregas.backend_gateway.gateway.ProxyProperties;
|
||||||
|
import com.litoralregas.backend_gateway.security.JwtProperties;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableConfigurationProperties(ProxyProperties.class)
|
@EnableConfigurationProperties({
|
||||||
|
ProxyProperties.class,
|
||||||
|
JwtProperties.class
|
||||||
|
})
|
||||||
public class BackendGatewayApplication {
|
public class BackendGatewayApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.litoralregas.backend_gateway.auth;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.auth.dto.LoginRequest;
|
||||||
|
import com.litoralregas.backend_gateway.auth.dto.LoginResponse;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/auth")
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final AuthService authService;
|
||||||
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
public AuthController(
|
||||||
|
AuthService authService,
|
||||||
|
PasswordEncoder passwordEncoder
|
||||||
|
) {
|
||||||
|
this.authService = authService;
|
||||||
|
this.passwordEncoder = passwordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public LoginResponse login(@RequestBody LoginRequest request) {
|
||||||
|
System.out.println(passwordEncoder.encode("admin123"));
|
||||||
|
return authService.login(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
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;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AuthService {
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
private final JwtService jwtService;
|
||||||
|
|
||||||
|
public AuthService(
|
||||||
|
UserRepository userRepository,
|
||||||
|
PasswordEncoder passwordEncoder,
|
||||||
|
JwtService jwtService
|
||||||
|
) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
this.passwordEncoder = passwordEncoder;
|
||||||
|
this.jwtService = jwtService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginResponse login(LoginRequest request) {
|
||||||
|
|
||||||
|
UserEntity user = userRepository.findByUsername(request.username())
|
||||||
|
.orElseThrow(InvalidCredentialsException::new);
|
||||||
|
|
||||||
|
if (!user.isEnabled()) {
|
||||||
|
throw new InvalidCredentialsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean valid = passwordEncoder.matches(
|
||||||
|
request.password(),
|
||||||
|
user.getPasswordHash()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
throw new InvalidCredentialsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String accessToken = jwtService.generateToken(user);
|
||||||
|
|
||||||
|
return new LoginResponse(
|
||||||
|
accessToken,
|
||||||
|
"Bearer",
|
||||||
|
user.getId(),
|
||||||
|
user.getClient().getId(),
|
||||||
|
user.getClient().getName(),
|
||||||
|
user.getUsername(),
|
||||||
|
user.getRole()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.litoralregas.backend_gateway.auth;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||||
|
public class InvalidCredentialsException extends RuntimeException {
|
||||||
|
|
||||||
|
public InvalidCredentialsException() {
|
||||||
|
super("Invalid credentials");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.litoralregas.backend_gateway.auth.dto;
|
||||||
|
|
||||||
|
public record LoginRequest(
|
||||||
|
String username,
|
||||||
|
String password
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
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,
|
||||||
|
String username,
|
||||||
|
UserRole role
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -7,4 +7,5 @@ import java.util.Optional;
|
|||||||
public interface ClientRepository extends JpaRepository<ClientEntity, Long> {
|
public interface ClientRepository extends JpaRepository<ClientEntity, Long> {
|
||||||
|
|
||||||
Optional<ClientEntity> findByName(String name);
|
Optional<ClientEntity> findByName(String name);
|
||||||
|
Optional<ClientEntity> findByIdAndEnabledTrue(Long id);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.litoralregas.backend_gateway.client;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.security.AuthenticatedUser;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ClientResolver {
|
||||||
|
|
||||||
|
private final ClientRepository clientRepository;
|
||||||
|
|
||||||
|
public ClientResolver(ClientRepository clientRepository) {
|
||||||
|
this.clientRepository = clientRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientEntity resolveCurrentClient() {
|
||||||
|
|
||||||
|
Authentication authentication =
|
||||||
|
SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
|
if (authentication == null) {
|
||||||
|
throw new RuntimeException("Not authenticated");
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticatedUser user =
|
||||||
|
(AuthenticatedUser) authentication.getPrincipal();
|
||||||
|
|
||||||
|
return clientRepository
|
||||||
|
.findByIdAndEnabledTrue(user.clientId())
|
||||||
|
.orElseThrow(() -> new RuntimeException("Client not found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.litoralregas.backend_gateway.auth;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class AuthExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(InvalidCredentialsException.class)
|
||||||
|
public ResponseEntity<String> handleInvalidCredentials() {
|
||||||
|
return ResponseEntity
|
||||||
|
.status(HttpStatus.UNAUTHORIZED)
|
||||||
|
.body("Invalid credentials");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,32 @@
|
|||||||
package com.litoralregas.backend_gateway.config;
|
package com.litoralregas.backend_gateway.config;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.security.JwtAuthenticationFilter;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||||
|
|
||||||
|
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
|
||||||
|
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
|
||||||
|
}
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
return http
|
return http
|
||||||
.csrf(csrf -> csrf.disable())
|
.csrf(csrf -> csrf.disable())
|
||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
.requestMatchers("/auth/**").permitAll()
|
||||||
|
.requestMatchers("/admin/**").hasRole("ADMIN")
|
||||||
|
.requestMatchers("/api/backend/**").authenticated()
|
||||||
.anyRequest().permitAll()
|
.anyRequest().permitAll()
|
||||||
)
|
)
|
||||||
|
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.litoralregas.backend_gateway.gateway;
|
package com.litoralregas.backend_gateway.gateway;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.client.ClientResolver;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -12,19 +13,18 @@ import org.springframework.web.reactive.function.client.WebClientResponseExcepti
|
|||||||
public class BackendProxyService {
|
public class BackendProxyService {
|
||||||
|
|
||||||
private final WebClient webClient;
|
private final WebClient webClient;
|
||||||
private final ProxyProperties proxyProperties;
|
private final ClientResolver clientResolver;
|
||||||
|
|
||||||
public BackendProxyService(WebClient webClient, ProxyProperties proxyProperties) {
|
public BackendProxyService(
|
||||||
|
WebClient webClient,
|
||||||
|
ClientResolver clientResolver
|
||||||
|
) {
|
||||||
this.webClient = webClient;
|
this.webClient = webClient;
|
||||||
this.proxyProperties = proxyProperties;
|
this.clientResolver = clientResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHealth() {
|
public String getHealth() {
|
||||||
return webClient.get()
|
return "UP";
|
||||||
.uri(proxyProperties.getBackendBaseUrl() + "/actuator/health")
|
|
||||||
.retrieve()
|
|
||||||
.bodyToMono(String.class)
|
|
||||||
.block();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<String> proxy(HttpServletRequest request, String body) {
|
public ResponseEntity<String> proxy(HttpServletRequest request, String body) {
|
||||||
@@ -33,7 +33,7 @@ public class BackendProxyService {
|
|||||||
String query = request.getQueryString();
|
String query = request.getQueryString();
|
||||||
|
|
||||||
String targetUrl =
|
String targetUrl =
|
||||||
proxyProperties.getBackendBaseUrl()
|
resolveBackendUrl()
|
||||||
+ path
|
+ path
|
||||||
+ (query != null ? "?" + query : "");
|
+ (query != null ? "?" + query : "");
|
||||||
|
|
||||||
@@ -76,4 +76,10 @@ public class BackendProxyService {
|
|||||||
.body("Backend unavailable");
|
.body("Backend unavailable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String resolveBackendUrl() {
|
||||||
|
return clientResolver
|
||||||
|
.resolveCurrentClient()
|
||||||
|
.getBackendBaseUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.litoralregas.backend_gateway.security;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.user.UserRole;
|
||||||
|
|
||||||
|
public record AuthenticatedUser(
|
||||||
|
Long userId,
|
||||||
|
Long clientId,
|
||||||
|
String username,
|
||||||
|
UserRole role
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.litoralregas.backend_gateway.security;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.user.UserRole;
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final JwtService jwtService;
|
||||||
|
|
||||||
|
public JwtAuthenticationFilter(JwtService jwtService) {
|
||||||
|
this.jwtService = jwtService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain
|
||||||
|
) throws ServletException, IOException {
|
||||||
|
|
||||||
|
String authHeader = request.getHeader("Authorization");
|
||||||
|
|
||||||
|
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = authHeader.substring(7);
|
||||||
|
|
||||||
|
if (!jwtService.isValid(token)) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String username = jwtService.extractUsername(token);
|
||||||
|
Long userId = jwtService.extractUserId(token);
|
||||||
|
Long clientId = jwtService.extractClientId(token);
|
||||||
|
UserRole role = UserRole.valueOf(jwtService.extractRole(token));
|
||||||
|
|
||||||
|
AuthenticatedUser authenticatedUser = new AuthenticatedUser(
|
||||||
|
userId,
|
||||||
|
clientId,
|
||||||
|
username,
|
||||||
|
role
|
||||||
|
);
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
|
new UsernamePasswordAuthenticationToken(
|
||||||
|
authenticatedUser,
|
||||||
|
null,
|
||||||
|
List.of(new SimpleGrantedAuthority("ROLE_" + role.name()))
|
||||||
|
);
|
||||||
|
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.litoralregas.backend_gateway.security;
|
||||||
|
|
||||||
|
import com.litoralregas.backend_gateway.user.UserEntity;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.JwtException;
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Claims getClaims(String token) {
|
||||||
|
|
||||||
|
return Jwts.parser()
|
||||||
|
.verifyWith(getSigningKey())
|
||||||
|
.build()
|
||||||
|
.parseSignedClaims(token)
|
||||||
|
.getPayload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid(String token) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
getClaims(token);
|
||||||
|
return true;
|
||||||
|
} catch (JwtException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String extractUsername(String token) {
|
||||||
|
return getClaims(token).getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long extractClientId(String token) {
|
||||||
|
|
||||||
|
Object value = getClaims(token).get("clientId");
|
||||||
|
|
||||||
|
if (value instanceof Integer integer) {
|
||||||
|
return integer.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof Long longValue) {
|
||||||
|
return longValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String extractRole(String token) {
|
||||||
|
return getClaims(token).get("role", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long extractUserId(String token) {
|
||||||
|
|
||||||
|
Object value = getClaims(token).get("userId");
|
||||||
|
|
||||||
|
if (value instanceof Integer integer) {
|
||||||
|
return integer.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof Long longValue) {
|
||||||
|
return longValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,4 +23,8 @@ gateway:
|
|||||||
proxy:
|
proxy:
|
||||||
backend-base-url: http://10.100.1.2:18450
|
backend-base-url: http://10.100.1.2:18450
|
||||||
connect-timeout: 3s
|
connect-timeout: 3s
|
||||||
response-timeout: 10s
|
response-timeout: 10s
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
secret: ${JWT_SECRET}
|
||||||
|
expiration-minutes: ${JWT_EXPIRATION_MINUTES:1440}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
INSERT INTO clients (name, backend_base_url, enabled)
|
||||||
|
SELECT 'dev-local', 'http://10.100.1.2:18450', 1
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM clients WHERE name = 'dev-local'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO users (client_id, username, password_hash, role, enabled)
|
||||||
|
SELECT
|
||||||
|
(SELECT id FROM clients WHERE name = 'dev-local'),
|
||||||
|
'admin',
|
||||||
|
'$2a$10$it1vy5t1FXISQTWit2A39udaMR0N0yqJtJUnxMqF1Xz4SuNBaam6u',
|
||||||
|
'ADMIN',
|
||||||
|
1
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM users WHERE username = 'admin'
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user