CA Gateway 토큰 처리
1. 기존메모리에서 따로 관리하던것을 인터스끼리 공유 할수있도록 sessionManager에서 토큰을 관리.(CAToken 관리용 cache 추가 작업) 2. ApiAuthFilter.java 에 ca 방식 토큰 인증 로직 추가. 나머지는 CA토큰 발급(BearerTokenController)처리 및 BeareTokenInfo 는 어윤삼 부장 작업본 그대로 사용.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.eactive.eai.adapter.http.dynamic.filter;
|
package com.eactive.eai.adapter.http.dynamic.filter;
|
||||||
|
|
||||||
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport;
|
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport;
|
||||||
|
import com.eactive.eai.authserver.service.BearerTokenInfo;
|
||||||
//import com.eactive.eai.authserver.vo.BearerTokenInfo;
|
//import com.eactive.eai.authserver.vo.BearerTokenInfo;
|
||||||
//import com.eactive.eai.authserver.custom.BearerTokenService;
|
//import com.eactive.eai.authserver.custom.BearerTokenService;
|
||||||
import com.eactive.eai.authserver.service.OAuth2Manager;
|
import com.eactive.eai.authserver.service.OAuth2Manager;
|
||||||
@@ -9,6 +10,7 @@ import com.eactive.eai.common.message.EAIMessage;
|
|||||||
import com.eactive.eai.common.message.EAIMessageManager;
|
import com.eactive.eai.common.message.EAIMessageManager;
|
||||||
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.session.SessionManager;
|
||||||
import com.eactive.eai.common.stdmessage.STDMessageManager;
|
import com.eactive.eai.common.stdmessage.STDMessageManager;
|
||||||
import com.eactive.eai.common.util.Logger;
|
import com.eactive.eai.common.util.Logger;
|
||||||
import com.eactive.eai.common.util.StringUtil;
|
import com.eactive.eai.common.util.StringUtil;
|
||||||
@@ -113,7 +115,7 @@ public class ApiAuthFilter implements HttpAdapterFilter {
|
|||||||
switch (eaiMessage.getAuthType()){
|
switch (eaiMessage.getAuthType()){
|
||||||
case "oauth":
|
case "oauth":
|
||||||
try {
|
try {
|
||||||
String token = ApiAuthFilter.extractJWTToken(request);
|
String token = extractBearerToken(request);
|
||||||
SignedJWT signedJWT = SignedJWT.parse(token);
|
SignedJWT signedJWT = SignedJWT.parse(token);
|
||||||
|
|
||||||
if (signedJWT.getJWTClaimsSet().getExpirationTime() == null) {
|
if (signedJWT.getJWTClaimsSet().getExpirationTime() == null) {
|
||||||
@@ -169,6 +171,21 @@ public class ApiAuthFilter implements HttpAdapterFilter {
|
|||||||
prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, apiKey);
|
prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, apiKey);
|
||||||
isPassScope = true;
|
isPassScope = true;
|
||||||
break;
|
break;
|
||||||
|
case "ca":
|
||||||
|
String token = extractBearerToken(request);
|
||||||
|
BearerTokenInfo bearerTokenInfo = SessionManager.getInstance().getCAToken(token);
|
||||||
|
if ( bearerTokenInfo != null ) {
|
||||||
|
if( bearerTokenInfo.isExpired() ) {
|
||||||
|
SessionManager.getInstance().removeCAToken(token);
|
||||||
|
throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "expried API key \""+token+"\" in Http Authrozation Header");
|
||||||
|
}
|
||||||
|
prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, bearerTokenInfo.getClientId());
|
||||||
|
isPassScope = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Invalid or missing API key \""+token+"\" in Http Authrozation Header");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "none":
|
case "none":
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@@ -276,7 +293,7 @@ public class ApiAuthFilter implements HttpAdapterFilter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String extractJWTToken(HttpServletRequest request) throws JwtAuthException {
|
public static String extractBearerToken(HttpServletRequest request) throws JwtAuthException {
|
||||||
String authorization = request.getHeader("Authorization");
|
String authorization = request.getHeader("Authorization");
|
||||||
if (StringUtils.isBlank(authorization)) {
|
if (StringUtils.isBlank(authorization)) {
|
||||||
throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "No have header info: Authorization");
|
throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "No have header info: Authorization");
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.eactive.eai.authserver.service;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public class BearerTokenInfo {
|
||||||
|
@JsonProperty("client_id")
|
||||||
|
private String clientId;
|
||||||
|
private Long expiresIn;
|
||||||
|
private Long expiresAt;
|
||||||
|
private Set<String> scopeSet;
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getExpiresIn() {
|
||||||
|
return expiresIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpiresIn(Long expiresIn) {
|
||||||
|
this.expiresIn = expiresIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getExpiresAt() {
|
||||||
|
return expiresAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpiresAt(Long expiresIn) {
|
||||||
|
this.expiresAt = System.currentTimeMillis() + (expiresIn * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getScopeSet() {
|
||||||
|
return scopeSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScopeSet(Set<String> scopeSet) {
|
||||||
|
this.scopeSet = scopeSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpired() {
|
||||||
|
return System.currentTimeMillis() > expiresAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package com.eactive.eai.authserver.service;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.eactive.eai.common.session.SessionManager;
|
||||||
|
import com.eactive.eai.common.session.SessionManagerForIgnite;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class BearerTokenService {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String generateCAToken(String clientId, Long expiresIn, Set<String> scopeSet) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String token = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
BearerTokenInfo CATokenInfo = new BearerTokenInfo();
|
||||||
|
CATokenInfo.setClientId(clientId);
|
||||||
|
CATokenInfo.setExpiresIn(expiresIn);
|
||||||
|
CATokenInfo.setExpiresAt(expiresIn);
|
||||||
|
CATokenInfo.setScopeSet(scopeSet);
|
||||||
|
|
||||||
|
//CATokenStore.put(token, CATokenInfo);
|
||||||
|
|
||||||
|
SessionManager.getInstance().putCAToken(token, CATokenInfo);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateCA(String token) {
|
||||||
|
BearerTokenInfo CATokenInfo = SessionManager.getInstance().getCAToken(token);
|
||||||
|
if (CATokenInfo == null) return false;
|
||||||
|
|
||||||
|
if (CATokenInfo.isExpired()) {
|
||||||
|
SessionManager.getInstance().removeCAToken(token);
|
||||||
|
return false;
|
||||||
|
}else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientIdFromCA(String token) {
|
||||||
|
BearerTokenInfo CATokenInfo = SessionManager.getInstance().getCAToken(token);
|
||||||
|
return CATokenInfo.getClientId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
// private static final SecureRandom secureRandom = new SecureRandom();
|
||||||
|
//
|
||||||
|
// public static String generateTokenString(int length) {
|
||||||
|
// // Java 8의 IntStream과 Collectors.joining을 사용한 효율적인 방법
|
||||||
|
// return IntStream.range(0, length)
|
||||||
|
// .map(i -> secureRandom.nextInt(CHARACTERS.length()))
|
||||||
|
// .mapToObj(CHARACTERS::charAt)
|
||||||
|
// .map(String::valueOf)
|
||||||
|
// .collect(Collectors.joining());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.eactive.eai.common.session;
|
package com.eactive.eai.common.session;
|
||||||
|
|
||||||
|
import com.eactive.eai.authserver.service.BearerTokenInfo;
|
||||||
import com.eactive.eai.common.lifecycle.Lifecycle;
|
import com.eactive.eai.common.lifecycle.Lifecycle;
|
||||||
import com.eactive.eai.common.lifecycle.LifecycleException;
|
import com.eactive.eai.common.lifecycle.LifecycleException;
|
||||||
import com.eactive.eai.common.lifecycle.LifecycleListener;
|
import com.eactive.eai.common.lifecycle.LifecycleListener;
|
||||||
@@ -58,6 +59,7 @@ public abstract class SessionManager implements Lifecycle {
|
|||||||
public static final String USERID_CAHCE_NAME = "convertUserIdSession";
|
public static final String USERID_CAHCE_NAME = "convertUserIdSession";
|
||||||
public static final String WEBSOCKER_CAHCE_NAME = "webSocketTimeout";
|
public static final String WEBSOCKER_CAHCE_NAME = "webSocketTimeout";
|
||||||
public static final String TERMINAL_CAHCE_NAME = "terminalSession";
|
public static final String TERMINAL_CAHCE_NAME = "terminalSession";
|
||||||
|
public static final String CAGATEWAY_TOKEN_CACHE_NAME = "CAGatewayToken";
|
||||||
|
|
||||||
public static final String SESSION_MANAGER_GROUPNAME = "RMIInfo";
|
public static final String SESSION_MANAGER_GROUPNAME = "RMIInfo";
|
||||||
public static final String SESSION_MANAGER_CACHETYPE = "cacheType";
|
public static final String SESSION_MANAGER_CACHETYPE = "cacheType";
|
||||||
@@ -193,6 +195,14 @@ public abstract class SessionManager implements Lifecycle {
|
|||||||
public abstract void putLogin(String key, SessionVO value);
|
public abstract void putLogin(String key, SessionVO value);
|
||||||
|
|
||||||
public abstract void removeLogin(String key);
|
public abstract void removeLogin(String key);
|
||||||
|
|
||||||
|
//CA Token Cache
|
||||||
|
public abstract BearerTokenInfo getCAToken(String key);
|
||||||
|
|
||||||
|
public abstract void putCAToken(String key, BearerTokenInfo value);
|
||||||
|
|
||||||
|
public abstract void removeCAToken(String key);
|
||||||
|
|
||||||
|
|
||||||
// HTTP Cache
|
// HTTP Cache
|
||||||
public abstract SessionVO getHttpLogin(String key);
|
public abstract SessionVO getHttpLogin(String key);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.eactive.eai.common.session;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.eactive.eai.authserver.service.BearerTokenInfo;
|
||||||
import com.eactive.eai.common.ehcache.CustomRMICacheReplicatorFactory;
|
import com.eactive.eai.common.ehcache.CustomRMICacheReplicatorFactory;
|
||||||
import com.eactive.eai.common.logger.EAIDBLogControl;
|
import com.eactive.eai.common.logger.EAIDBLogControl;
|
||||||
import com.eactive.eai.common.message.EAIMessage;
|
import com.eactive.eai.common.message.EAIMessage;
|
||||||
@@ -921,4 +922,19 @@ public class SessionManagerForEhcache extends SessionManager {
|
|||||||
sb.append("</Caches>");
|
sb.append("</Caches>");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BearerTokenInfo getCAToken(String key) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putCAToken(String key, BearerTokenInfo value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeCAToken(String key) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMultic
|
|||||||
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
|
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
|
||||||
|
|
||||||
import com.eactive.eai.adapter.socket2.common.Env;
|
import com.eactive.eai.adapter.socket2.common.Env;
|
||||||
|
import com.eactive.eai.authserver.service.BearerTokenInfo;
|
||||||
import com.eactive.eai.common.logger.EAIDBLogControl;
|
import com.eactive.eai.common.logger.EAIDBLogControl;
|
||||||
import com.eactive.eai.common.message.EAIMessage;
|
import com.eactive.eai.common.message.EAIMessage;
|
||||||
import com.eactive.eai.common.property.PropManager;
|
import com.eactive.eai.common.property.PropManager;
|
||||||
@@ -63,6 +64,7 @@ import ch.qos.logback.classic.Level;
|
|||||||
// 에러내용 : Failed to execute the cache operation
|
// 에러내용 : Failed to execute the cache operation
|
||||||
// (all partition owners have left the grid, partition data has been lost)
|
// (all partition owners have left the grid, partition data has been lost)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public class SessionManagerForIgnite extends SessionManager {
|
public class SessionManagerForIgnite extends SessionManager {
|
||||||
// evictMaster Instance - single socket 관련
|
// evictMaster Instance - single socket 관련
|
||||||
private static IgniteCache<String, String> evictMasterCache = null;
|
private static IgniteCache<String, String> evictMasterCache = null;
|
||||||
@@ -72,7 +74,8 @@ public class SessionManagerForIgnite extends SessionManager {
|
|||||||
private static IgniteCache<String, EAIMessage> cacheTopic = null;
|
private static IgniteCache<String, EAIMessage> cacheTopic = null;
|
||||||
// 비동기 거래 복원용
|
// 비동기 거래 복원용
|
||||||
private static IgniteCache<String, CacheStoreObject> cacheStore = null;
|
private static IgniteCache<String, CacheStoreObject> cacheStore = null;
|
||||||
|
// CA Gateway Token 관리용
|
||||||
|
private static IgniteCache<String, BearerTokenInfo> cacheCAToken = null;
|
||||||
// webSocket Login cache 정보
|
// webSocket Login cache 정보
|
||||||
private static IgniteCache<String, SessionVO> cacheLogin = null; // key = loginId
|
private static IgniteCache<String, SessionVO> cacheLogin = null; // key = loginId
|
||||||
private static IgniteCache<String, String> cacheConvertUserId = null; // 단말ID 를 userID로 변경
|
private static IgniteCache<String, String> cacheConvertUserId = null; // 단말ID 를 userID로 변경
|
||||||
@@ -364,6 +367,7 @@ public class SessionManagerForIgnite extends SessionManager {
|
|||||||
caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, USERID_CAHCE_NAME, 20000, false));
|
caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, USERID_CAHCE_NAME, 20000, false));
|
||||||
caches.add(initCache(config, webSocketTimeout, bootstrapAsynchronously, WEBSOCKER_CAHCE_NAME, 20000, false));
|
caches.add(initCache(config, webSocketTimeout, bootstrapAsynchronously, WEBSOCKER_CAHCE_NAME, 20000, false));
|
||||||
caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, TERMINAL_CAHCE_NAME, 20000, false));
|
caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, TERMINAL_CAHCE_NAME, 20000, false));
|
||||||
|
caches.add(initCache(config, 0, bootstrapAsynchronously, CAGATEWAY_TOKEN_CACHE_NAME, 1000, false));
|
||||||
|
|
||||||
config.setCacheConfiguration(caches.stream().toArray(CacheConfiguration[]::new));
|
config.setCacheConfiguration(caches.stream().toArray(CacheConfiguration[]::new));
|
||||||
|
|
||||||
@@ -391,6 +395,7 @@ public class SessionManagerForIgnite extends SessionManager {
|
|||||||
cacheSocket = manager.cache(ADAPTER_CAHCE_NAME);
|
cacheSocket = manager.cache(ADAPTER_CAHCE_NAME);
|
||||||
cacheTopic = manager.cache(TOPIC_CAHCE_NAME);
|
cacheTopic = manager.cache(TOPIC_CAHCE_NAME);
|
||||||
cacheStore = manager.cache(STORE_CAHCE_NAME);
|
cacheStore = manager.cache(STORE_CAHCE_NAME);
|
||||||
|
cacheCAToken = manager.cache(CAGATEWAY_TOKEN_CACHE_NAME);
|
||||||
|
|
||||||
cacheLogin = manager.cache(LOGIN_CAHCE_NAME);
|
cacheLogin = manager.cache(LOGIN_CAHCE_NAME);
|
||||||
httpLogin = manager.cache(HTTP_CAHCE_NAME);
|
httpLogin = manager.cache(HTTP_CAHCE_NAME);
|
||||||
@@ -810,4 +815,33 @@ public class SessionManagerForIgnite extends SessionManager {
|
|||||||
sb.append("</Caches>");
|
sb.append("</Caches>");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BearerTokenInfo getCAToken(String key) {
|
||||||
|
try {
|
||||||
|
return cacheCAToken.get(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("getCAToken null key=" + key, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putCAToken(String key, BearerTokenInfo value) {
|
||||||
|
if (logger.isWarn()) {
|
||||||
|
logger.warn("Put CAToken key - " + key + ", CAToken - " + value.toString());
|
||||||
|
}
|
||||||
|
cacheCAToken.put(key, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeCAToken(String key) {
|
||||||
|
if (logger.isWarn()) {
|
||||||
|
logger.warn("Remove CAToken key - " + key);
|
||||||
|
}
|
||||||
|
cacheCAToken.remove(key);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user