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 79e66b36..9195236e 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthConfig.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthConfig.java @@ -4,18 +4,18 @@ import nlib.cmm.service.NlibProperty; public interface OAuthConfig { - 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 GOOGLE_SERVICE_NAME = NlibProperty.getString("oauth2.client.provider.google.name"); + 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_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 NAVER_SERVICE_NAME = NlibProperty.getString("oauth2.client.provider.naver.name"); + 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_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 KAKAO_SERVICE_NAME = NlibProperty.getString("oauth2.client.provider.kakao.name"); + 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"; } 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 c05c1c9d..68c3207c 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java @@ -13,6 +13,7 @@ import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; +import nlib.user.service.LoginService; import nlib.util.StringUtil; @@ -25,15 +26,15 @@ public class OAuthLogin { this(oauthVO, null); } - public OAuthLogin(OAuthVO oauthVO, String deptJsessionId) { + public OAuthLogin(OAuthVO oauthVO, String councilJsessionId) { // CallBack 호출될 경우, 지방문화원 원세션ID를 다시 전달받을 수 있도록 포함 처리 (2021.08.23 KKN) this.oauthService = new ServiceBuilder(oauthVO.getClientId()) .apiSecret(oauthVO.getClientSecret()) .callback( - StringUtil.isEmpty(deptJsessionId) ? + StringUtil.isEmpty(councilJsessionId) ? oauthVO.getRedirectUrl() : - appendUrlParam(oauthVO.getRedirectUrl(), "deptJsessionId", deptJsessionId) + appendUrlParam(oauthVO.getRedirectUrl(), LoginService.COUNCIL_JSESSION_ID_NAME, councilJsessionId) ) .scope("profile") .build(oauthVO.getApi20Instance()); diff --git a/src/main/java/nlib/cmm/crypto/NlibPasswordEncoder.java b/src/main/java/nlib/cmm/crypto/NlibPasswordEncoder.java index d7e7ba5c..37e88b45 100644 --- a/src/main/java/nlib/cmm/crypto/NlibPasswordEncoder.java +++ b/src/main/java/nlib/cmm/crypto/NlibPasswordEncoder.java @@ -48,7 +48,7 @@ public class NlibPasswordEncoder implements PasswordEncoder { /* extends EgovPa */ @Override public String encode(CharSequence rawPassword) { - + log.debug("encode > rawPassword = " + rawPassword); return egovPasswordEncoder.encryptPassword(rawPassword.toString()); } @@ -61,7 +61,8 @@ public class NlibPasswordEncoder implements PasswordEncoder { /* extends EgovPa */ @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { - + log.debug("matches > rawPassword = " + rawPassword); + log.debug("matches > encodedPassword = " + encodedPassword); return egovPasswordEncoder.checkPassword(rawPassword.toString(), encodedPassword); } diff --git a/src/main/java/nlib/cmm/session/SessionConfig.java b/src/main/java/nlib/cmm/session/SessionConfig.java index a52e396a..10a7c5b3 100644 --- a/src/main/java/nlib/cmm/session/SessionConfig.java +++ b/src/main/java/nlib/cmm/session/SessionConfig.java @@ -16,57 +16,101 @@ import org.springframework.security.core.context.SecurityContextHolder; import nlib.user.service.impl.LoginServiceImpl; import nlib.util.StringUtil; +/** + *
+ * @Class Name : SessionConfig.java
+ * 
+ * @Description : 멀티도메인에서의 로그인 처리를 위해 지방문화원에서 해당 세션에서 로그인처리 가능한 정보를 관리하는 클래스 
+ * 
+ * 
+ * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
+ *
+ * 
+ * + * @ ------------ -------- --------------------------- + * @ 수정일 수정자 수정내용 + * @ ------------ -------- --------------------------- + * @ 2021. 8. 25. KNKIM 최초 생성 + * + * + * @author 이씨플라자 * DIGITALSHIP KNKIM + * @since 2021. 8. 25. + * @version 1.0 + * + */ @WebListener public class SessionConfig implements HttpSessionListener { - private static final Logger log = LoggerFactory.getLogger(LoginServiceImpl.class); - + private static final Logger log = LoggerFactory.getLogger(SessionConfig.class); + + /* 사용자 정보를 구분하는 구분자 */ + private static final String DELIMITER = "\t"; + + /* 세션별 로그인 처리 가능한 정보 목록 */ private static final Map sessions = new ConcurrentHashMap<>(); -// -// //중복로그인 지우기 -// public synchronized static String getSessionidCheck(String type, String compareId){ -// String result = ""; -// for( String key : sessions.keySet() ){ -// HttpSession hs = sessions.get(key); -// if(hs != null && hs.getAttribute(type) != null && hs.getAttribute(type).toString().equals(compareId) ){ -// result = key.toString(); -// } -// } -// removeSessionForDoubleLogin(result); -// return result; -// } -// -// private static void removeSessionForDoubleLogin(String userId){ -// System.out.println("remove userId : " + userId); -// if(userId != null && userId.length() > 0){ -// sessions.get(userId).invalidate(); -// sessions.remove(userId); -// } -// } -// @Override public void sessionCreated(HttpSessionEvent se) { - System.out.println("Session sessionCreated (O) : " + se.getSession().getId()); + log.debug("Session sessionCreated (O) : " + se.getSession().getId()); } @Override public void sessionDestroyed(HttpSessionEvent se) { log.debug("Session sessionDestroyed (X) : " + se.getSession().getId()); if(sessions.get(se.getSession().getId()) != null){ - //sessions.get(se.getSession().getId()).invalidate(); - sessions.remove(se.getSession().getId()); + removeLoginInfo(se.getSession().getId()); + } + } + + + /** + * 지방문화원 해당 세션에 로그인 처리 가능한 SNS 유형 및 SNS ID 정보를 리턴한다. + * 리턴유형 문자열 배열 + * [0] : snsType + * [1] : snsId + * + * @param sessionId + * @return + */ + public static String[] getLoginInfo(String sessionId) { + + if(StringUtil.isEmpty(sessionId)) return null; + + String loginInfo = sessions.get(sessionId); + if(StringUtil.isEmpty(loginInfo)) return null; + + String ret[] = loginInfo.split(DELIMITER); + + log.debug("setLoginInfo : " + sessionId + ", " + ret[0] + ", " + ret[1]); + + return ret; + } + + /** + * 지방문화원 해당 세션에 로그인 처리 가능한 SNS유형 및 SNSID 정보를 저장한다. + * + * @param sessionId + * @param snsType + * @param snsId + */ + public static void setLoginInfo(String sessionId, String snsType, String snsId) { + log.debug("setLoginInfo : " + sessionId + ", " + snsType + ", " + snsId); + sessions.put(sessionId, StringUtil.getString(snsType, "NONE") + DELIMITER + StringUtil.getString(snsId, "NONE")); + } + + /** + * 지방문화원 해당 세션에 로그인 처리 가능한 정보를 삭제한다. + * (로그인 처리 완료 후 또는 세션 종료 시, 삭제) + * + * @param sessionId + * @param snsType + * @param snsId + */ + public static void removeLoginInfo(String sessionId) { + if(StringUtil.isNotEmpty(sessionId)){ + sessions.remove(sessionId); + log.debug("removeLoginInfo > sessionId = " + sessionId); } } - public static String getLoginInfo(String sessionId) { - if(StringUtil.isEmpty(sessionId)) return null; - - return sessions.get(sessionId); - } - - public static void setLoginInfo(String sessionId, String snsUserId) { - sessions.put(sessionId, snsUserId); - } - } \ No newline at end of file diff --git a/src/main/java/nlib/user/service/LoginService.java b/src/main/java/nlib/user/service/LoginService.java index f0a3ba9a..d2fa6219 100644 --- a/src/main/java/nlib/user/service/LoginService.java +++ b/src/main/java/nlib/user/service/LoginService.java @@ -5,27 +5,33 @@ import java.util.HashMap; import javax.servlet.http.HttpServletRequest; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.LockedException; + import nlib.restful.service.DataApiReqVO; import nlib.restful.service.DataApiResVO; public interface LoginService { + public final String COUNCIL_JSESSION_ID_NAME = "councilJsessionId"; /* 지방문화원 회원 세션ID 저장변수명 */ //------------------------------- // 로그인 오류코드 //------------------------------- - public final String ERR_CODE_REQ_MEMBERSHIP = "ERR_REQ_MEMBERSHIP"; /* 오류코드 : 회원가입 필요 */ - public final String ERR_CODE_REQ_SNSLOGIN = "ERR_REQ_SNSLOGIN"; /* 오류코드 : SNS 로그인 필요 */ - + public final String ERR_CODE_REQ_MEMBERSHIP = "ERR_REQ_MEMBERSHIP"; /* 오류코드 : 회원가입 필요 */ + public final String ERR_CODE_REQ_SNSLOGIN = "ERR_REQ_SNSLOGIN"; /* 오류코드 : SNS 로그인 필요 */ + public final String ERR_CODE_LOCKED = "ERR_CODE_LOGIN_LOCKED"; /* 오류코드 : 계정잠김 */ + public final String ERR_CODE_DISABLE = "ERR_CODE_LOGIN_DISABLE"; /* 오류코드 : 계정유효하지 않음 */ + public final String ERR_CODE_MISMATCH = "ERR_CODE_LOGIN_MISMATCH"; /* 오류코드 : ID,PW일치하지 않음 */ + public final String ERR_CODE_EXC = "ERR_CODE_LOGIN_EXC"; /* 오류코드 : 기타오류 */ public String login(HttpServletRequest req, String username, String password); - public String loginOauth(HttpServletRequest req, String snsUserId, String councilJsessionId); + public String loginOauth(HttpServletRequest req, String oauthServiceName, String snsId, String councilJsessionId); - public String loginCouncilSSO(HttpServletRequest req, String snsUserId); + public String loginCouncilSSO(HttpServletRequest req, String councilJsessionId); - public String loginCouncil(HttpServletRequest req, String snsUserId); - public DataApiResVO logout(DataApiReqVO reqVO); public HashMap selectCouncilInfoByDnsHost(String councilDnsHost); diff --git a/src/main/java/nlib/user/service/NlibLoginVO.java b/src/main/java/nlib/user/service/NlibLoginVO.java index cb3adf03..0bf522ab 100644 --- a/src/main/java/nlib/user/service/NlibLoginVO.java +++ b/src/main/java/nlib/user/service/NlibLoginVO.java @@ -68,6 +68,9 @@ public class NlibLoginVO implements Serializable { private String ip; /* 접속IP */ private String authorityList; /* 권한ROLE 리스트 */ private String authKey; /* RESTful API : 접속인증코드 */ + + private String error = null; /* 처리 오류코드 */ + private String message = null; /* 처리 관련 메시지 */ /** * 로그인인증키값을 리턴한다. 만일 존재하지 않을 경우, userId를 기반으로 인증키를 생성하여 리턴한다. @@ -323,4 +326,20 @@ public class NlibLoginVO implements Serializable { this.authKey = authKey; } + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + } diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java index 3ac8eace..2f55bd3d 100644 --- a/src/main/java/nlib/user/service/impl/LoginDAO.java +++ b/src/main/java/nlib/user/service/impl/LoginDAO.java @@ -21,8 +21,8 @@ public class LoginDAO extends EgovComAbstractDAO { return null; } - public NlibLoginVO selectLoginUserInfo(String snsUserId) { - return (NlibLoginVO) selectOne("LoginDAO.selectLoginUserInfo", snsUserId); + public NlibLoginVO selectLoginUserInfo(NlibLoginVO nLoginParamVO) { + return (NlibLoginVO) selectOne("LoginDAO.selectLoginUserInfo", nLoginParamVO); } public void insertLoginLog(NlibLoginVO userVO) { diff --git a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java index 0d8d5e48..0465abc9 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -40,43 +40,171 @@ public class LoginServiceImpl implements LoginService /* * 입력된 로그인정보를 받아 로그인 처리한다. + * 정상인 경우 null을 리턴하고, 오류발생시 오류코드를 리턴한다 * * (non-Javadoc) * @see nlib.user.service.LoginService#login(javax.servlet.http.HttpServletRequest, java.lang.String, java.lang.String) */ public String login(HttpServletRequest req, String username, String password) { - // 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다. UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); - try { - // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. - Authentication authentication = authenticationManager.authenticate(token); - - // AuthKey 등록 - SecUserVO userVO = (SecUserVO)authentication.getPrincipal(); - userVO.setAuthKey(req.getSession().getId()); // TODO : 임시로 세션ID 넣음, 실제 Authkey 생성 규칙에 따른 해당 키 설정 처리 필요 - - // 실제 SecurityContext 에 authentication 정보를 등록한다. - SecurityContextHolder.getContext().setAuthentication(authentication); - - // TODO : 로그인 로그 정보를 통합자료시스템에 전송한다. - - } catch (DisabledException e) { - return "/login/loginForm.do?error=locked"; - } catch (LockedException e) { - return "/login/loginForm.do?error=disable"; - } catch (BadCredentialsException e) { - return "/login/loginForm.do?error=invalid-password"; - } catch (Exception e) { - return "/login/loginForm.do?error=other." + e.toString(); + NlibLoginVO userVO = loginProcSecurity(req, token); + + if(StringUtil.isNotEmpty(userVO.getError())) { + return userVO.getError(); } + // 로그인 로그 정보 저장 + loginDAO.insertLoginLog(userVO); + return null; } + + /* + * SNS 연동 SSO를 처리를 위한 확인작업을 수행한다. + * (nlib에서 호출됨) + * + * return값이 null인 경우, 정상적인 로그인 가능 상태 + * null이 아닌 경우, 오류 코드 + * - ERR_CODE_REQ_SNSLOGIN : SNS 정상적인 로그인이 필요 + * - ERR_CODE_REQ_MEMBERSHIP : 신규회원가입/회원통합 필요 + */ + public String loginOauth(HttpServletRequest req, String oauthServiceName, String snsId, String councilJsessionId) { + + if(StringUtil.isEmpty(snsId)) return ERR_CODE_REQ_SNSLOGIN; + + // SNS 연동 사용자UID로 사용자정보 조회 + NlibLoginVO nLoginParamVO = new NlibLoginVO(); + nLoginParamVO.setSnsId(snsId); + nLoginParamVO.setSnsType(oauthServiceName); + NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(nLoginParamVO); + + if(nLoginVO == null) { + return ERR_CODE_REQ_MEMBERSHIP; + } + + // 세션목록관리에 로그인 정상 가능 정보 추가 + SessionConfig.setLoginInfo(councilJsessionId, oauthServiceName, snsId); + + // 회원가입정보 존재하는 SNS 아이디임을 확인 완료 + return null; + } + + /* + * 지방문화원 해당 세션에 대한 최종 로그인 세션을 처리한다. + * 정상인 경우 null을 리턴하고, 오류발생시 오류코드를 리턴한다. + * + * (non-Javadoc) + * @see nlib.user.service.LoginService#loginCouncilSSO(javax.servlet.http.HttpServletRequest, java.lang.String) + */ + public String loginCouncilSSO(HttpServletRequest req, String councilJsessionId) { + + // 세션에서 로그인 처리 가능 정보 가져오기 + String loginInfo[] = SessionConfig.getLoginInfo(councilJsessionId); + if(loginInfo == null || loginInfo.length < 2) return ERR_CODE_REQ_SNSLOGIN; + + String oauthServiceName = loginInfo[0]; + String snsId = loginInfo[1]; + + if(StringUtil.isEmpty(oauthServiceName)) + return ERR_CODE_REQ_SNSLOGIN; + if(StringUtil.isEmpty(snsId)) + return ERR_CODE_REQ_SNSLOGIN; + + // 회원DB에서 사용자 정보 조회 + NlibLoginVO nLoginParamVO = new NlibLoginVO(); + nLoginParamVO.setSnsId(snsId); + nLoginParamVO.setSnsType(oauthServiceName); + + NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(nLoginParamVO); + + if(nLoginVO == null) { + return ERR_CODE_REQ_MEMBERSHIP; + } + + // Spring Security 로그인처리위한 token 생성하여 로그인 처리 + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getPassword()); + NlibLoginVO nlibLoginedVO = loginProcSecurity(req, token); + + if(StringUtil.isNotEmpty(nlibLoginedVO.getError())) { + return nlibLoginedVO.getError(); + } + + // 로그인 로그 정보 저장 + loginDAO.insertLoginLog(nlibLoginedVO); + + return null; + + } + + /** + * 스프링 시큐리티 로그인 처리를 수행한다. + * + * @param req + * @param token + * @return + */ + public NlibLoginVO loginProcSecurity(HttpServletRequest req, UsernamePasswordAuthenticationToken token) { + + NlibLoginVO nlibLoginVO = null; + + try { + // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. + Authentication authentication = authenticationManager.authenticate(token); + + // AuthKey 생성 및 기타 정보 저장 + String sessionId = req.getSession().getId(); + nlibLoginVO = (NlibLoginVO)authentication.getPrincipal(); + nlibLoginVO.getOrCreateAuthKey(sessionId); // SET AUTHKEY + nlibLoginVO.setIp(req.getRemoteAddr()); + + // 실제 SecurityContext 에 authentication 정보를 등록한다. + SecurityContextHolder.getContext().setAuthentication(authentication); + SessionConfig.removeLoginInfo(sessionId); + + } catch (DisabledException e) { + log.error("loginProcSecurity > " + ERR_CODE_LOCKED); + if(nlibLoginVO == null) nlibLoginVO = new NlibLoginVO(); + nlibLoginVO.setError(ERR_CODE_LOCKED); + } catch (LockedException e) { + log.error("loginProcSecurity > " + ERR_CODE_DISABLE); + if(nlibLoginVO == null) nlibLoginVO = new NlibLoginVO(); + nlibLoginVO.setError(ERR_CODE_DISABLE); + } catch (BadCredentialsException e) { + log.error("loginProcSecurity > " + ERR_CODE_MISMATCH); + if(nlibLoginVO == null) nlibLoginVO = new NlibLoginVO(); + nlibLoginVO.setError(ERR_CODE_MISMATCH); + } catch (Exception e) { + log.error("loginProcSecurity > " + ERR_CODE_EXC + " : " + e.toString()); + if(nlibLoginVO == null) nlibLoginVO = new NlibLoginVO(); + nlibLoginVO.setError(ERR_CODE_EXC + " : " + e.toString()); + } + + return nlibLoginVO; + } + + public DataApiResVO logout(DataApiReqVO reqVO) { + return null; + } + + /* + * DNS 호스트명으로 지방문화원 정보를 조회한다. (지방문화원코드, 명칭) + * + * (non-Javadoc) + * @see nlib.user.service.LoginService#selectCouncilInfoByDnsHost(java.lang.String) + */ + public HashMap selectCouncilInfoByDnsHost(String councilDnsHost) { + return loginDAO.selectCouncilInfoByDnsHost(councilDnsHost); + } + + + + + /* SNS 연동 SSO를 통한 로그인 처리한다. * * return값이 null인 경우, 정상적인 로그인 처리 완료 @@ -131,134 +259,40 @@ public class LoginServiceImpl implements LoginService // } // - /* SNS 연동 SSO를 통한 로그인 처리한다. - * - * return값이 null인 경우, 정상적인 로그인 처리 완료 - * null이 아닌 경우, 오류 코드 - * - REQ-SNS-SSO : SNS 정상적인 로그인이 필요 - * - NEW-MEMBERSHIP : 신규회원가입/회원통합 필요 - */ - public String loginOauth(HttpServletRequest req, String snsId, String councilJsessionId) { - - // SNS 연동 사용자UID로 사용자정보 조회 - if(StringUtil.isEmpty(snsId)) return ERR_CODE_REQ_SNSLOGIN; - - NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(snsId); - - if(nLoginVO == null) { - return ERR_CODE_REQ_MEMBERSHIP; - } - - // 회원가입정보 존재하는 SNS 아이디임을 확인 완료 - return null; - } - - public String loginCouncilSSO(HttpServletRequest req, String snsUserId) { - - // SNS 연동 사용자UID로 사용자정보 조회 - if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso"; - - NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(snsUserId); - - if(nLoginVO == null) { - return "/login/loginForm.do?error=new-membership"; - } - - // 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다. - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getPassword()); - - try { - // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. - Authentication authentication = authenticationManager.authenticate(token); - - // AuthKey 등록 - SecUserVO userVO = (SecUserVO)authentication.getPrincipal(); - userVO.getOrCreateAuthKey(req.getSession().getId()); // SET AUTHKEY - - // 실제 SecurityContext 에 authentication 정보를 등록한다. - SecurityContextHolder.getContext().setAuthentication(authentication); - - // TODO : 로그인 로그 정보를 통합자료시스템에 전송한다. - userVO.setIp(req.getRemoteAddr()); - loginDAO.insertLoginLog(userVO); - - } 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(); - } - - return null; - } - - /* SNS 연동 SSO를 통한 로그인 처리한다. + /* + * SNS 연동 SSO를 통한 로그인 처리한다. * * return값이 null인 경우, 정상적인 로그인 처리 완료 * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) * */ - public String loginCouncil(HttpServletRequest req, String snsUserId) { - - // SNS 연동 사용자UID로 사용자정보 조회 - if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso"; - - NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(snsUserId); - - if(nLoginVO == null) { - return "/login/loginForm.do?error=new-membership"; - } - - // 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다. - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getPassword()); - - try { - // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. - Authentication authentication = authenticationManager.authenticate(token); - - // AuthKey 등록 - SecUserVO userVO = (SecUserVO)authentication.getPrincipal(); - userVO.getOrCreateAuthKey(req.getSession().getId()); // SET AUTHKEY - - // 실제 SecurityContext 에 authentication 정보를 등록한다. - SecurityContextHolder.getContext().setAuthentication(authentication); - - // TODO : 로그인 로그 정보를 통합자료시스템에 전송한다. - userVO.setIp(req.getRemoteAddr()); - loginDAO.insertLoginLog(userVO); - - } 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(); - } - - return null; - } +// public String loginCouncil(HttpServletRequest req, String snsUserId) { +// +// // SNS 연동 사용자UID로 사용자정보 조회 +// if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso"; +// +// +// NlibLoginVO nLoginParamVO = new NlibLoginVO(); +// +// nLoginParamVO.setSnsId(snsId); +// nLoginParamVO.setSnsType(oauthServiceName); +// +// NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(nLoginParamVO); +// +// if(nLoginVO == null) { +// return "/login/loginForm.do?error=new-membership"; +// } +// +// // 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다. +// UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getPassword()); +// NlibLoginVO nlibLoginedVO = loginProcSecurity(req, token); +// +// // 로그인 로그 저장 +// loginDAO.insertLoginLog(NlibLoginedVO); +// +// return null; +// } - 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 e1640961..9e9291a2 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -46,13 +46,12 @@ import nlib.util.StringUtil; * * * @ ------------ -------- --------------------------- - * @ 수정일 수정자 수정내용 + * @ 수정일 수정자 수정내용 * @ ------------ -------- --------------------------- - * @ 2021. 7. 9. KNKIM 최초 생성 - * @ 2021. 8.18. RESTful -> DB접속 방식으로 변경 처리 - * @ 2021. 8.19. 지방문화원별 다른 도메인 호스트 접속 처리를 위한 Spring Security 변경 작업, 네이버 전자정보 프레임워크 기반으로 변경 - * @ 2021. 8.24. 테이블 변경에 따른 항목명 변경 - * + * @ 2021. 7. 9. KNKIM 최초 생성 + * @ 2021. 8.18. KNKIM RESTful -> DB접속 방식으로 변경 처리 + * @ 2021. 8.19. KNKIM 지방문화원별 다른 도메인 호스트 접속 처리를 위한 Spring Security 변경 작업, 네이버 전자정보 프레임워크 기반으로 변경 + * @ 2021. 8.24. KNKIM 테이블 변경에 따른 항목명 변경 및 코드 정리작업 * * * @author 이씨플라자 * DIGITALSHIP KNKIM @@ -109,14 +108,14 @@ public class LoginController { 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); - } - } +// 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); @@ -169,7 +168,7 @@ public class LoginController { //---------------------------------------------- // 지방문화원 사이트에서 접속한 경우, 지방문화원 정보 확인 //---------------------------------------------- - String councilJsessionId = paramMap.get("councilJsessionId"); + String councilJsessionId = paramMap.get(LoginService.COUNCIL_JSESSION_ID_NAME); String councilDnsHost = paramMap.get("councilDnsHost"); String councilReturnUrl = StringUtil.decodeBase64(paramMap.get("councilReturnUrl")); String councilHomeUrl = StringUtil.decodeBase64(paramMap.get("councilHomeUrl")); @@ -183,7 +182,7 @@ public class LoginController { log.debug("loginForm > councilCd = " + councilCd); log.debug("loginForm > councilNm = " + councilNm); - session.setAttribute("councilJsessionId", councilJsessionId); + session.setAttribute(LoginService.COUNCIL_JSESSION_ID_NAME, councilJsessionId); session.setAttribute("councilDnsHost", councilDnsHost); session.setAttribute("councilReturnUrl", councilReturnUrl); session.setAttribute("councilHomeUrl" , councilHomeUrl); @@ -211,9 +210,177 @@ public class LoginController { return "nlib/login/loginForm"; } + + /** + * SNS 로그인 후, 콜백으로 호출되며 회원가입된 사용자가 존재하는 지 확인하여 로그인 처리가 진행될 수 있도록 한다. + * 정상 회원가입자인 경우, 해당 지방문화원 도메인(호스트)주소로 loginCouncilSSO(..)가 재호출되어 실제 세션 로그인 처리 마무리가 이루어진다. + * + * @param req + * @param oauthServiceName + * @param paramMap + * @param model + * @param session + * @return + * @throws Exception + */ + @RequestMapping(value = {"/login/{oauthServiceName}Callback.do", "/login/{oauthServiceName}/callback.do"}) + public String loginOauthCallback( + HttpServletRequest req, + @PathVariable String oauthServiceName, + @RequestParam Map paramMap, + Model model, + HttpSession session) throws Exception { + + String redirectUrl = NlibProperty.getString("home.uri"); // "/index.do"; + String code = paramMap.get("code"); + String councilJsessionId = paramMap.get(LoginService.COUNCIL_JSESSION_ID_NAME); + + log.debug("oauthLoginCallback: code = ", code); + + // SNS 클라이언트 설정 정보 할당 + OAuthVO oauthVO = null; + if (StringUtil.equalsIgnoreCase(OAuthConfig.GOOGLE_SERVICE_NAME, oauthServiceName)) + oauthVO = googleAuthVO; + else if (StringUtil.equalsIgnoreCase(OAuthConfig.NAVER_SERVICE_NAME, oauthServiceName)) + oauthVO = naverAuthVO; + else if (StringUtil.equalsIgnoreCase(OAuthConfig.KAKAO_SERVICE_NAME, oauthServiceName)) + oauthVO = kakaoAuthVO; + else { + throw new Exception("SNS 연동 콜백정보가 올바르지 않습니다."); + } + + //----------------------------------------------- + // 1. code를 이용해서 Access Token 받기 + // 2. Access Token을 이용해서 사용자 제공정보 가져오기 + //----------------------------------------------- + OAuthLogin oauthLogin = new OAuthLogin(oauthVO, councilJsessionId); + OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시 + log.debug("oauthLoginCallback > Profile ===>>" + oauthUser.getSnsId() + ", " + oauthUser.getName()); + + // oAuth를 통한 SNS연동이 실패한 경우 + if(oauthUser == null || !oauthUser.isValid()) { + model.addAttribute("message", "먼저 회원가입하신 후, 이용하여 주시기 바랍니다."); + redirectUrl = NlibProperty.getString("member.new.url"); // "/member/insertMemberInfoForm.do" + return "redirect:" + redirectUrl; + } + + //----------------------------------------------- + // 등록된 사용자 여부 확인 + //----------------------------------------------- + String loginResult = loginService.loginOauth(req, oauthServiceName, oauthUser.getSnsId(), councilJsessionId); + + // 정상 SNS 연동 로그인 + if(loginResult == null) { + // 세션에 설정된 redirect 주소 확인 + String councilHomeUrl = (String)session.getAttribute("councilHomeUrl"); + redirectUrl = councilHomeUrl + "/login/loginCouncilSSO.do"; + return "redirect:" + redirectUrl; + } + + // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 + model.addAttribute("error", loginResult); + if(StringUtil.equalsIgnoreCase(loginResult, loginService.ERR_CODE_REQ_MEMBERSHIP)) { + model.addAttribute("message", "회원가입하신 후, 이용 가능합니다."); + redirectUrl = NlibProperty.getString("member.new.url"); + } else if(StringUtil.equalsIgnoreCase(loginResult, loginService.ERR_CODE_REQ_SNSLOGIN)) { + model.addAttribute("message", "먼저 로그인할 SNS를 선택하여 로그인 바랍니다."); + redirectUrl = NlibProperty.getString("login.back.url"); + } + + return "redirect:" + redirectUrl; + } + + /** + * ID, PW를 입력받아 로그인을 처리한다. + * (스프링 시큐리티 로그인 수행) + * + * @param req + * @param res + * @param username + * @param password + * @param model + * @return + */ + @RequestMapping("/login/login.do") + public String login(HttpServletRequest req, HttpServletResponse res, + @RequestParam(required = false) String username, @RequestParam(required = false) String password, + ModelMap model) { + + String loginResult = loginService.login(req, username, password); + String redirectUrl = NlibProperty.getString("home.uri"); + + // 정상적으로 로그인된 경우 + if (StringUtil.isEmpty(loginResult)) { + RequestCache cache = new HttpSessionRequestCache(); + SavedRequest savedRequest = cache.getRequest(req, res); + if (savedRequest != null) { + redirectUrl = savedRequest.getRedirectUrl(); + } + } + // 로그인 실패 + else { + redirectUrl = NlibProperty.getString("login.back.url") + "?error=" + loginResult; + } + + log.debug("login.do > loginResult = " + loginResult); + log.debug("login.do > redirectUrl = " + redirectUrl); + + return "redirect:" + redirectUrl; + } + /** + * 정상적인 사용자의 로그인 요청이 검증된 후, 실제 해당 지방문화원 사이트 URL로 호출되는 함수로써 로그인 최종 처리를 진행한다. + * + * @param req + * @param res + * @param session + * @param model + * @return + * @throws Exception + */ + @RequestMapping("/login/loginCouncilSSO.do") + public String loginCouncilSSO( + HttpServletRequest req, + HttpServletResponse res, + HttpSession session, + ModelMap model) throws Exception { + + String redirectUrl = "/index.do"; + + String jsessionId = session.getId(); + String loginResult = loginService.loginCouncilSSO(req, session.getId()); + + // oAuth를 통한 SNS연동 성공인 경우 + if(loginResult == null) { + // 세션에 설정된 redirect 주소 확인 + String councilReturnUrl = (String)session.getAttribute("councilReturnUrl"); + + log.debug("loginCouncilSSO > councilReturnUrl = " + councilReturnUrl); + if(StringUtil.isNotEmpty(councilReturnUrl)) { + redirectUrl = councilReturnUrl; + } + } + // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않았거나 정보가 서로 맞지 않는 경우 + else { + model.addAttribute("error", loginResult); + redirectUrl = NlibProperty.getString("login.back.url"); + } + + return "redirect:" + redirectUrl; + } + + /** + * 로그아웃 후의 처리를 담당한다. 스프링 시큐리티에서 로그아웃이 수행된 후, 호출된다. + * + * @param req + * @return + */ + @RequestMapping("/login/logout.do") + public String logout(HttpServletRequest req) { + return null; + } - + // // 구글 로그인 콜백 // @RequestMapping(value = "/login/googleCallback.do") // public String googleCallback(@RequestParam(value = "code") String authCode, HttpSession session, Model model, @@ -297,146 +464,4 @@ public class LoginController { // }// end kakaoLogin() // - @RequestMapping(value = {"/login/{oauthServiceName}Callback.do", "/login/{oauthServiceName}/callback.do"}) - public String oauthLoginCallback( - HttpServletRequest req, - @PathVariable String oauthServiceName, - @RequestParam Map paramMap, - Model model, - HttpSession session) throws Exception { - - String redirectUrl = NlibProperty.getString("home.uri"); // "/index.do"; - String code = paramMap.get("code"); - String councilJsessionId = paramMap.get("councilJsessionId"); - - log.debug("oauthLoginCallback: code = ", code); - - // SNS 클라이언트 설정 정보 할당 - OAuthVO oauthVO = null; - if (StringUtil.equals(OAuthConfig.GOOGLE_SERVICE_NAME, oauthServiceName)) - oauthVO = googleAuthVO; - else if (StringUtil.equals(OAuthConfig.NAVER_SERVICE_NAME, oauthServiceName)) - oauthVO = naverAuthVO; - else if (StringUtil.equals(OAuthConfig.KAKAO_SERVICE_NAME, oauthServiceName)) - oauthVO = kakaoAuthVO; - else { - throw new Exception("SNS 연동 콜백정보가 올바르지 않습니다."); - } - - //----------------------------------------------- - // 1. code를 이용해서 Access Token 받기 - // 2. Access Token을 이용해서 사용자 제공정보 가져오기 - //----------------------------------------------- - OAuthLogin oauthLogin = new OAuthLogin(oauthVO, councilJsessionId); - - OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시 - 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; - } - - // 등록된 사용자 여부 확인 - String loginResult = loginService.loginOauth(req, oauthUser.getSnsId(), councilJsessionId); - - // 정상 SNS 연동 로그인 - if(loginResult == null) { - // 세션에 설정된 redirect 주소 확인 - model.addAttribute("message", "정상적으로 로그인되었습니다."); - String councilHomeUrl = (String)session.getAttribute("councilHomeUrl"); - redirectUrl = councilHomeUrl + "/login/loginCouncilSSO.do"; - return "redirect:" + redirectUrl; - } - - // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 - model.addAttribute("error", loginResult); - if(StringUtil.equals(loginResult, loginService.ERR_CODE_REQ_MEMBERSHIP)) { - model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?"); - 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; - } - - /** - * 로그인을 처리한다. (스프링 시큐리티 로그인 수행) - * - * @param req - * @param res - * @param username - * @param password - * @param model - * @return - */ - @RequestMapping("/login/login.do") - public String login(HttpServletRequest req, HttpServletResponse res, - @RequestParam(required = false) String username, @RequestParam(required = false) String password, - ModelMap model) { - - String redirectUrl = loginService.login(req, username, password); - - // 정상적으로 로그인된 경우 - if (StringUtil.isEmpty(redirectUrl)) { - RequestCache cache = new HttpSessionRequestCache(); - SavedRequest savedRequest = cache.getRequest(req, res); - if (savedRequest == null) - redirectUrl = "/"; - else - redirectUrl = savedRequest.getRedirectUrl(); - } - - log.debug("login.do > RequestCache : url=" + redirectUrl); - - return "redirect:" + redirectUrl; - } - - @RequestMapping("/login/loginCouncilSSO.do") - public String loginCouncilSSO( - HttpServletRequest req, - HttpServletResponse res, - HttpSession session, - ModelMap model) throws Exception { - - String redirectUrl = "/index.do"; - - String snsUserId = SessionConfig.getLoginInfo(session.getId()); - String loginResult = loginService.loginCouncilSSO(req, snsUserId); - - // oAuth를 통한 SNS연동이 실패한 경우 - if(loginResult == null) { - // 세션에 설정된 redirect 주소 확인 - String councilReturnUrl = (String)session.getAttribute("councilReturnUrl"); - - log.debug("loginCouncilSSO > councilReturnUrl = " + councilReturnUrl); - if(StringUtil.isNotEmpty(councilReturnUrl)) { - redirectUrl = councilReturnUrl; - } - } - // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 - else { - model.addAttribute("code", "GONEW"); - model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?"); - redirectUrl = loginResult; - } - - return "redirect:" + redirectUrl; - - } - - /** - * 로그아웃 후의 처리를 담당한다. 스프링 시큐리티에서 로그아웃이 수행된 후, 호출된다. - * - * @param req - * @return - */ - @RequestMapping("/login/logout.do") - public String logout(HttpServletRequest req) { - return null; - } } \ No newline at end of file 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 c0cae348..3d936d49 100644 --- a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml @@ -3,7 +3,7 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - SELECT A.MB_INFO_ID , A.LOGIN_USER_ID @@ -32,7 +32,7 @@ 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} + AND UPPER(SNS_TYPE) = UPPER(#{snsType}) AND B.UNLINK_DD IS NULL /* 연동해제건 제외 */ LIMIT 1 diff --git a/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml b/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml index 81163423..919f9421 100644 --- a/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml @@ -4,16 +4,35 @@ \ No newline at end of file diff --git a/src/main/resources/nlib/nlib.properties b/src/main/resources/nlib/nlib.properties index 0227b47a..9ece71c3 100644 --- a/src/main/resources/nlib/nlib.properties +++ b/src/main/resources/nlib/nlib.properties @@ -17,6 +17,17 @@ # \uba54\uc778\ud648\ud398\uc774\uc9c0 URI home.uri = /index.do +#---------------------------------------- +# \ub85c\uadf8\uc778/\ud68c\uc6d0\uac00\uc785\uad00\ub828 URL \uc815\ubcf4 +#---------------------------------------- +member.new.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 + #---------------------------------------- # DataAPI \uc811\uc18d\uc815\ubcf4 #---------------------------------------- @@ -105,17 +116,6 @@ oauth2.client.provider.kakao.user-info-uri = https://kapi.kakao.com/v2/use #---------------------------------------- guest.userid = GUEST -#---------------------------------------- -# \ub85c\uadf8\uc778/\ud68c\uc6d0\uac00\uc785\uad00\ub828 URL \uc815\ubcf4 -#---------------------------------------- -member.new.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 - #---------------------------------------- # \uc0ac\uc6a9\uc790\uad8c\ud55c\uba85 #---------------------------------------- diff --git a/src/main/webapp/WEB-INF/tiles/inc/header.jsp b/src/main/webapp/WEB-INF/tiles/inc/header.jsp index 34168e53..090ad4e9 100644 --- a/src/main/webapp/WEB-INF/tiles/inc/header.jsp +++ b/src/main/webapp/WEB-INF/tiles/inc/header.jsp @@ -5,27 +5,33 @@ <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> -온라인자료대출관리 + + + ';">온라인자료대출관리 (<%=session.getAttribute("councilHomeUrl") %>) + + + 온라인자료대출관리(${pageContext.request.contextPath}/) +