diff --git a/pom.xml b/pom.xml
index 9f60383..cfce41e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,6 +80,11 @@
layered-architecture-template
1.0.0-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
diff --git a/src/main/java/com/goi/erp/auth/AuthenticationController.java b/src/main/java/com/goi/erp/auth/AuthenticationController.java
index ab8282f..416a289 100644
--- a/src/main/java/com/goi/erp/auth/AuthenticationController.java
+++ b/src/main/java/com/goi/erp/auth/AuthenticationController.java
@@ -33,5 +33,10 @@ public class AuthenticationController {
public void refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
service.refreshToken(request, response);
}
+
+ @PostMapping("/authenticate/system")
+ public AuthenticationResponse authenticateSystem(@RequestBody SystemAuthenticationRequestDto request) {
+ return service.authenticateSystem(request);
+ }
}
diff --git a/src/main/java/com/goi/erp/auth/AuthenticationService.java b/src/main/java/com/goi/erp/auth/AuthenticationService.java
index 3597d92..5da2eb7 100644
--- a/src/main/java/com/goi/erp/auth/AuthenticationService.java
+++ b/src/main/java/com/goi/erp/auth/AuthenticationService.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.goi.erp.common.exception.InvalidPasswordException;
import com.goi.erp.common.exception.UserNotFoundException;
import com.goi.erp.config.JwtService;
+import com.goi.erp.config.SecuritySystemClientsProperties;
import com.goi.erp.token.Token;
import com.goi.erp.token.TokenRepository;
import com.goi.erp.token.TokenType;
@@ -34,6 +35,7 @@ public class AuthenticationService {
private final RolePermissionRepository rolePermissionRepository;
private final JwtService jwtService;
+ private final SecuritySystemClientsProperties systemClientsProperties;
// private final AuthenticationManager authenticationManager;
// public AuthenticationResponse register(RegisterRequest request) {
@@ -157,4 +159,32 @@ public class AuthenticationService {
}
}
}
+
+ // 시스템 토큰 발급 (OPR/CRM 등 서버간 호출용)
+ public AuthenticationResponse authenticateSystem(SystemAuthenticationRequestDto request) {
+
+ if (request.getClientId() == null || request.getClientSecret() == null) {
+ throw new InvalidPasswordException("Missing client credentials");
+ }
+
+ var clientConfig = systemClientsProperties.getClients().get(request.getClientId());
+ if (clientConfig == null) {
+ throw new InvalidPasswordException("Invalid system client");
+ }
+
+ if (!clientConfig.getSecret().equals(request.getClientSecret())) {
+ throw new InvalidPasswordException("Invalid system secret");
+ }
+
+ List permissions = clientConfig.getPermissions(); // 예: ["H:R:A"]
+
+ String jwtToken = jwtService.generateSystemToken(request.getClientId(), permissions);
+
+ // system token은 보통 DB(TokenRepository)에 저장/폐기(revoke) 안 함 (짧게 발급 + 캐싱)
+ return AuthenticationResponse.builder()
+ .accessToken(jwtToken)
+ .refreshToken(null)
+ .build();
+ }
+
}
diff --git a/src/main/java/com/goi/erp/auth/SystemAuthenticationRequestDto.java b/src/main/java/com/goi/erp/auth/SystemAuthenticationRequestDto.java
new file mode 100644
index 0000000..8e7170c
--- /dev/null
+++ b/src/main/java/com/goi/erp/auth/SystemAuthenticationRequestDto.java
@@ -0,0 +1,9 @@
+package com.goi.erp.auth;
+
+import lombok.Data;
+
+@Data
+public class SystemAuthenticationRequestDto {
+ private String clientId;
+ private String clientSecret;
+}
diff --git a/src/main/java/com/goi/erp/config/JwtService.java b/src/main/java/com/goi/erp/config/JwtService.java
index 886c92b..5566bf5 100644
--- a/src/main/java/com/goi/erp/config/JwtService.java
+++ b/src/main/java/com/goi/erp/config/JwtService.java
@@ -61,6 +61,14 @@ public class JwtService {
return buildToken(extraClaims, employee.getEmpUuid().toString(), jwtExpiration);
}
+
+ public String generateSystemToken(String clientId, java.util.List permissions) {
+ Map extraClaims = new HashMap<>();
+ extraClaims.put("permissions", permissions);
+ extraClaims.put("loginId", clientId);
+ return buildToken(extraClaims, clientId, jwtExpiration);
+ }
+
public String generateRefreshToken(Employee employee, List roles, List permissions) {
Map extraClaims = new HashMap<>();
diff --git a/src/main/java/com/goi/erp/config/SecuritySystemClientsProperties.java b/src/main/java/com/goi/erp/config/SecuritySystemClientsProperties.java
new file mode 100644
index 0000000..d31df49
--- /dev/null
+++ b/src/main/java/com/goi/erp/config/SecuritySystemClientsProperties.java
@@ -0,0 +1,24 @@
+package com.goi.erp.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+import java.util.Map;
+
+@Configuration
+@ConfigurationProperties(prefix = "application.security.system-clients")
+@Data
+public class SecuritySystemClientsProperties {
+ /**
+ * key: clientId (e.g. "opr-rest-api")
+ */
+ private Map clients;
+
+ @Data
+ public static class Client {
+ private String secret;
+ private List permissions;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 68daa74..5538a98 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -21,7 +21,14 @@ application:
expiration: 86400000 # a day
refresh-token:
expiration: 604800000 # 7 days
+ system-clients:
+ clients:
+ opr-rest-api:
+ secret: ${OPR_SYSTEM_CLIENT_SECRET}
+ permissions:
+ - "H:R:A"
+
server:
port: 8080
servlet:
- context-path: /auth-service
\ No newline at end of file
+ context-path: /auth-service