From 78d836dfa3dbca7bc0d264ee979381f88acb4f29 Mon Sep 17 00:00:00 2001 From: Hyojin Ahn Date: Wed, 14 Jan 2026 11:42:49 -0500 Subject: [PATCH] [auth] Added generating system token. For example, opr-rest-api needs a token to call hcm-rest-api in scheduler. --- pom.xml | 5 ++++ .../erp/auth/AuthenticationController.java | 5 ++++ .../goi/erp/auth/AuthenticationService.java | 30 +++++++++++++++++++ .../auth/SystemAuthenticationRequestDto.java | 9 ++++++ .../java/com/goi/erp/config/JwtService.java | 8 +++++ .../SecuritySystemClientsProperties.java | 24 +++++++++++++++ src/main/resources/application.yml | 9 +++++- 7 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/goi/erp/auth/SystemAuthenticationRequestDto.java create mode 100644 src/main/java/com/goi/erp/config/SecuritySystemClientsProperties.java 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