bugfix 및 token 거래 GET 방식 추가.

토큰거래 GET 방식으로 하는것 보안상 좋지않음.
(GET 파라미터같은 경우 웹서버에 로깅이 되어버림, clientSecret 같은 것들이 파일로그에 남아서 그대로 노출됨)

사유 : 고객요청.
This commit is contained in:
cho
2026-01-21 16:57:31 +09:00
parent 730196cefb
commit 61e6aa6b19
4 changed files with 53 additions and 24 deletions
@@ -34,15 +34,16 @@ public class ApiRequestBodyFilter extends OncePerRequestFilter {
FilterChain filterChain) FilterChain filterChain)
throws ServletException, IOException { throws ServletException, IOException {
String encoding = getInboundGroupAdapterEncoding(request);
if (!isTarget(request)) { if (!isTarget(request)) {
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
return; return;
} }
String encoding = getInboundGroupAdapterEncoding(request);
//원본 바디를 byte[]로 읽기 (개행 포함 그대로) 왜? 뒤에 필터에서 HMAC값 계산할수도 있어서 변조되면 안됨. 개행문자도 그대로 가야함. //원본 바디를 byte[]로 읽기 (개행 포함 그대로) 왜? 뒤에 필터에서 HMAC값 계산할수도 있어서 변조되면 안됨. 개행문자도 그대로 가야함.
byte[] rawBody = readBodyAsBytes(request); byte[] rawBody = readBodyAsBytes(request);
@@ -1,13 +1,11 @@
package com.eactive.eai.authserver.config; package com.eactive.eai.authserver.config;
import java.security.KeyPair; import java.security.KeyPair;
import java.time.LocalDateTime;
import java.util.Arrays;
import javax.sql.DataSource; import javax.sql.DataSource;
import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
import com.eactive.eai.authserver.service.OAuth2Manager;
import com.eactive.eai.authserver.vo.ClientVO;
import com.eactive.eai.common.logger.EAIDBLogControl;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -16,6 +14,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
@@ -27,31 +26,25 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.E
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator; import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory; import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import com.eactive.eai.authserver.provider.ElinkJdbcTokenStore; import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
import com.eactive.eai.authserver.service.OAuth2Manager;
import com.eactive.eai.authserver.vo.ClientVO;
import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.dao.Keys; import com.eactive.eai.common.dao.Keys;
import com.eactive.eai.common.logger.EAIDBLogControl;
import com.eactive.eai.common.property.PropGroupVO; import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.ServiceLocator; import com.eactive.eai.common.util.ServiceLocator;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Map;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog; import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Configuration @Configuration
@EnableAuthorizationServer @EnableAuthorizationServer
@@ -79,6 +72,8 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Autowired @Autowired
@Qualifier("eLinkUserDetailsService") @Qualifier("eLinkUserDetailsService")
private UserDetailsService userDetailsService; private UserDetailsService userDetailsService;
@Override @Override
public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception { public void configure(final AuthorizationServerSecurityConfigurer security) throws Exception {
@@ -107,6 +102,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
endpoints.pathMapping("/oauth/token", "/oauth2/token") ; endpoints.pathMapping("/oauth/token", "/oauth2/token") ;
endpoints.authenticationManager(authenticationManager); endpoints.authenticationManager(authenticationManager);
endpoints.userDetailsService(userDetailsService); endpoints.userDetailsService(userDetailsService);
endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
// JWT 토큰을 사용하는 경우 // JWT 토큰을 사용하는 경우
JwtAccessTokenConverter converter = jwtAccessTokenConverter(); JwtAccessTokenConverter converter = jwtAccessTokenConverter();
@@ -35,8 +35,10 @@ public class BearerTokenContoller {
this.tokenService = tokenService; this.tokenService = tokenService;
} }
// 기본 CA Bearer Token 발급 @RequestMapping(
@PostMapping("/token") value = "/token",
method = {RequestMethod.POST, RequestMethod.GET}
)
public ResponseEntity<?> issueCAToken(@RequestParam MultiValueMap<String, String> req) throws JwtAuthException { public ResponseEntity<?> issueCAToken(@RequestParam MultiValueMap<String, String> req) throws JwtAuthException {
JSONObject resObject = new JSONObject(); JSONObject resObject = new JSONObject();
@@ -10,6 +10,7 @@ import java.time.LocalDateTime;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@@ -29,9 +30,11 @@ import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
@@ -64,6 +67,31 @@ public class KjbMGOAuth2Controller {
@ResponseBody @ResponseBody
public ResponseEntity<String> token(@RequestBody KjbMGOAuth2AccessTokenRequest tokenRequest, public ResponseEntity<String> token(@RequestBody KjbMGOAuth2AccessTokenRequest tokenRequest,
HttpServletRequest request, HttpServletResponse response) { HttpServletRequest request, HttpServletResponse response) {
return issueToken(tokenRequest, request, response);
}
@GetMapping(value = "/mapi/oauth2/token", produces = "application/json; charset=UTF-8")
@ResponseBody
public ResponseEntity<String> tokenGet(@RequestParam Map<String, String> params, HttpServletRequest request,
HttpServletResponse response) {
KjbMGOAuth2AccessTokenRequest tokenRequest = new KjbMGOAuth2AccessTokenRequest();
tokenRequest.setGrantType(params.get("grant_type"));
tokenRequest.setClientId(params.get("client_id"));
tokenRequest.setClientSecret(params.get("client_secret"));
tokenRequest.setScope(params.get("scope"));
tokenRequest.setResource(params.get("resource"));
return issueToken(tokenRequest, request, response);
}
private ResponseEntity<String> issueToken(
KjbMGOAuth2AccessTokenRequest tokenRequest,
HttpServletRequest request,
HttpServletResponse response) {
if (logger.isDebug()) { if (logger.isDebug()) {
logger.debug(tokenRequest.toString()); logger.debug(tokenRequest.toString());
} }
@@ -142,8 +170,10 @@ public class KjbMGOAuth2Controller {
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, "Unauthorized. [Unknown]"); String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, "Unauthorized. [Unknown]");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorJson); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorJson);
} }
} }
private void verifyClient(ClientDetails clientDetails, String clientId, String clientSecret, Set<String> scopeSet) private void verifyClient(ClientDetails clientDetails, String clientId, String clientSecret, Set<String> scopeSet)
throws JwtAuthException { throws JwtAuthException {