From 98b4273b4a8bb28dd75ba8bc71ddc2f37eb8c4f2 Mon Sep 17 00:00:00 2001 From: KNKIM Date: Tue, 24 Aug 2021 17:01:55 +0900 Subject: [PATCH] =?UTF-8?q?DB=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9E=91=EC=97=85=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20-=20=EC=A7=84=ED=96=89=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ext/oauth/service/OAuthConfig.java | 23 +- .../com/ext/oauth/service/OAuthLogin.java | 112 +++-- .../ext/oauth/service/OAuthUniversalUser.java | 43 +- .../com/ext/oauth/service/OAuthVO.java | 10 +- .../nlib/security/SpringSecurityConfig.java | 3 +- .../java/nlib/user/service/LoginService.java | 18 +- .../java/nlib/user/service/impl/LoginDAO.java | 5 + .../user/service/impl/LoginServiceImpl.java | 53 +-- .../java/nlib/user/web/LoginController.java | 434 ++++++------------ src/main/java/nlib/util/StringUtil.java | 21 +- .../mapper/config/mapper-config.xml | 3 +- .../cmm/{CMM_CODE_SQL.xml => CodeDAO_SQL.xml} | 2 +- .../mapper/nlib/user/LoginDAO_SQL.xml | 14 +- src/main/resources/nlib/nlib.properties | 38 +- src/main/webapp/homes/seoul.jsp | 5 + 15 files changed, 328 insertions(+), 456 deletions(-) rename src/main/resources/egovframework/mapper/nlib/cmm/{CMM_CODE_SQL.xml => CodeDAO_SQL.xml} (88%) diff --git a/src/main/java/egovframework/com/ext/oauth/service/OAuthConfig.java b/src/main/java/egovframework/com/ext/oauth/service/OAuthConfig.java index a679bab6..79e66b36 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthConfig.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthConfig.java @@ -1,18 +1,21 @@ package egovframework.com.ext.oauth.service; +import nlib.cmm.service.NlibProperty; + public interface OAuthConfig { - static final String GOOGLE_PROFILE_URL = "https://www.googleapis.com/plus/v1/people/me"; - static final String NAVER_PROFILE_URL = "https://openapi.naver.com/v1/nid/me"; - static final String KAKAO_PROFILE_URL = "https://kapi.kakao.com/v2/user/me"; + static final String GOOGLE_SERVICE_NAME = NlibProperty.getString("oauth2.sns.name.google"); + static final String GOOGLE_PROFILE_URL = NlibProperty.getString("oauth2.client.provider.google.user-info-uri"); // "https://www.googleapis.com/plus/v1/people/me"; - static final String NAVER_ACCESS_TOKEN = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code"; - static final String NAVER_AUTH = "https://nid.naver.com/oauth2.0/authorize"; + static final String NAVER_SERVICE_NAME = NlibProperty.getString("oauth2.sns.name.naver"); + static final String NAVER_PROFILE_URL = NlibProperty.getString("oauth2.client.provider.naver.user-info-uri"); // "https://openapi.naver.com/v1/nid/me"; + static final String NAVER_ACCESS_TOKEN = NlibProperty.getString("oauth2.client.provider.naver.token-uri"); // "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code"; + static final String NAVER_AUTH = NlibProperty.getString("oauth2.client.provider.naver.authorization-uri"); // "https://nid.naver.com/oauth2.0/authorize"; - static final String KAKAO_ACCESS_TOKEN = "https://kauth.kakao.com/oauth/token?client_id="; - static final String KAKAO_AUTH = "https://kauth.kakao.com/oauth/authorize"; + static final String KAKAO_SERVICE_NAME = NlibProperty.getString("oauth2.sns.name.kakao"); + static final String KAKAO_PROFILE_URL = NlibProperty.getString("oauth2.client.provider.kakao.user-info-uri"); // "https://kapi.kakao.com/v2/user/me"; + static final String KAKAO_ACCESS_TOKEN = NlibProperty.getString("oauth2.client.provider.kakao.token-uri"); // "https://kauth.kakao.com/oauth/token?client_id="; + static final String KAKAO_AUTH = NlibProperty.getString("oauth2.client.provider.kakao.authorization-uri"); // "https://kauth.kakao.com/oauth/authorize"; - static final String GOOGLE_SERVICE_NAME = "google"; - static final String NAVER_SERVICE_NAME = "naver"; - static final String KAKAO_SERVICE_NAME = "kakao"; } + diff --git a/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java b/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java index 5ce7211f..c05c1c9d 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java @@ -22,21 +22,19 @@ public class OAuthLogin { public OAuthLogin(OAuthVO oauthVO) { - - this.oauthService = new ServiceBuilder(oauthVO.getClientId()) - .apiSecret(oauthVO.getClientSecret()) - .callback(oauthVO.getRedirectUrl()) - .scope("profile") - .build(oauthVO.getApi20Instance()); - - this.oauthVO = oauthVO; + this(oauthVO, null); } public OAuthLogin(OAuthVO oauthVO, String deptJsessionId) { + // CallBack 호출될 경우, 지방문화원 원세션ID를 다시 전달받을 수 있도록 포함 처리 (2021.08.23 KKN) this.oauthService = new ServiceBuilder(oauthVO.getClientId()) .apiSecret(oauthVO.getClientSecret()) - .callback(appendParam(oauthVO.getRedirectUrl(), "deptJsessionId", deptJsessionId)) + .callback( + StringUtil.isEmpty(deptJsessionId) ? + oauthVO.getRedirectUrl() : + appendUrlParam(oauthVO.getRedirectUrl(), "deptJsessionId", deptJsessionId) + ) .scope("profile") .build(oauthVO.getApi20Instance()); @@ -48,8 +46,7 @@ public class OAuthLogin { } public OAuthUniversalUser getUserProfile(String code) throws Exception { - //System.out.println("===>>> oauthService.getApiKey() = "+oauthService.getApiKey()); - //System.out.println("===>>> oauthService.getApiSecret() = "+oauthService.getApiSecret()); + OAuth2AccessToken accessToken = oauthService.getAccessToken(code); OAuthRequest request = new OAuthRequest(Verb.GET, this.oauthVO.getProfileUrl()); @@ -60,21 +57,58 @@ public class OAuthLogin { } private OAuthUniversalUser parseJson(String body) throws Exception { - //System.out.println("============================\n" + body + "\n=================="); + OAuthUniversalUser user = new OAuthUniversalUser(); ObjectMapper mapper = new ObjectMapper(); JsonNode rootNode = mapper.readTree(body); - if (this.oauthVO.isGoogle()) { + //------------------------------------ + // 네이버 (2021.08.19 KKN) + //------------------------------------ + if (this.oauthVO.isNaver()) { + user.setServiceName(OAuthConfig.NAVER_SERVICE_NAME); + JsonNode resNode = rootNode.get("response"); + + // 사용자 내부 고유 ID (예: kh3lhfSg2v7TnJLmdhH7a0HyL-1zExIS4cF1mD4Hi4Y) + user.setSnsId(resNode.get("id").asText()); + + // 사용자로그인ID (메일형식) : 네이버 계정 제공하지 않으므로 연락처 이메일을 기본 메일 계정으로 설정 + user.setLoginUserId(resNode.get("email").asText()); + + // 사용자명 (예: 홍길동) + user.setName(resNode.get("name").asText()); + + // 메일주소 + user.setEmail(resNode.get("email").asText()); + + // 생년월일 + String birthday = StringUtil.getString(resNode.get("birthday").asText(), "0000"); + String birthyear = StringUtil.getString(resNode.get("birthyear").asText(), "0000"); + birthday = birthday.replaceAll("-", ""); + if(birthday.length() != 4) birthday = "0000"; + if(birthyear.length() != 4) birthyear = "0000"; + user.setBirthday(birthyear + birthday); + + // 성별 + user.setGender(resNode.get("gender").asText()); + + // 로그인 성공 + user.setValidLogin(true); + + } + //------------------------------------ + // 구글 + //------------------------------------ + else if (this.oauthVO.isGoogle()) { String id = rootNode.get("id").asText(); user.setServiceName(OAuthConfig.GOOGLE_SERVICE_NAME); if (oauthVO.isGoogle()) - user.setUserId(id); + user.setLoginUserId(id); user.setNickName(rootNode.get("displayName").asText()); JsonNode nameNode = rootNode.path("name"); String uname = nameNode.get("familyName").asText() + nameNode.get("givenName").asText(); - user.setUserName(uname); + user.setName(uname); Iterator iterEmails = rootNode.path("emails").elements(); while(iterEmails.hasNext()) { @@ -86,47 +120,29 @@ public class OAuthLogin { } } - } else if (this.oauthVO.isNaver()) { - user.setServiceName(OAuthConfig.NAVER_SERVICE_NAME); - JsonNode resNode = rootNode.get("response"); - - // 사용자 내부 고유 ID (예: kh3lhfSg2v7TnJLmdhH7a0HyL-1zExIS4cF1mD4Hi4Y) - user.setUid(resNode.get("id").asText()); - - // 사용자로그인ID (메일형식) - user.setUserId(resNode.get("email").asText()); - - // 사용자명 (예: 홍길동) - user.setUserName(resNode.get("name").asText()); - - // 메일주소 - user.setEmail(resNode.get("email").asText()); - - // 생년월일 - String birthday = StringUtil.getString(resNode.get("birthday").asText(), "0000"); - String birthyear = StringUtil.getString(resNode.get("birthyear").asText(), "0000"); - birthday = birthday.replaceAll("-", ""); - if(birthday.length() != 4) birthday = "0000"; - if(birthyear.length() != 4) birthyear = "0000"; - user.setBirthdate(birthyear + birthday); - - // 성별 - user.setGender(resNode.get("gender").asText()); - - // 로그인 성공 - user.setValidLogin(true); - - } else if (this.oauthVO.isKakao()) { + } + //------------------------------------ + // 카카오 + //------------------------------------ + else if (this.oauthVO.isKakao()) { user.setServiceName(OAuthConfig.KAKAO_SERVICE_NAME); JsonNode resNode = rootNode.get("properties"); - user.setUserId(rootNode.get("id").asText()); + user.setLoginUserId(rootNode.get("id").asText()); user.setNickName(resNode.get("nickname").asText()); } return user; } - public String appendParam(String url, String paramName, String paramValue) { + /** + * URL에 매개변수를 GET 방식으로 추가하여 리턴한다. + * + * @param url + * @param paramName + * @param paramValue + * @return + */ + public String appendUrlParam(String url, String paramName, String paramValue) { if(StringUtil.isEmpty(url)) return ""; if(StringUtil.isEmpty(paramName)) return url; diff --git a/src/main/java/egovframework/com/ext/oauth/service/OAuthUniversalUser.java b/src/main/java/egovframework/com/ext/oauth/service/OAuthUniversalUser.java index 052033d2..414541f7 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthUniversalUser.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthUniversalUser.java @@ -6,32 +6,33 @@ import nlib.util.StringUtil; public class OAuthUniversalUser { - private String uid; + private String snsId; private String email; - private String userId; - private String userName; + private String loginUserId; + private String name; private String nickName; - private String birthdate; + private String birthday; private String gender; private String serviceName; private String loginIp; private Date lastLogin; + private boolean isValidLogin = false; public boolean isValid() { - return StringUtil.isNotEmpty(uid) && StringUtil.isNotEmpty(userId); + return StringUtil.isNotEmpty(snsId); } - public String getUid() { - return uid; + public String getSnsId() { + return snsId; } - public void setUid(String uid) { - this.uid = uid; + public void setSnsId(String snsId) { + this.snsId = snsId; } public String getEmail() { @@ -42,20 +43,20 @@ public class OAuthUniversalUser { this.email = email; } - public String getUserId() { - return userId; + public String getLoginUserId() { + return loginUserId; } - public void setUserId(String userId) { - this.userId = userId; + public void setLoginUserId(String loginUserId) { + this.loginUserId = loginUserId; } - public String getUserName() { - return userName; + public String getName() { + return name; } - public void setUserName(String userName) { - this.userName = userName; + public void setName(String name) { + this.name = name; } public String getNickName() { @@ -90,12 +91,12 @@ public class OAuthUniversalUser { this.lastLogin = lastLogin; } - public String getBirthdate() { - return birthdate; + public String getBirthday() { + return birthday; } - public void setBirthdate(String birthdate) { - this.birthdate = birthdate; + public void setBirthday(String birthday) { + this.birthday = birthday; } public String getLoginIp() { diff --git a/src/main/java/egovframework/com/ext/oauth/service/OAuthVO.java b/src/main/java/egovframework/com/ext/oauth/service/OAuthVO.java index 85aeecef..8dd173ba 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthVO.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthVO.java @@ -1,10 +1,10 @@ package egovframework.com.ext.oauth.service; -import org.apache.commons.lang3.StringUtils; - import com.github.scribejava.apis.GoogleApi20; import com.github.scribejava.core.builder.api.DefaultApi20; +import nlib.util.StringUtil; + public class OAuthVO implements OAuthConfig { public String getService() { return serviceName; @@ -95,9 +95,9 @@ public class OAuthVO implements OAuthConfig { this.clientSecret = clientSecret; this.redirectUrl = redirectUrl; - this.isGoogle = StringUtils.equalsIgnoreCase(GOOGLE_SERVICE_NAME, serviceName); - this.isNaver = StringUtils.equalsIgnoreCase(NAVER_SERVICE_NAME, serviceName); - this.isKakao = StringUtils.equalsIgnoreCase(KAKAO_SERVICE_NAME, serviceName); + this.isGoogle = StringUtil.equalsIgnoreCase(GOOGLE_SERVICE_NAME, serviceName); + this.isNaver = StringUtil.equalsIgnoreCase(NAVER_SERVICE_NAME, serviceName); + this.isKakao = StringUtil.equalsIgnoreCase(KAKAO_SERVICE_NAME, serviceName); if (isGoogle) { this.api20Instance = GoogleApi20.instance(); diff --git a/src/main/java/nlib/security/SpringSecurityConfig.java b/src/main/java/nlib/security/SpringSecurityConfig.java index 8a6eb302..6af53b54 100644 --- a/src/main/java/nlib/security/SpringSecurityConfig.java +++ b/src/main/java/nlib/security/SpringSecurityConfig.java @@ -15,6 +15,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import nlib.cmm.crypto.NlibPasswordEncoder; +import nlib.cmm.service.NlibProperty; /** *
@@ -87,7 +88,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
 			.antMatchers("/homes/**").permitAll()
 			.anyRequest().authenticated()
 		.and().formLogin()
-			  .loginPage("/login/loginForm.do")
+			  .loginPage(NlibProperty.getString("login.url"))
 			  .permitAll()
 		.and().csrf()
 			  .disable();
diff --git a/src/main/java/nlib/user/service/LoginService.java b/src/main/java/nlib/user/service/LoginService.java
index cbdfcf5e..f0a3ba9a 100644
--- a/src/main/java/nlib/user/service/LoginService.java
+++ b/src/main/java/nlib/user/service/LoginService.java
@@ -1,6 +1,8 @@
 
 package nlib.user.service;
 
+import java.util.HashMap;
+
 import javax.servlet.http.HttpServletRequest;
 
 import nlib.restful.service.DataApiReqVO;
@@ -8,15 +10,23 @@ import nlib.restful.service.DataApiResVO;
 
 public interface LoginService
 {
+
+	//-------------------------------
+	// 로그인 오류코드 
+	//-------------------------------
+	public final String ERR_CODE_REQ_MEMBERSHIP = "ERR_REQ_MEMBERSHIP"; /* 오류코드 : 회원가입 필요 */
+	public final String ERR_CODE_REQ_SNSLOGIN   = "ERR_REQ_SNSLOGIN";   /* 오류코드 : SNS 로그인 필요 */
+	
+	
 	public String login(HttpServletRequest req, String username, String password);
 	
-	public String loginOauth(HttpServletRequest req, String snsUserId, String deptJsessionId);
+	public String loginOauth(HttpServletRequest req, String snsUserId, String councilJsessionId);
 	
-	public String loginDeptSSO(HttpServletRequest req, String snsUserId);
+	public String loginCouncilSSO(HttpServletRequest req, String snsUserId);
 	
-	public String loginDept(HttpServletRequest req, String snsUserId);
+	public String loginCouncil(HttpServletRequest req, String snsUserId);
 
 	public DataApiResVO logout(DataApiReqVO reqVO);
 
-
+	public HashMap selectCouncilInfoByDnsHost(String councilDnsHost);
 }
\ No newline at end of file
diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java
index 81cc39c1..3ac8eace 100644
--- a/src/main/java/nlib/user/service/impl/LoginDAO.java
+++ b/src/main/java/nlib/user/service/impl/LoginDAO.java
@@ -1,6 +1,8 @@
 
 package nlib.user.service.impl;
 
+import java.util.HashMap;
+
 import org.springframework.stereotype.Repository;
 
 import egovframework.com.cmm.service.impl.EgovComAbstractDAO;
@@ -27,4 +29,7 @@ public class LoginDAO extends EgovComAbstractDAO {
 		insert("LoginDAO.insertLoginLog", userVO); 
 	}
 	
+	public HashMap selectCouncilInfoByDnsHost(String councilDnsHost) {
+		return (HashMap) selectOne("LoginDAO.selectCouncilInfoByDnsHost", councilDnsHost);
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java
index 9f81aeb5..0d8d5e48 100644
--- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java
+++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java
@@ -1,6 +1,8 @@
 
 package nlib.user.service.impl;
 
+import java.util.HashMap;
+
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 
@@ -13,10 +15,10 @@ import org.springframework.security.authentication.DisabledException;
 import org.springframework.security.authentication.LockedException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 
+import nlib.cmm.service.NlibProperty;
 import nlib.cmm.session.SessionConfig;
 import nlib.restful.service.DataApiReqVO;
 import nlib.restful.service.DataApiResVO;
@@ -132,51 +134,26 @@ public class LoginServiceImpl implements LoginService
 	/* SNS 연동 SSO를 통한 로그인 처리한다.  
 	 * 
 	 * return값이 null인 경우, 정상적인 로그인 처리 완료
-	 * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) 
-	 * 
+	 * null이 아닌 경우, 오류 코드 
+	 * - REQ-SNS-SSO : SNS 정상적인 로그인이 필요    
+	 * - NEW-MEMBERSHIP : 신규회원가입/회원통합 필요
 	 */
-	public String loginOauth(HttpServletRequest req, String snsUserId, String deptJsessionId)  {
+	public String loginOauth(HttpServletRequest req, String snsId, String councilJsessionId)  {
 		
 		// SNS 연동 사용자UID로 사용자정보 조회 
-		if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso";
+		if(StringUtil.isEmpty(snsId)) return ERR_CODE_REQ_SNSLOGIN;
 		
-		NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(snsUserId);
+		NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(snsId);
 		
 		if(nLoginVO == null) {
-			return "/login/loginForm.do?error=new-membership";
+			return ERR_CODE_REQ_MEMBERSHIP;
 		}
-
-		// 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다.
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getPassword());
-		
-        try {
-	        // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다.
-	        Authentication authentication = authenticationManager.authenticate(token);
-	        
-	        if(authentication.isAuthenticated()) {
-	        	 SessionConfig.setLoginInfo(deptJsessionId, snsUserId);
-	        } else {
-	        	 SessionConfig.setLoginInfo(deptJsessionId, null);
-	        }
-	        
-        } catch (DisabledException e) {
-        	e.printStackTrace();
-            return "/login/loginForm.do?error=locked";
-        } catch (LockedException e) {
-        	e.printStackTrace();
-        	return "/login/loginForm.do?error=disable";
-        } catch (BadCredentialsException e) {
-        	e.printStackTrace();
-        	return "/login/loginForm.do?error=invalid-password";
-        } catch (Exception e) {
-        	e.printStackTrace();
-        	return "/login/loginForm.do?error=other&message=" + e.toString();
-        }
         
+		// 회원가입정보 존재하는 SNS 아이디임을 확인 완료 
 		return null;
 	}
 	
-	public String loginDeptSSO(HttpServletRequest req, String snsUserId)  {
+	public String loginCouncilSSO(HttpServletRequest req, String snsUserId)  {
 		
 		// SNS 연동 사용자UID로 사용자정보 조회 
 		if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso";
@@ -230,7 +207,7 @@ public class LoginServiceImpl implements LoginService
 	 * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) 
 	 * 
 	 */
-	public String loginDept(HttpServletRequest req, String snsUserId)  {
+	public String loginCouncil(HttpServletRequest req, String snsUserId)  {
 		
 		// SNS 연동 사용자UID로 사용자정보 조회 
 		if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso";
@@ -279,5 +256,9 @@ public class LoginServiceImpl implements LoginService
 	public DataApiResVO logout(DataApiReqVO reqVO)  {
 		return null;
 	}
+	
+	public HashMap selectCouncilInfoByDnsHost(String councilDnsHost) {
+		return loginDAO.selectCouncilInfoByDnsHost(councilDnsHost);
+	}
 
 }
\ No newline at end of file
diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java
index 743d648d..e1640961 100644
--- a/src/main/java/nlib/user/web/LoginController.java
+++ b/src/main/java/nlib/user/web/LoginController.java
@@ -1,6 +1,7 @@
 
 package nlib.user.web;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.annotation.Resource;
@@ -48,7 +49,11 @@ import nlib.util.StringUtil;
  * @ 수정일 수정자 수정내용 
  * @ ------------ -------- --------------------------- 
  * @ 2021. 7. 9. KNKIM 최초 생성
- *
+ * @ 2021. 8.18. RESTful -> DB접속 방식으로 변경 처리 
+ * @ 2021. 8.19. 지방문화원별 다른 도메인 호스트 접속 처리를 위한 Spring Security 변경 작업, 네이버 전자정보 프레임워크 기반으로 변경  
+ * @ 2021. 8.24. 테이블 변경에 따른 항목명 변경 
+ * 
+ *  
  * 
  * @author 이씨플라자 * DIGITALSHIP KNKIM
  * @since 2021. 7. 9.
@@ -61,32 +66,87 @@ public class LoginController {
 	private static final Logger log = LoggerFactory.getLogger(LoginController.class);
 	
 	//-------------------------------------------
-	// SNS 연동 
+	// SNS 연동 환경설정 정보 : context-oauth.xml 참고 
 	//-------------------------------------------
 	@Inject
-	private OAuthVO naverAuthVO;
+	private OAuthVO naverAuthVO; /* 네이버 */
 	
 	@Inject
-	private OAuthVO googleAuthVO;
+	private OAuthVO googleAuthVO; /* 구글 */
 
 	@Inject
-	private OAuthVO kakaoAuthVO;
+	private OAuthVO kakaoAuthVO; /* 카카오 */
 	//-------------------------------------------
 	
 
-//	/* NaverLoginBO */
-//	private NaverLoginBO naverLoginBO;
-//	private String apiResult = null;
-
-//	@Autowired
-//	private void setNaverLoginBO(NaverLoginBO naverLoginBO) {
-//		this.naverLoginBO = naverLoginBO;
-//	}
-
 	@Resource(name = "loginService")
 	private LoginService loginService;
 
 
+	/**
+	 * 각 지방문화원 사이트에서 로그인을 위해서 최초 접속한다. 
+	 * 지방문화원 정보를 확인하여 로그인처리가 진행될 수 있도록 한다. 
+	 *  
+	 * @param req
+	 * @param res
+	 * @param session
+	 * @param returnUrl
+	 * @param model
+	 * @return
+	 * @throws Exception
+	 */
+	@RequestMapping("/login/loginCouncil.do")
+	public String loginCouncil(
+			HttpServletRequest req, 
+			HttpServletResponse res,
+			HttpSession session,
+			@RequestParam(required = false) String returnUrl,
+			ModelMap model) throws Exception {
+		
+		String url = req.getRequestURL().toString();
+		String councilHomeUrl = url.replaceAll(req.getRequestURI(), "") + req.getContextPath();
+		String councilReturnUrl = councilHomeUrl + (StringUtil.isEmpty(returnUrl) ? "/" : returnUrl);
+		String councilDnsHost = StringUtil.getHostName(url);
+		
+		// returnUrl 정보 설정 
+		if(StringUtil.isEmpty(returnUrl)) {
+			RequestCache cache = new HttpSessionRequestCache();
+			SavedRequest savedRequest = cache.getRequest(req, res);
+			if (savedRequest != null) {
+				councilReturnUrl = savedRequest.getRedirectUrl();
+				log.debug("loginCouncil > HttpSessionRequestCache에서 획득 councilReturnUrl = " + councilReturnUrl);				
+			}
+		}
+		
+		// 지방문화원 코드 확인
+		HashMap councilInfo = loginService.selectCouncilInfoByDnsHost(councilDnsHost);
+		String councilCd = (councilInfo == null ? null : councilInfo.get("councilCd"));
+		String councilNm = (councilInfo == null ? null : councilInfo.get("councilNm"));
+		
+		session.setAttribute("councilDnsHost", councilDnsHost);
+		session.setAttribute("councilReturnUrl", councilReturnUrl);
+		session.setAttribute("councilHomeUrl", councilHomeUrl);
+		session.setAttribute("councilCd", councilCd);
+		session.setAttribute("councilNm", councilNm);
+		
+		log.debug("loginCouncil > REQ URL = " + url);
+		log.debug("loginCouncil > councilJsessionId = " + session.getId());
+		log.debug("loginCouncil > councilDnsHost = " + councilDnsHost);
+		log.debug("loginCouncil > councilReturnUrl = " + councilReturnUrl);
+		log.debug("loginCouncil > councilHomeUrl = " + councilHomeUrl);
+		log.debug("loginCouncil > councilCd = " + councilCd);
+		log.debug("loginCouncil > councilNm = " + councilNm);
+		
+		String params = "councilJsessionId=" + session.getId() + 
+				"&councilDnsHost=" + councilDnsHost + 
+				"&councilCd=" + councilCd +
+				"&councilNm=" + StringUtil.encodeBase64(councilNm) +
+				"&councilHomeUrl="   + StringUtil.encodeBase64(councilHomeUrl) +
+				"&councilReturnUrl=" + StringUtil.encodeBase64(councilReturnUrl);
+		
+		return "redirect:" + NlibProperty.getString("nculture.login.redirect.url") + "?" + params;
+	}
+
 	/**
 	 * 로그인 정보 입력 화면을 출력한다.
 	 * 
@@ -109,33 +169,39 @@ public class LoginController {
 		//----------------------------------------------
 		// 지방문화원 사이트에서 접속한 경우, 지방문화원 정보 확인 
 		//----------------------------------------------
-		String deptJsessionId = paramMap.get("deptJsessionId");
-		String deptHostName = paramMap.get("deptHostName");
-		String deptReturnUrl = paramMap.get("deptReturnUrl");
-		String deptHomeUrl = paramMap.get("deptHomeUrl");
+		String councilJsessionId = paramMap.get("councilJsessionId");
+		String councilDnsHost    = paramMap.get("councilDnsHost");
+		String councilReturnUrl  = StringUtil.decodeBase64(paramMap.get("councilReturnUrl"));
+		String councilHomeUrl    = StringUtil.decodeBase64(paramMap.get("councilHomeUrl"));
+		String councilCd         = paramMap.get("councilCd");
+		String councilNm         = StringUtil.decodeBase64(paramMap.get("councilNm"));
 		
-		log.debug("loginForm > deptJsessionId = " + deptJsessionId);
-		log.debug("loginForm > deptHostName = " + deptHostName);
-		log.debug("loginForm > deptReturnUrl = " + deptReturnUrl);
-		log.debug("loginForm > deptHomeUrl = " + deptHomeUrl);
+		log.debug("loginForm > councilJsessionId = " + councilJsessionId);
+		log.debug("loginForm > councilDnsHost = " + councilDnsHost);
+		log.debug("loginForm > councilReturnUrl = " + councilReturnUrl);
+		log.debug("loginForm > councilHomeUrl = " + councilHomeUrl);
+		log.debug("loginForm > councilCd = " + councilCd);
+		log.debug("loginForm > councilNm = " + councilNm);
 
-		session.setAttribute("deptJsessionId", deptJsessionId);
-		session.setAttribute("deptHostName", deptHostName);
-		session.setAttribute("deptReturnUrl", (StringUtil.isNotEmpty(deptReturnUrl) ? StringUtil.decodeBase64(deptReturnUrl) : null));
-		session.setAttribute("deptHomeUrl", (StringUtil.isNotEmpty(deptHomeUrl) ? StringUtil.decodeBase64(deptHomeUrl) : null));
+		session.setAttribute("councilJsessionId", councilJsessionId);
+		session.setAttribute("councilDnsHost", councilDnsHost);
+		session.setAttribute("councilReturnUrl", councilReturnUrl);
+		session.setAttribute("councilHomeUrl"  , councilHomeUrl);
+		session.setAttribute("councilCd"  , councilCd);
+		session.setAttribute("councilNm"  , councilNm);
 		
 		//----------------------------------------------
 		// SNS 연동 URL 생성 
 		//----------------------------------------------
-		OAuthLogin naverLogin = new OAuthLogin(naverAuthVO, deptJsessionId);
+		OAuthLogin naverLogin = new OAuthLogin(naverAuthVO, councilJsessionId);
 		log.debug("naverLogin.getOAuthURL() = "+naverLogin.getOAuthURL());
 		model.addAttribute("naverUrl", naverLogin.getOAuthURL());
 		
-		OAuthLogin googleLogin = new OAuthLogin(googleAuthVO, deptJsessionId);
+		OAuthLogin googleLogin = new OAuthLogin(googleAuthVO, councilJsessionId);
 		log.debug("googleLogin.getOAuthURL() = "+googleLogin.getOAuthURL());
 		model.addAttribute("googleUrl", googleLogin.getOAuthURL());
 
-		OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO, deptJsessionId);
+		OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO, councilJsessionId);
 		log.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL());
 		model.addAttribute("kakaoUrl", kakaoLogin.getOAuthURL());
 		
@@ -146,154 +212,8 @@ public class LoginController {
 		return "nlib/login/loginForm";
 	}
 	
-//	@RequestMapping("/login/loginForm.do")
-//	public String loginForm(HttpServletRequest req, 
-//			@RequestParam(required = false) String error,
-//			@RequestParam(required = false) String message,
-//			@RequestParam(required = false) String logout, 
-//			Model model, 
-//			HttpSession session) {
-//		
-//		
-//		model.addAttribute("error", error);
-//		model.addAttribute("message", message);
-//		model.addAttribute("logout", String.format("로그아웃하였습니다 %s", logout));
-//		
-//		// SNS 연동 URL 생성 
-//		OAuthLogin naverLogin = new OAuthLogin(naverAuthVO);
-//		log.debug("naverLogin.getOAuthURL() = "+naverLogin.getOAuthURL());
-//		model.addAttribute("naverUrl", naverLogin.getOAuthURL());
-//		
-//		OAuthLogin googleLogin = new OAuthLogin(googleAuthVO);
-//		log.debug("googleLogin.getOAuthURL() = "+googleLogin.getOAuthURL());
-//		model.addAttribute("googleUrl", googleLogin.getOAuthURL());
-//
-//		OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO);
-//		log.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL());
-//		model.addAttribute("kakaoUrl", kakaoLogin.getOAuthURL());
-//		
-//		model.addAttribute("coutTest", "서울시 마포구");
-//		
-//		return "nlib/login/loginForm";
-//	}
 	
-//	@RequestMapping("/login/loginForm_BK20210817.do")
-//	public String loginForm_BK20210817(HttpServletRequest req, @RequestParam(required = false) String error,
-//			@RequestParam(required = false) String logout, Model model, HttpSession session) {
-//		if (error != null) {
-//			model.addAttribute("error", String.format("ID와 비밀번호를 확인하여 주시기 바랍니다. %s", error));
-//		}
-//		if (logout != null) {
-//			model.addAttribute("logout", String.format("로그아웃하였습니다 %s", logout));
-//		}
-//		// 네이버 로그인 URL 생성
-//		/* 네이버아이디로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
-//		naverLoginBO.setRedirect_url("http://nlib.nculture.org/nlib/login/naverCallback.do");
-//		String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
-//		
-//		// 구글 로그인 URL 생성
-//		String googleUrl = "https://accounts.google.com/o/oauth2/v2/auth?" 
-//				+ "client_id=879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com" 
-//				+ "&redirect_uri=http://nlib.nculture.org/nlib/login/googleCallback.do"
-//				+ "&response_type=code"
-//				+ "&scope=email%20profile%20openid"
-//				+ "&access_type=offline";
-//		
-//		// 카카오 로그인 URL 생성
-//		String k_redirect_url="http://nlib.nculture.org/nlib/login/kakaoCallback.do";
-//		String kakaoUrl = KakaoController.getAuthorizationUrl(session,k_redirect_url);
-//
-//		model.addAttribute("naverUrl", naverAuthUrl);
-//		model.addAttribute("googleUrl", googleUrl);
-//		model.addAttribute("kakaoUrl", kakaoUrl);
-//		
-//		return "nlib/login/loginForm";
-//	}
-//	
-//	@RequestMapping(value = "/login/{oauthService}Callback.do", method = { RequestMethod.GET, RequestMethod.POST})
-//	public String oauthLoginCallback(
-//			HttpServletRequest req, 
-//			@PathVariable String oauthService,
-//			Model model, 
-//			@RequestParam String code, 
-//			@RequestParam Map paramMap,
-//			HttpSession session) throws Exception {
-//		
-//		String redirectUrl = "/index.do";
-//		
-//		log.debug("oauthLoginCallback: service={}", oauthService);
-//		log.debug("===>>> code = "+ code);
-//		
-//		OAuthVO oauthVO = null;
-//		if (StringUtils.equals(OAuthConfig.GOOGLE_SERVICE_NAME, oauthService))
-//			oauthVO = googleAuthVO;
-//		else if (StringUtils.equals(OAuthConfig.NAVER_SERVICE_NAME, oauthService))
-//			oauthVO = naverAuthVO;
-//		else if (StringUtils.equals(OAuthConfig.KAKAO_SERVICE_NAME, oauthService))
-//			oauthVO = kakaoAuthVO;
-//		else {
-//			throw new Exception("SNS 연동 콜백정보가 올바르지 않습니다.");
-//		}
-//		
-//		// 1. code를 이용해서 Access Token 받기
-//		// 2. Access Token을 이용해서 사용자 제공정보 가져오기
-//		String deptJsessionId = paramMap.get("deptJsessionId");
-//		OAuthLogin oauthLogin = new OAuthLogin(oauthVO, deptJsessionId);
-//		
-//		OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시
-//		log.debug("Profile ===>>" + oauthUser);
-//		
-//		//-----------------------------------------------------------------
-//		// 호스트에 따른 별도 로그인 처리 
-//		//-----------------------------------------------------------------
-//		// 해당 호스트로 로그인처리 요청
-//		//loginService.loginDept(req, oauthUser.getUid());
-//		
-//		//-----------------------------------------------------------------
-//
-//		String loginResult = loginService.loginOauth(req, oauthUser.getUid(), deptJsessionId);
-//		
-//		// oAuth를 통한 SNS연동이 실패한 경우 
-//		if(oauthUser == null || !oauthUser.isValid()) {
-//			model.addAttribute("message", "먼저 회원가입하신 후, 이용하여 주시기 바랍니다.");
-//			redirectUrl = NlibProperty.getString("member.new.url"); // "/member/insertMemberInfoForm.do"
-//		}
-//		// 정상 SNS 연동 로그인 
-//		else if(oauthUser.isValid() && loginResult == null) {
-//			// 세션에 설정된 redirect 주소 확인
-//			model.addAttribute("message", "정상적으로 로그인되었습니다.");
-//		}
-//		// SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환   
-//		else {
-//			model.addAttribute("code", "GONEW");
-//			model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?");
-//			redirectUrl = loginResult;
-//		}
-//		String deptReturnUrl = (String)session.getAttribute("deptReturnUrl");
-//		if(StringUtil.isNotEmpty(deptReturnUrl)) redirectUrl = deptReturnUrl;
-//		
-//		return "redirect:" + redirectUrl;
-//	}
 	
-	// 네이버 로그인 성공시 callback호출 메소드
-//	@RequestMapping(value = "/login/naverCallback_BK20210817.do", method = { RequestMethod.GET, RequestMethod.POST })
-//	public String naverCallback_BK20210817(Model model, @RequestParam String code, @RequestParam String state, HttpSession session)
-//			throws IOException, ParseException {
-//		OAuth2AccessToken oauthToken;
-//		oauthToken = naverLoginBO.getAccessToken(session, code, state);
-//		// 로그인 사용자 정보를 읽어온다.
-//		apiResult = naverLoginBO.getUserProfile(oauthToken);
-//		JSONParser parser = new JSONParser();
-//		Object obj = parser.parse(apiResult);
-//		JSONObject jsonObj = (JSONObject) obj;
-//		JSONObject response_obj = (JSONObject) jsonObj.get("response");
-//		String email = (String) response_obj.get("email");
-//		model.addAttribute("result", apiResult);
-//
-//		/* 네이버 로그인 성공 페이지 View 호출 */
-//		return "naverSuccess";
-//	}
-//
 //	// 구글 로그인 콜백
 //	@RequestMapping(value = "/login/googleCallback.do")
 //	public String googleCallback(@RequestParam(value = "code") String authCode, HttpSession session, Model model,
@@ -377,123 +297,68 @@ public class LoginController {
 //		}// end kakaoLogin()
 //	
 
-	//	@RequestMapping("/login/loginForm.do")
-	//	public String loginForm(HttpServletRequest req, 
-	//			@RequestParam(required = false) String error,
-	//			@RequestParam(required = false) String message,
-	//			@RequestParam(required = false) String logout, 
-	//			Model model, 
-	//			HttpSession session) {
-	//		
-	//		
-	//		model.addAttribute("error", error);
-	//		model.addAttribute("message", message);
-	//		model.addAttribute("logout", String.format("로그아웃하였습니다 %s", logout));
-	//		
-	//		// SNS 연동 URL 생성 
-	//		OAuthLogin naverLogin = new OAuthLogin(naverAuthVO);
-	//		log.debug("naverLogin.getOAuthURL() = "+naverLogin.getOAuthURL());
-	//		model.addAttribute("naverUrl", naverLogin.getOAuthURL());
-	//		
-	//		OAuthLogin googleLogin = new OAuthLogin(googleAuthVO);
-	//		log.debug("googleLogin.getOAuthURL() = "+googleLogin.getOAuthURL());
-	//		model.addAttribute("googleUrl", googleLogin.getOAuthURL());
-	//
-	//		OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO);
-	//		log.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL());
-	//		model.addAttribute("kakaoUrl", kakaoLogin.getOAuthURL());
-	//		
-	//		model.addAttribute("coutTest", "서울시 마포구");
-	//		
-	//		return "nlib/login/loginForm";
-	//	}
-		
-	//	@RequestMapping("/login/loginForm_BK20210817.do")
-	//	public String loginForm_BK20210817(HttpServletRequest req, @RequestParam(required = false) String error,
-	//			@RequestParam(required = false) String logout, Model model, HttpSession session) {
-	//		if (error != null) {
-	//			model.addAttribute("error", String.format("ID와 비밀번호를 확인하여 주시기 바랍니다. %s", error));
-	//		}
-	//		if (logout != null) {
-	//			model.addAttribute("logout", String.format("로그아웃하였습니다 %s", logout));
-	//		}
-	//		// 네이버 로그인 URL 생성
-	//		/* 네이버아이디로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
-	//		naverLoginBO.setRedirect_url("http://nlib.nculture.org/nlib/login/naverCallback.do");
-	//		String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
-	//		
-	//		// 구글 로그인 URL 생성
-	//		String googleUrl = "https://accounts.google.com/o/oauth2/v2/auth?" 
-	//				+ "client_id=879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com" 
-	//				+ "&redirect_uri=http://nlib.nculture.org/nlib/login/googleCallback.do"
-	//				+ "&response_type=code"
-	//				+ "&scope=email%20profile%20openid"
-	//				+ "&access_type=offline";
-	//		
-	//		// 카카오 로그인 URL 생성
-	//		String k_redirect_url="http://nlib.nculture.org/nlib/login/kakaoCallback.do";
-	//		String kakaoUrl = KakaoController.getAuthorizationUrl(session,k_redirect_url);
-	//
-	//		model.addAttribute("naverUrl", naverAuthUrl);
-	//		model.addAttribute("googleUrl", googleUrl);
-	//		model.addAttribute("kakaoUrl", kakaoUrl);
-	//		
-	//		return "nlib/login/loginForm";
-	//	}
-	//	
-		@RequestMapping(value = "/login/{oauthService}Callback.do", method = { RequestMethod.GET, RequestMethod.POST})
+		@RequestMapping(value = {"/login/{oauthServiceName}Callback.do", "/login/{oauthServiceName}/callback.do"})
 		public String oauthLoginCallback(
 				HttpServletRequest req, 
-				@PathVariable String oauthService,
-				Model model, 
-				@RequestParam String code, 
+				@PathVariable String oauthServiceName,
 				@RequestParam Map paramMap,
+				Model model, 
 				HttpSession session) throws Exception {
 			
-			String redirectUrl = "/index.do";
+			String redirectUrl = NlibProperty.getString("home.uri"); // "/index.do";
+			String code = paramMap.get("code");
+			String councilJsessionId = paramMap.get("councilJsessionId");
 			
-			log.debug("oauthLoginCallback: service={}", oauthService);
-			log.debug("===>>> code = "+ code);
+			log.debug("oauthLoginCallback: code = ", code);
 			
+			// SNS 클라이언트 설정 정보 할당 
 			OAuthVO oauthVO = null;
-			if (StringUtils.equals(OAuthConfig.GOOGLE_SERVICE_NAME, oauthService))
+			if (StringUtil.equals(OAuthConfig.GOOGLE_SERVICE_NAME, oauthServiceName))
 				oauthVO = googleAuthVO;
-			else if (StringUtils.equals(OAuthConfig.NAVER_SERVICE_NAME, oauthService))
+			else if (StringUtil.equals(OAuthConfig.NAVER_SERVICE_NAME, oauthServiceName))
 				oauthVO = naverAuthVO;
-			else if (StringUtils.equals(OAuthConfig.KAKAO_SERVICE_NAME, oauthService))
+			else if (StringUtil.equals(OAuthConfig.KAKAO_SERVICE_NAME, oauthServiceName))
 				oauthVO = kakaoAuthVO;
 			else {
 				throw new Exception("SNS 연동 콜백정보가 올바르지 않습니다.");
 			}
 			
-			String deptJsessionId = paramMap.get("deptJsessionId");
-			
+			//-----------------------------------------------
 			// 1. code를 이용해서 Access Token 받기
 			// 2. Access Token을 이용해서 사용자 제공정보 가져오기
-			OAuthLogin oauthLogin = new OAuthLogin(oauthVO, deptJsessionId);
+			//-----------------------------------------------
+			OAuthLogin oauthLogin = new OAuthLogin(oauthVO, councilJsessionId);
 			
 			OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시
-			log.debug("Profile ===>>" + oauthUser);
-			
-			String loginResult = loginService.loginOauth(req, oauthUser.getUid(), deptJsessionId);
+			log.debug("oauthLoginCallback > Profile ===>>" + oauthUser.toString());
 			
 			// oAuth를 통한 SNS연동이 실패한 경우 
 			if(oauthUser == null || !oauthUser.isValid()) {
 				model.addAttribute("message", "먼저 회원가입하신 후, 이용하여 주시기 바랍니다.");
 				redirectUrl = NlibProperty.getString("member.new.url"); // "/member/insertMemberInfoForm.do"
+				return "redirect:" + redirectUrl;
 			}
-			// 정상 SNS 연동 로그인 
-			else if(oauthUser.isValid() && loginResult == null) {
+			
+			// 등록된 사용자 여부 확인 
+			String loginResult = loginService.loginOauth(req, oauthUser.getSnsId(), councilJsessionId);
+			
+			// 정상 SNS 연동 로그인
+			if(loginResult == null) {
 				// 세션에 설정된 redirect 주소 확인
 				model.addAttribute("message", "정상적으로 로그인되었습니다.");
-				String deptHomeUrl = (String)session.getAttribute("deptHomeUrl");
-				redirectUrl = deptHomeUrl + "/login/loginDeptSSO.do";
+				String councilHomeUrl = (String)session.getAttribute("councilHomeUrl");
+				redirectUrl = councilHomeUrl + "/login/loginCouncilSSO.do";
+				return "redirect:" + redirectUrl;
 			}
+			
 			// SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환   
-			else {
-				model.addAttribute("code", "GONEW");
+			model.addAttribute("error", loginResult);
+			if(StringUtil.equals(loginResult, loginService.ERR_CODE_REQ_MEMBERSHIP)) {
 				model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?");
-				redirectUrl = loginResult;
+				redirectUrl = NlibProperty.getString("member.new.url");
+			} else if(StringUtil.equals(loginResult, loginService.ERR_CODE_REQ_SNSLOGIN)) {
+				model.addAttribute("message", "먼저 SNS 로그인 바랍니다.");
+				redirectUrl = NlibProperty.getString("login.back.url");
 			}
 			
 			return "redirect:" + redirectUrl;
@@ -531,39 +396,8 @@ public class LoginController {
 		return "redirect:" + redirectUrl;
 	}
 	
-	@RequestMapping("/login/loginDept.do")
-	public String loginDept(
-			HttpServletRequest req, 
-			HttpServletResponse res,
-			HttpSession session,
-			@RequestParam(required = false) String returnUrl,
-			ModelMap model) throws Exception {
-		
-		String url = req.getRequestURL().toString();
-		String deptHomeUrl = url.replaceAll(req.getRequestURI(), "") + req.getContextPath();
-		String deptReturnUrl = deptHomeUrl + (StringUtil.isEmpty(returnUrl) ? "/" : returnUrl);
-		String deptHostName = StringUtil.getHostName(url);
-		
-		session.setAttribute("deptHostName", deptHostName);
-		session.setAttribute("deptReturnUrl", deptReturnUrl);
-		session.setAttribute("deptHomeUrl", deptHomeUrl);
-		
-		log.debug("REQ URL = " + url);
-		log.debug("deptJsessionId = " + session.getId());
-		log.debug("deptHostName = " + deptHostName);
-		log.debug("deptReturnUrl = " + deptReturnUrl);
-		log.debug("deptHomeUrl = " + deptHomeUrl);
-		
-		String params = "deptJsessionId=" + session.getId() + 
-				"&deptHostName=" + deptHostName + 
-				"&deptHomeUrl="   + StringUtil.encodeBase64(deptHomeUrl) +
-				"&deptReturnUrl=" + StringUtil.encodeBase64(deptReturnUrl);
-		
-		return "redirect:" + NlibProperty.getString("nculture.login.redirect.url") + "?" + params;
-	}
-	
-	@RequestMapping("/login/loginDeptSSO.do")
-	public String loginDeptSSO(
+	@RequestMapping("/login/loginCouncilSSO.do")
+	public String loginCouncilSSO(
 			HttpServletRequest req, 
 			HttpServletResponse res,
 			HttpSession session,
@@ -572,16 +406,16 @@ public class LoginController {
 		String redirectUrl = "/index.do";
 		
 		String snsUserId = SessionConfig.getLoginInfo(session.getId());
-		String loginResult = loginService.loginDeptSSO(req, snsUserId);
+		String loginResult = loginService.loginCouncilSSO(req, snsUserId);
 		
 		// oAuth를 통한 SNS연동이 실패한 경우 
 		if(loginResult == null) {
 			// 세션에 설정된 redirect 주소 확인
-			String deptReturnUrl = (String)session.getAttribute("deptReturnUrl");
+			String councilReturnUrl = (String)session.getAttribute("councilReturnUrl");
 			
-			log.debug("loginDeptSSO > deptReturnUrl = " + deptReturnUrl);
-			if(StringUtil.isNotEmpty(deptReturnUrl)) {
-				redirectUrl = deptReturnUrl;
+			log.debug("loginCouncilSSO > councilReturnUrl = " + councilReturnUrl);
+			if(StringUtil.isNotEmpty(councilReturnUrl)) {
+				redirectUrl = councilReturnUrl;
 			}
 		}
 		// SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환   
diff --git a/src/main/java/nlib/util/StringUtil.java b/src/main/java/nlib/util/StringUtil.java
index 493f07cd..8de7a671 100644
--- a/src/main/java/nlib/util/StringUtil.java
+++ b/src/main/java/nlib/util/StringUtil.java
@@ -6,14 +6,11 @@ import java.text.SimpleDateFormat;
 import java.util.Base64;
 import java.util.Base64.Decoder;
 import java.util.Base64.Encoder;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.util.Locale;
 
-import egovframework.com.utl.fcc.service.EgovStringUtil;
-import nlib.user.web.LoginController;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * 
@@ -37,7 +34,7 @@ import nlib.user.web.LoginController;
  * @version 1.0
  *
  */
-public class StringUtil extends EgovStringUtil {
+public class StringUtil extends StringUtils {
 	
 	private static final Logger log = LoggerFactory.getLogger(StringUtil.class);
 	
@@ -47,8 +44,8 @@ public class StringUtil extends EgovStringUtil {
 	 * @param str
 	 * @return
 	 */
-	public static boolean isEmpty(String str) {
-		return str == null || str.trim().length() == 0;
+	public static boolean isEmpty(final CharSequence cs) {
+		return isBlank(cs);
 	}
 	
 	/**
@@ -69,7 +66,7 @@ public class StringUtil extends EgovStringUtil {
 	 * @return
 	 */
 	public static boolean isNotEmpty(String str) {
-		return !isEmpty(str);
+		return !isBlank(str);
 	}
 	
 	/**
@@ -127,7 +124,7 @@ public class StringUtil extends EgovStringUtil {
 	 */
 	public static String encodeBase64(String str) {
 
-		if(str == null) return null;
+		if(isEmpty(str)) return "";
 		
 		Encoder encoder = Base64.getEncoder();
 		return new String(encoder.encode(str.getBytes()));
@@ -140,7 +137,7 @@ public class StringUtil extends EgovStringUtil {
 	 */
 	public static String decodeBase64(String str) {
 
-		if(str == null) return null;
+		if(isEmpty(str)) return "";
 		
 		Decoder decoder = Base64.getDecoder();
 		return new String(decoder.decode(str.getBytes()));
diff --git a/src/main/resources/egovframework/mapper/config/mapper-config.xml b/src/main/resources/egovframework/mapper/config/mapper-config.xml
index 03e9d61a..4cca8ee2 100644
--- a/src/main/resources/egovframework/mapper/config/mapper-config.xml
+++ b/src/main/resources/egovframework/mapper/config/mapper-config.xml
@@ -12,7 +12,8 @@
     
     
     
-        
+        
+        
         
         
     
diff --git a/src/main/resources/egovframework/mapper/nlib/cmm/CMM_CODE_SQL.xml b/src/main/resources/egovframework/mapper/nlib/cmm/CodeDAO_SQL.xml
similarity index 88%
rename from src/main/resources/egovframework/mapper/nlib/cmm/CMM_CODE_SQL.xml
rename to src/main/resources/egovframework/mapper/nlib/cmm/CodeDAO_SQL.xml
index 88019a4c..2c7492a8 100644
--- a/src/main/resources/egovframework/mapper/nlib/cmm/CMM_CODE_SQL.xml
+++ b/src/main/resources/egovframework/mapper/nlib/cmm/CodeDAO_SQL.xml
@@ -3,7 +3,7 @@
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
 
- 	
 		SELECT B.S_CODE_ID 
 		     , B.S_CODE_NM
 		FROM SM_CODE_M A,
diff --git a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml
index 42fcf7f2..c0cae348 100644
--- a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml
+++ b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml
@@ -31,12 +31,20 @@
 		FROM UAC_CLTR_DB.MB_INFO A /* 사용자정보 */
 		JOIN UAC_CLTR_DB.MB_SNS B  /* 사용자 SNS 정보 */
 		ON A.MB_INFO_ID = B.MB_INFO_ID 
-		WHERE B.SNS_ID = '#{snsId}'
-		  AND SNS_TYPE = '#{snsType}'
+		WHERE B.SNS_ID = #{snsId}
+		  AND SNS_TYPE = #{snsType}
 		  AND B.UNLINK_DD IS NULL /* 연동해제건 제외 */	
 		LIMIT 1			
  	
-
+ 	
+ 	
+    
     
 		INSERT INTO SM_ACC_LOG /* 접속로그 */ 
 		(    USER_ID
diff --git a/src/main/resources/nlib/nlib.properties b/src/main/resources/nlib/nlib.properties
index 12ca478f..0227b47a 100644
--- a/src/main/resources/nlib/nlib.properties
+++ b/src/main/resources/nlib/nlib.properties
@@ -14,6 +14,9 @@
 #   8.  value\uac12 \ub4a4\uc5d0 \uc2a4\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \uc11c\ube14\ub9bf\uc5d0\uc11c \ucc38\uc870\ud560\ub54c\ub294 \uc5d0\ub7ec\ubc1c\uc0dd\ud560 \uc218 \uc788\uc73c\ubbc0\ub85c trim()\ud558\uac70\ub098 \ub9c8\uc9c0\ub9c9 \uacf5\ubc31\uc5c6\uc774 properties \uac12\uc744 \uc124\uc815\ud560\uac83
 #-----------------------------------------------------------------------
 
+# \uba54\uc778\ud648\ud398\uc774\uc9c0 URI 
+home.uri = /index.do
+
 #----------------------------------------
 # DataAPI \uc811\uc18d\uc815\ubcf4 
 #----------------------------------------
@@ -77,32 +80,39 @@ search.managerPort = 7800
 
 
 #----------------------------------------
-# SNS SSO 
+# SNS SSO \ucc98\ub9ac URL \uc815\ubcf4 (\ud074\ub77c\uc774\uc5b8\ud2b8 \uc124\uc815\uc815\ubcf4 : context-oauth.xml \ucc38\uc870)  
 #----------------------------------------
-# Naver : registration
-oauth2.client.registration.naver.client-id = (Client ID)
-oauth2.client.registration.naver.client-secret = (Client Secret)
-oauth2.client.registration.naver.redirect_uri={baseUrl}/{action}/oauth2/code/{registrationId}
-oauth2.client.registration.naver.authorization-grant-type=authorization_code
-oauth2.client.registration.naver.scope=name,email,profile_image
-oauth2.client.registration.naver.client-name=Naver
-
-# Naver : Provider
-oauth2.client.provider.naver.authorization-uri = https://nid.naver.com/oauth2.0/authorize
-oauth2.client.provider.naver.token-uri = https://nid.naver.com/oauth2.0/token
-oauth2.client.provider.naver.user-info-uri = https://openapi.naver.com/v1/nid/me
+# \ub124\uc774\ubc84 
+oauth2.client.provider.naver.name  = NAVER
+oauth2.client.provider.naver.authorization-uri   = https://nid.naver.com/oauth2.0/authorize
+oauth2.client.provider.naver.token-uri           = https://nid.naver.com/oauth2.0/token?grant_type=authorization_code
+oauth2.client.provider.naver.user-info-uri       = https://openapi.naver.com/v1/nid/me
 oauth2.client.provider.naver.user-name-attribute = response
 
+# \uad6c\uae00 
+oauth2.client.provider.google.name = GOOGLE
+oauth2.client.provider.google.user-info-uri      = https://www.googleapis.com/plus/v1/people/me
+
+# \uce74\uce74\uc624 
+oauth2.client.provider.kakao.name  = KAKAO
+oauth2.client.provider.kakao.authorization-uri   = https://kauth.kakao.com/oauth/authorize
+oauth2.client.provider.kakao.token-uri           = https://kauth.kakao.com/oauth/token?client_id=
+oauth2.client.provider.kakao.user-info-uri       = https://kapi.kakao.com/v2/user/me
+
 
 #----------------------------------------
 # \uc190\ub2d8\uc815\ubcf4
 #----------------------------------------
 guest.userid = GUEST
+
 #----------------------------------------
 # \ub85c\uadf8\uc778/\ud68c\uc6d0\uac00\uc785\uad00\ub828 URL \uc815\ubcf4 
 #----------------------------------------
 member.new.url = /member/insertMemberInfoForm.do
-member.login.url = /member/insertMemberInfoForm.do
+# \ub85c\uadf8\uc778 \ub610\ub294 \uad8c\ud55c\uc5c6\ub294 \uacbd\uc6b0, \ub85c\uadf8\uc778\uc73c\ub85c \uc804\ud658\ucc98\ub9ac\ub418\uc5b4 \uc811\uc18d\ub418\ub294 \ucd5c\ucd08 \uc8fc\uc18c 
+login.url      = /login/loginCouncil.do
+# \ub85c\uadf8\uc778 \ubb38\uc81c \ubc1c\uc0dd \uc2dc, \ub2e4\uc2dc \ub9ac\ub2e4\uc774\ub809\ud2b8\ub420 \ub85c\uadf8\uc778\ud654\uba74 \uc8fc\uc18c  
+login.back.url = /login/loginForm.do
 # \uc9c0\ubc29\ubb38\ud654\uc6d0\uc5d0\uc11c \uc811\uc18d\uc2dc \ub9ac\ub2e4\uc774\ub809\ud2b8\ub420 URL \uc815\ubcf4 
 nculture.login.redirect.url = http://nlib.nculture.org/nlib/login/loginForm.do  
 
diff --git a/src/main/webapp/homes/seoul.jsp b/src/main/webapp/homes/seoul.jsp
index 6d88b279..7bdd2110 100644
--- a/src/main/webapp/homes/seoul.jsp
+++ b/src/main/webapp/homes/seoul.jsp
@@ -26,6 +26,11 @@ JSESSIONID = <%=session.getId() %>
  
 
+

HOME

+HOME

+

로그인

로그인