From b98ed38065f0641a03c6819f3e3a6d8621cd4e51 Mon Sep 17 00:00:00 2001 From: KNKIM Date: Wed, 18 Aug 2021 18:57:54 +0900 Subject: [PATCH 1/4] =?UTF-8?q?SNS=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20DB?= =?UTF-8?q?=EC=A0=91=EC=86=8D=EC=B2=98=EB=A6=AC=20-=20=EC=A4=91=EA=B0=84?= =?UTF-8?q?=EB=B0=B1=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nlib/security/SecUserDAO.java | 38 +++++----- .../nlib/security/SecUserDetailsService.java | 6 +- src/main/java/nlib/security/SecUserVO.java | 9 ++- .../java/nlib/user/service/LoginService.java | 2 +- .../java/nlib/user/service/NlibLoginVO.java | 37 +++++++++- .../java/nlib/user/service/impl/LoginDAO.java | 15 +++- .../user/service/impl/LoginServiceImpl.java | 70 +++++++++++-------- .../java/nlib/user/web/LoginController.java | 20 +++--- .../mapper/config/mapper-config.xml | 1 + .../mapper/nlib/user/LoginDAO_SQL.xml | 43 ++++++++++++ .../mapper/nlib/user/SecUserDAO_SQL.xml | 19 +++++ src/main/resources/nlib/nlib.properties | 17 +++++ 12 files changed, 209 insertions(+), 68 deletions(-) create mode 100644 src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml create mode 100644 src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml diff --git a/src/main/java/nlib/security/SecUserDAO.java b/src/main/java/nlib/security/SecUserDAO.java index 9d56c79c..df4f908a 100644 --- a/src/main/java/nlib/security/SecUserDAO.java +++ b/src/main/java/nlib/security/SecUserDAO.java @@ -7,9 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; -import egovframework.rte.psl.dataaccess.EgovAbstractMapper; -import nlib.restful.service.DataApiReqVO; -import nlib.restful.service.DataApiResVO; +import egovframework.com.cmm.service.impl.EgovComAbstractDAO; import nlib.util.StringUtil; /** @@ -36,30 +34,30 @@ import nlib.util.StringUtil; * */ @Repository("secUserDAO") -public class SecUserDAO extends EgovAbstractMapper { +public class SecUserDAO extends EgovComAbstractDAO { private static final Logger log = LoggerFactory.getLogger(SecUserDAO.class); - public SecUserVO loadUserByUsername(String userName) { + public SecUserVO loadUserByUsername(String loginUserId) { - HashMap info = selectOne("secUserDAO.loadUserByUsername", userName); + SecUserVO uInfo = (SecUserVO)selectOne("SecUserDAO.loadUserByUsername", loginUserId); - // 사용자 정보 담기 - SecUserVO ret = new SecUserVO(); - ret.setUserId ((String)info.get("userId")); - ret.setUserNm ((String)info.get("userName")); - ret.setUserPwd ((String)info.get("userPwd")); - ret.setLoginUserId ((String)info.get("loginUserId")); - - // 다중 권한 설정 - String authorities = (String)info.get("authorities"); - if(StringUtil.isEmpty(authorities)) ret.addAuthority(SecUserVO.DEFAULT_ROLE); - else { - String[] authArr = authorities.split(","); - Arrays.stream(authArr).forEach(auth -> ret.addAuthority(auth)); + if(uInfo == null) { + uInfo = new SecUserVO(); + } else { + // 다중 권한 설정 + String authorities = (String)uInfo.getAuthorityList(); + if(StringUtil.isEmpty(authorities)) { + uInfo.addAuthority(SecUserVO.DEFAULT_ROLE); + } else { + String[] authArr = authorities.split(","); + for(String auth : authArr) { + uInfo.addAuthority(auth); + } + } } - return ret; + return uInfo; } } diff --git a/src/main/java/nlib/security/SecUserDetailsService.java b/src/main/java/nlib/security/SecUserDetailsService.java index 52718168..a697dedb 100644 --- a/src/main/java/nlib/security/SecUserDetailsService.java +++ b/src/main/java/nlib/security/SecUserDetailsService.java @@ -52,12 +52,12 @@ public class SecUserDetailsService implements UserDetailsService { * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) */ @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + public UserDetails loadUserByUsername(String loginUserId) throws UsernameNotFoundException { - SecUserVO secUserVO = secUserDAO.loadUserByUsername(username); + SecUserVO secUserVO = secUserDAO.loadUserByUsername(loginUserId); if(secUserVO == null) { - throw new UsernameNotFoundException(username); + throw new UsernameNotFoundException(loginUserId); } return secUserVO; } diff --git a/src/main/java/nlib/security/SecUserVO.java b/src/main/java/nlib/security/SecUserVO.java index 25783ee0..45782787 100644 --- a/src/main/java/nlib/security/SecUserVO.java +++ b/src/main/java/nlib/security/SecUserVO.java @@ -7,6 +7,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; +import nlib.cmm.service.NlibProperty; import nlib.user.service.NlibLoginVO; /** @@ -35,8 +36,12 @@ public class SecUserVO extends NlibLoginVO implements UserDetails { private static final long serialVersionUID = -8274004534207618048L; - public static final String ROLE_USER = "ROLE_USER"; - public static final String ROLE_ADMIN = "ROLE_ADMIN"; + /* 권한 ROLE 명칭 */ + public static final String ROLE_USER = NlibProperty.getString("auth.role.user"); // 일반사용자 + public static final String ROLE_ADMIN = NlibProperty.getString("auth.role.admin"); // 관리자 + public static final String ROLE_SYSTEM = NlibProperty.getString("auth.role.system"); // 시스템관리자 + + /* 기본권한 ROLE */ public static final String DEFAULT_ROLE = ROLE_USER; ArrayList auth = null; /* 권한 목록 */ diff --git a/src/main/java/nlib/user/service/LoginService.java b/src/main/java/nlib/user/service/LoginService.java index 836d34a0..87c5f80a 100644 --- a/src/main/java/nlib/user/service/LoginService.java +++ b/src/main/java/nlib/user/service/LoginService.java @@ -10,7 +10,7 @@ public interface LoginService { public String login(HttpServletRequest req, String username, String password); - public String loginOauth(String snsUid); + public String loginOauth(HttpServletRequest req, String snsUserId); public DataApiResVO logout(DataApiReqVO reqVO); diff --git a/src/main/java/nlib/user/service/NlibLoginVO.java b/src/main/java/nlib/user/service/NlibLoginVO.java index ef21e154..6b2f065c 100644 --- a/src/main/java/nlib/user/service/NlibLoginVO.java +++ b/src/main/java/nlib/user/service/NlibLoginVO.java @@ -35,6 +35,7 @@ public class NlibLoginVO implements Serializable { private String userId; /* 사용자아이디 (ex: U1000000001) */ private String loginUserId; /* 로그인사용자ID (이메일주소) */ private String deptSeq; /* 조직코드 */ + private String deptNm; /* 조직명 */ private String userDiv; /* 사용자구분 */ private String userNm; /* 사용자명 */ private String userPwd; /* 비밀번호 */ @@ -69,7 +70,9 @@ public class NlibLoginVO implements Serializable { private String gender; /* 성별(M:남자,F:여자) */ private String authKey; /* 로그인 인증키 */ - + private String loginSucsYn; /* 로그인성공여부 */ + private String accIp; /* 접속IP */ + private String authorityList; /* 권한ROLE 리스트 */ /** * 로그인인증키값을 리턴한다. 만일 존재하지 않을 경우, userId를 기반으로 인증키를 생성하여 리턴한다. @@ -378,5 +381,37 @@ public class NlibLoginVO implements Serializable { public void setGender(String gender) { this.gender = gender; } + + public String getDeptNm() { + return deptNm; + } + + public void setDeptNm(String deptNm) { + this.deptNm = deptNm; + } + + public String getAccIp() { + return accIp; + } + + public void setAccIp(String accIp) { + this.accIp = accIp; + } + + public String getLoginSucsYn() { + return loginSucsYn; + } + + public void setLoginSucsYn(String loginSucsYn) { + this.loginSucsYn = loginSucsYn; + } + + public String getAuthorityList() { + return authorityList; + } + + public void setAuthorityList(String authorityList) { + this.authorityList = authorityList; + } } diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java index ba8f2b21..86a1d1de 100644 --- a/src/main/java/nlib/user/service/impl/LoginDAO.java +++ b/src/main/java/nlib/user/service/impl/LoginDAO.java @@ -3,12 +3,14 @@ package nlib.user.service.impl; import org.springframework.stereotype.Repository; +import egovframework.com.cmm.service.impl.EgovComAbstractDAO; import nlib.restful.service.DataApiReqVO; import nlib.restful.service.DataApiResVO; +import nlib.user.service.NlibLoginVO; @Repository("loginDAO") -public class LoginDAO -{ +public class LoginDAO extends EgovComAbstractDAO { + public DataApiResVO login(DataApiReqVO reqVO) { return null; } @@ -17,5 +19,12 @@ public class LoginDAO return null; } - + public NlibLoginVO selectLoginUserInfo(String snsUserId) { + return (NlibLoginVO) selectOne("LoginDAO.selectLoginUserInfo", snsUserId); + } + + public void insertLoginLog(NlibLoginVO userVO) { + insert("BBSArticle.insertLoginLog", userVO); + } + } \ 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 b37375cf..5e6b70fe 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -20,6 +20,7 @@ import nlib.restful.service.DataApiReqVO; import nlib.restful.service.DataApiResVO; import nlib.security.SecUserVO; import nlib.user.service.LoginService; +import nlib.user.service.NlibLoginVO; import nlib.util.StringUtil; @Service("loginService") @@ -72,40 +73,51 @@ public class LoginServiceImpl implements LoginService } - /* - * SNS 연동을 통한 로그인 처리를 수행한다. + /* SNS 연동 SSO를 통한 로그인 처리한다. + * + * return값이 null인 경우, 정상적인 로그인 처리 완료 + * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) * */ - public String loginOauth(String snsUid) { + public String loginOauth(HttpServletRequest req, String snsUserId) { // SNS 연동 사용자UID로 사용자정보 조회 - if(StringUtil.isEmpty(snsUid)) return null; + 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(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(); -// } + // 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다. + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getUserPwd()); + + try { + // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. + Authentication authentication = authenticationManager.authenticate(token); + + // AuthKey 등록 + SecUserVO userVO = (SecUserVO)authentication.getPrincipal(); + userVO.getAndCreateAuthKey(req.getSession().getId()); // SET AUTHKEY + + // 실제 SecurityContext 에 authentication 정보를 등록한다. + SecurityContextHolder.getContext().setAuthentication(authentication); + + // TODO : 로그인 로그 정보를 통합자료시스템에 전송한다. + userVO.setAccIp(req.getRemoteAddr()); + userVO.setLoginSucsYn("Y"); + loginDAO.insertLoginLog(userVO); + + } 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&message=" + e.toString(); + } return null; } diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java index 26b8903e..65bbfd99 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -49,6 +49,7 @@ import egovframework.com.ext.oauth.service.OAuthConfig; import egovframework.com.ext.oauth.service.OAuthLogin; import egovframework.com.ext.oauth.service.OAuthUniversalUser; import egovframework.com.ext.oauth.service.OAuthVO; +import nlib.cmm.service.NlibProperty; import nlib.cmm.snslogin.GoogleOAuthResponse; import nlib.cmm.snslogin.KakaoController; import nlib.cmm.snslogin.NaverLoginBO; @@ -178,7 +179,7 @@ public class LoginController { // } // @RequestMapping(value = "/login/{oauthService}Callback.do", method = { RequestMethod.GET, RequestMethod.POST}) - public String oauthLoginCallback(@PathVariable String oauthService, + public String oauthLoginCallback(HttpServletRequest req, @PathVariable String oauthService, Model model, @RequestParam String code, HttpSession session) throws Exception { String redirectUrl = "/index.do"; @@ -204,23 +205,24 @@ public class LoginController { OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시 log.debug("Profile ===>>" + oauthUser); - String resultDBInfo = loginService.loginOauth(oauthUser.getUid()); + String loginResult = loginService.loginOauth(req, oauthUser.getUid()); // oAuth를 통한 SNS연동이 실패한 경우 if(oauthUser == null || !oauthUser.isValid()) { - model.addAttribute("code", "NOMEM"); model.addAttribute("message", "먼저 회원가입하신 후, 이용하여 주시기 바랍니다."); - } - // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 - else if(oauthUser.isValid() && resultDBInfo == null) { - model.addAttribute("code", "GONEW"); - model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?"); + redirectUrl = NlibProperty.getString("member.new.url"); // "/member/insertMemberInfoForm.do" } // 정상 SNS 연동 로그인 - else if(oauthUser.isValid() && resultDBInfo != null) { + else if(oauthUser.isValid() && loginResult == null) { // 세션에 설정된 redirect 주소 확인 model.addAttribute("message", "정상적으로 로그인되었습니다."); } + // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 + else { + model.addAttribute("code", "GONEW"); + model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?"); + redirectUrl = loginResult; + } return "redirect:" + redirectUrl; } diff --git a/src/main/resources/egovframework/mapper/config/mapper-config.xml b/src/main/resources/egovframework/mapper/config/mapper-config.xml index 17568b6e..6a706d7f 100644 --- a/src/main/resources/egovframework/mapper/config/mapper-config.xml +++ b/src/main/resources/egovframework/mapper/config/mapper-config.xml @@ -13,6 +13,7 @@ + \ 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 new file mode 100644 index 00000000..4489e05f --- /dev/null +++ b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml @@ -0,0 +1,43 @@ + + + + + + + + INSERT INTO SM_ACC_LOG /* 접속로그 */ + ( USER_ID + ,USER_NM + ,DEPT_SEQ + ,DEPT_NM + ,ACC_IP + ,LOGIN_SUCS_YN + ,ACC_DATE + ) VALUES ( + #{userId} + ,#{userNm} + ,#{deptSeq} + ,#{deptNm} + ,#{accIp} + ,#{loginSucsYn} + ,NOW() + ) + + + \ No newline at end of file diff --git a/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml b/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml new file mode 100644 index 00000000..41dc45e3 --- /dev/null +++ b/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/nlib/nlib.properties b/src/main/resources/nlib/nlib.properties index 0062fe1f..2e5c1f71 100644 --- a/src/main/resources/nlib/nlib.properties +++ b/src/main/resources/nlib/nlib.properties @@ -91,3 +91,20 @@ 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 oauth2.client.provider.naver.user-name-attribute = response + +#---------------------------------------- +# \ub85c\uadf8\uc778/\ud68c\uc6d0\uac00\uc785\uad00\ub828 URL \uc815\ubcf4 +#---------------------------------------- +member.new.url = /member/insertMemberInfoForm.do +member.login.url = /member/insertMemberInfoForm.do + + +#---------------------------------------- +# \uc0ac\uc6a9\uc790\uad8c\ud55c\uba85 +#---------------------------------------- +# \uc77c\ubc18\uc0ac\uc6a9\uc790 +auth.role.user = ROLE_USER +# \uad00\ub9ac\uc790 +auth.role.admin = ROLE_ADMIN +# \uc2dc\uc2a4\ud15c\uad00\ub9ac\uc790 +auth.role.system = ROLE_SYSTEM From 3cc150fc426b11d8882644c4742a8eabdb01611f Mon Sep 17 00:00:00 2001 From: KNKIM Date: Fri, 20 Aug 2021 14:40:08 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20SNS,=20Sprin?= =?UTF-8?q?gSecurity=20:=20DB=EC=97=B0=EB=8F=99=20=EC=A0=84=ED=99=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B4=88=EA=B8=B0=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 1 - pom.xml | 23 ++- src/main/java/nlib/cmm/qrcode/QRCodeUtil.java | 1 - .../nlib/security/SpringSecurityConfig.java | 15 +- .../java/nlib/user/service/NlibLoginVO.java | 193 +++--------------- .../java/nlib/user/service/impl/LoginDAO.java | 2 +- .../user/service/impl/LoginServiceImpl.java | 4 + .../java/nlib/user/web/LoginController.java | 19 +- .../mapper/config/mapper-config.xml | 5 +- .../mapper/nlib/user/LoginDAO_SQL.xml | 6 +- .../mapper/nlib/user/SecUserDAO_SQL.xml | 4 +- .../WEB-INF/jsp/nlib/login/loginForm.jsp | 7 + src/main/webapp/WEB-INF/tiles/inc/header.jsp | 5 +- 13 files changed, 90 insertions(+), 195 deletions(-) diff --git a/.classpath b/.classpath index 99a4add8..da9dfd75 100644 --- a/.classpath +++ b/.classpath @@ -34,6 +34,5 @@ - diff --git a/pom.xml b/pom.xml index a54739b4..5206bb4a 100644 --- a/pom.xml +++ b/pom.xml @@ -141,6 +141,18 @@ commons-httpclient 3.1 + + + org.springframework + spring-core + ${spring.maven.artifact.version} + + + + org.springframework + spring-expression + ${spring.maven.artifact.version} + @@ -155,8 +167,17 @@ --> - + + + org.springframework.webflow + spring-faces + 2.4.1.RELEASE + org.springframework.security spring-security-web diff --git a/src/main/java/nlib/cmm/qrcode/QRCodeUtil.java b/src/main/java/nlib/cmm/qrcode/QRCodeUtil.java index f0fbbac5..e2f3d6db 100644 --- a/src/main/java/nlib/cmm/qrcode/QRCodeUtil.java +++ b/src/main/java/nlib/cmm/qrcode/QRCodeUtil.java @@ -149,7 +149,6 @@ public class QRCodeUtil { // (2) 앞의 (1)의 문자열을 암호화 처리 String cryptedBarcodeText = EgovFileScrty.encodeBinary(barcodeText.getBytes()); log.debug("generateMemberQRCodeImage : cryptedBarcodeText=" + cryptedBarcodeText); - loginVO.setOnnaraUserid(cryptedBarcodeText); // TODO 임시저장처리 DDDDDDDDDDDDDDDDDDDDDDD // (3) 앞의 (2) 암호화 문자열로 QRCode 생성하여 BufferedImage형식으로 리턴 return generateQRCodeImageByZxing(cryptedBarcodeText); diff --git a/src/main/java/nlib/security/SpringSecurityConfig.java b/src/main/java/nlib/security/SpringSecurityConfig.java index dbc0d02a..eab90855 100644 --- a/src/main/java/nlib/security/SpringSecurityConfig.java +++ b/src/main/java/nlib/security/SpringSecurityConfig.java @@ -45,6 +45,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { + + // 권한/인증과 무관한 오픈된 정적 리소트 web.ignoring() .antMatchers("/resources/**") .antMatchers("/css/**") @@ -52,13 +54,6 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/js/**") .antMatchers("/temp/**") .antMatchers("/favicon/**") - .antMatchers("/*/*Ajax.do") - .antMatchers("/fileupload/**") - .antMatchers("/board/**") - .antMatchers("/inform/**") - .antMatchers("/alert/**") - .antMatchers("/code/**") - .antMatchers("/**") ; } @@ -82,6 +77,12 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/rent/*.do").permitAll() .antMatchers("/collection/*.do").permitAll() .antMatchers("/sample/password/getSampleEncoder.do").permitAll() + .antMatchers("/*/*Ajax.do").permitAll() + .antMatchers("/fileupload/**").permitAll() + .antMatchers("/board/**").permitAll() + .antMatchers("/inform/**").permitAll() + .antMatchers("/alert/**").permitAll() + .antMatchers("/code/**").permitAll() .anyRequest().authenticated() .and().formLogin() .loginPage("/login/loginForm.do") diff --git a/src/main/java/nlib/user/service/NlibLoginVO.java b/src/main/java/nlib/user/service/NlibLoginVO.java index 6b2f065c..6dfa17d7 100644 --- a/src/main/java/nlib/user/service/NlibLoginVO.java +++ b/src/main/java/nlib/user/service/NlibLoginVO.java @@ -36,35 +36,19 @@ public class NlibLoginVO implements Serializable { private String loginUserId; /* 로그인사용자ID (이메일주소) */ private String deptSeq; /* 조직코드 */ private String deptNm; /* 조직명 */ - private String userDiv; /* 사용자구분 */ private String userNm; /* 사용자명 */ private String userPwd; /* 비밀번호 */ - private String posNm; /* 직위 */ - private String rank; /* 직급 */ - private String workFlag; /* 근무여부 */ private String telNo; /* 전화번호 */ private String zipcode; /* 우편번호 (변경예정) */ private String addr1; /* 주소1 (변경예정) */ private String addr2; /* 주소2 (변경예정) */ - private String strtMenuSeq; /* 시작페이지 */ - private String idCardChkYn; /* 신분증 확인여부 */ - private String useYn; /* 사용여부 */ - private String ssoFlag; /* 시스템구분(1:기록관리,2:기관배치) */ - private String loginErrorCnt; /* 로그인오류건수 */ - private String onnaraUserid; /* 온나라사용자아이디(웹서비스용) */ - private String pkiNameCheck; /* 인증서 등록시 이름 체크 구분 */ - private String ssoKey; /* SSO 인증KEY (SSO를 위한 사용자의 KEY값) */ + private String status; /* 상태 : S정상, D탈퇴, P휴면 */ private String regId; /* 등록자 */ private String regDd; /* 등록일자 */ private String modId; /* 수정자 */ private String modDd; /* 수정일자 */ private String email; /* 이메일 */ private String mobileNo; /* 모바일 */ - private String websiteAddr; /* 웹사이트 */ - private String facebookId; /* 페이스북아이디 */ - private String twitterId; /* 트위터아이디 */ - private String googleId; /* 구글플러스아이디 */ - private String boardRowCnt; /* 글목록수 */ private String birthdate; /* 생년월일 */ private String gender; /* 성별(M:남자,F:여자) */ @@ -98,9 +82,11 @@ public class NlibLoginVO implements Serializable { return this.authKey; } + //---------------------------------------------------------------- // SETTER.GETTER //---------------------------------------------------------------- + public String getUserId() { return userId; } @@ -125,18 +111,22 @@ public class NlibLoginVO implements Serializable { this.deptSeq = deptSeq; } - public String getUserDiv() { - return userDiv; + public String getDeptNm() { + return deptNm; } - public void setUserDiv(String userDiv) { - this.userDiv = userDiv; + public void setDeptNm(String deptNm) { + this.deptNm = deptNm; } public String getUserNm() { return userNm; } + public String getName() { + return userNm; + } + public void setUserNm(String userNm) { this.userNm = userNm; } @@ -149,30 +139,6 @@ public class NlibLoginVO implements Serializable { this.userPwd = userPwd; } - public String getPosNm() { - return posNm; - } - - public void setPosNm(String posNm) { - this.posNm = posNm; - } - - public String getRank() { - return rank; - } - - public void setRank(String rank) { - this.rank = rank; - } - - public String getWorkFlag() { - return workFlag; - } - - public void setWorkFlag(String workFlag) { - this.workFlag = workFlag; - } - public String getTelNo() { return telNo; } @@ -205,68 +171,12 @@ public class NlibLoginVO implements Serializable { this.addr2 = addr2; } - public String getStrtMenuSeq() { - return strtMenuSeq; + public String getStatus() { + return status; } - public void setStrtMenuSeq(String strtMenuSeq) { - this.strtMenuSeq = strtMenuSeq; - } - - public String getIdCardChkYn() { - return idCardChkYn; - } - - public void setIdCardChkYn(String idCardChkYn) { - this.idCardChkYn = idCardChkYn; - } - - public String getUseYn() { - return useYn; - } - - public void setUseYn(String useYn) { - this.useYn = useYn; - } - - public String getSsoFlag() { - return ssoFlag; - } - - public void setSsoFlag(String ssoFlag) { - this.ssoFlag = ssoFlag; - } - - public String getLoginErrorCnt() { - return loginErrorCnt; - } - - public void setLoginErrorCnt(String loginErrorCnt) { - this.loginErrorCnt = loginErrorCnt; - } - - public String getOnnaraUserid() { - return onnaraUserid; - } - - public void setOnnaraUserid(String onnaraUserid) { - this.onnaraUserid = onnaraUserid; - } - - public String getPkiNameCheck() { - return pkiNameCheck; - } - - public void setPkiNameCheck(String pkiNameCheck) { - this.pkiNameCheck = pkiNameCheck; - } - - public String getSsoKey() { - return ssoKey; - } - - public void setSsoKey(String ssoKey) { - this.ssoKey = ssoKey; + public void setStatus(String status) { + this.status = status; } public String getRegId() { @@ -317,55 +227,6 @@ public class NlibLoginVO implements Serializable { this.mobileNo = mobileNo; } - public String getWebsiteAddr() { - return websiteAddr; - } - - public void setWebsiteAddr(String websiteAddr) { - this.websiteAddr = websiteAddr; - } - - public String getFacebookId() { - return facebookId; - } - - public void setFacebookId(String facebookId) { - this.facebookId = facebookId; - } - - public String getTwitterId() { - return twitterId; - } - - public void setTwitterId(String twitterId) { - this.twitterId = twitterId; - } - - public String getGoogleId() { - return googleId; - } - - public void setGoogleId(String googleId) { - this.googleId = googleId; - } - - public String getBoardRowCnt() { - return boardRowCnt; - } - - public void setBoardRowCnt(String boardRowCnt) { - this.boardRowCnt = boardRowCnt; - } - - public String getAuthKey() { - - return authKey; - } - - public void setAuthKey(String authKey) { - this.authKey = authKey; - } - public String getBirthdate() { return birthdate; } @@ -382,20 +243,12 @@ public class NlibLoginVO implements Serializable { this.gender = gender; } - public String getDeptNm() { - return deptNm; + public String getAuthKey() { + return authKey; } - public void setDeptNm(String deptNm) { - this.deptNm = deptNm; - } - - public String getAccIp() { - return accIp; - } - - public void setAccIp(String accIp) { - this.accIp = accIp; + public void setAuthKey(String authKey) { + this.authKey = authKey; } public String getLoginSucsYn() { @@ -406,6 +259,14 @@ public class NlibLoginVO implements Serializable { this.loginSucsYn = loginSucsYn; } + public String getAccIp() { + return accIp; + } + + public void setAccIp(String accIp) { + this.accIp = accIp; + } + public String getAuthorityList() { return authorityList; } diff --git a/src/main/java/nlib/user/service/impl/LoginDAO.java b/src/main/java/nlib/user/service/impl/LoginDAO.java index 86a1d1de..81cc39c1 100644 --- a/src/main/java/nlib/user/service/impl/LoginDAO.java +++ b/src/main/java/nlib/user/service/impl/LoginDAO.java @@ -24,7 +24,7 @@ public class LoginDAO extends EgovComAbstractDAO { } public void insertLoginLog(NlibLoginVO userVO) { - insert("BBSArticle.insertLoginLog", userVO); + insert("LoginDAO.insertLoginLog", userVO); } } \ 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 5e6b70fe..aec851e7 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -110,12 +110,16 @@ public class LoginServiceImpl implements LoginService 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(); } diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java index 65bbfd99..a058421a 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -120,14 +120,17 @@ public class LoginController { * @return */ @RequestMapping("/login/loginForm.do") - public String loginForm(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)); - } + 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); diff --git a/src/main/resources/egovframework/mapper/config/mapper-config.xml b/src/main/resources/egovframework/mapper/config/mapper-config.xml index 6a706d7f..03e9d61a 100644 --- a/src/main/resources/egovframework/mapper/config/mapper-config.xml +++ b/src/main/resources/egovframework/mapper/config/mapper-config.xml @@ -12,8 +12,9 @@ - - + + + \ 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 4489e05f..5b325e2a 100644 --- a/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/user/LoginDAO_SQL.xml @@ -4,7 +4,7 @@ @@ -35,7 +35,7 @@ ,#{deptSeq} ,#{deptNm} ,#{accIp} - ,#{loginSucsYn} + ,'Y' ,NOW() ) 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 41dc45e3..81163423 100644 --- a/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml +++ b/src/main/resources/egovframework/mapper/nlib/user/SecUserDAO_SQL.xml @@ -3,7 +3,7 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - SELECT A.*, CASE WHEN A.USER_DIV = '1' THEN 'ROLE_USER' WHEN A.USER_DIV = '2' THEN 'ROLE_USER, ROLE_ADMIN' @@ -13,7 +13,7 @@ FROM TMP_SM_USER A /* 사용자정보 */ WHERE A.USE_YN = 'Y' AND A.LOGIN_USER_ID = #{loginUserId} - AND LIMIT 1 + LIMIT 1 \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp b/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp index 5cfc396e..06169234 100644 --- a/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp +++ b/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp @@ -49,6 +49,13 @@
+ +error : ${error } + 
+message : ${message } + 

+ diff --git a/src/main/webapp/WEB-INF/tiles/inc/header.jsp b/src/main/webapp/WEB-INF/tiles/inc/header.jsp index 62502593..34168e53 100644 --- a/src/main/webapp/WEB-INF/tiles/inc/header.jsp +++ b/src/main/webapp/WEB-INF/tiles/inc/header.jsp @@ -11,7 +11,6 @@
  • 개인정보처리방침
  • 이용약관
  • -
  • 로그인
  • 로그인
  • @@ -26,8 +25,8 @@
  • - - + + ${userName}님 (${userId}) From d985bebb796cabec200afc5dd4baf93e80bbba83 Mon Sep 17 00:00:00 2001 From: KNKIM Date: Fri, 20 Aug 2021 17:46:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EC=83=81=EC=9D=B4=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B8=EC=85=98?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=20-=20=EC=A4=91=EA=B0=84=EB=B0=B1?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nlib/security/SpringSecurityConfig.java | 2 + .../user/service/impl/LoginServiceImpl.java | 107 ++++++++++++++++++ .../java/nlib/user/web/LoginController.java | 27 +++++ src/main/java/nlib/util/StringUtil.java | 37 +++++- .../WEB-INF/jsp/nlib/login/loginForm.jsp | 5 + src/main/webapp/homes/mapo.jsp | 45 ++++++++ src/main/webapp/homes/seoul.jsp | 52 +++++++++ src/main/webapp/login/index.jsp | 4 +- 8 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 src/main/webapp/homes/mapo.jsp create mode 100644 src/main/webapp/homes/seoul.jsp diff --git a/src/main/java/nlib/security/SpringSecurityConfig.java b/src/main/java/nlib/security/SpringSecurityConfig.java index eab90855..0e796bdb 100644 --- a/src/main/java/nlib/security/SpringSecurityConfig.java +++ b/src/main/java/nlib/security/SpringSecurityConfig.java @@ -54,6 +54,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/js/**") .antMatchers("/temp/**") .antMatchers("/favicon/**") + .antMatchers("/homes/**") ; } @@ -83,6 +84,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/inform/**").permitAll() .antMatchers("/alert/**").permitAll() .antMatchers("/code/**").permitAll() + .antMatchers("/homes/**").permitAll() .anyRequest().authenticated() .and().formLogin() .loginPage("/login/loginForm.do") diff --git a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java index aec851e7..3305d0e7 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -73,6 +73,60 @@ public class LoginServiceImpl implements LoginService } + /* SNS 연동 SSO를 통한 로그인 처리한다. + * + * return값이 null인 경우, 정상적인 로그인 처리 완료 + * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) + * + */ +// public String loginOauth(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.getUserPwd()); +// +// try { +// // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. +// Authentication authentication = authenticationManager.authenticate(token); +// +// // AuthKey 등록 +// SecUserVO userVO = (SecUserVO)authentication.getPrincipal(); +// userVO.getAndCreateAuthKey(req.getSession().getId()); // SET AUTHKEY +// +// // 실제 SecurityContext 에 authentication 정보를 등록한다. +// SecurityContextHolder.getContext().setAuthentication(authentication); +// +// // TODO : 로그인 로그 정보를 통합자료시스템에 전송한다. +// userVO.setAccIp(req.getRemoteAddr()); +// userVO.setLoginSucsYn("Y"); +// 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를 통한 로그인 처리한다. * * return값이 null인 경우, 정상적인 로그인 처리 완료 @@ -93,6 +147,59 @@ public class LoginServiceImpl implements LoginService // 아이디와 패스워드로, Security 가 알아 볼 수 있는 token 객체로 변경한다. UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getLoginUserId(), nLoginVO.getUserPwd()); + try { + // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. + Authentication authentication = authenticationManager.authenticate(token); + + // AuthKey 등록 + SecUserVO userVO = (SecUserVO)authentication.getPrincipal(); + userVO.getAndCreateAuthKey(req.getSession().getId()); // SET AUTHKEY + + // 실제 SecurityContext 에 authentication 정보를 등록한다. + SecurityContextHolder.getContext().setAuthentication(authentication); + + // TODO : 로그인 로그 정보를 통합자료시스템에 전송한다. + userVO.setAccIp(req.getRemoteAddr()); + userVO.setLoginSucsYn("Y"); + 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를 통한 로그인 처리한다. + * + * return값이 null인 경우, 정상적인 로그인 처리 완료 + * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) + * + */ + public String loginSSO(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.getUserPwd()); + try { // AuthenticationManager 에 token 을 넘기면 UserDetailsService 가 받아 처리하도록 한다. Authentication authentication = authenticationManager.authenticate(token); diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java index a058421a..8b93be46 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -36,6 +36,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.util.UriComponentsBuilder; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -145,6 +146,8 @@ public class LoginController { log.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL()); model.addAttribute("kakaoUrl", kakaoLogin.getOAuthURL()); + model.addAttribute("coutTest", "서울시 마포구"); + return "nlib/login/loginForm"; } @@ -362,6 +365,30 @@ public class LoginController { return "redirect:" + redirectUrl; } + + @RequestMapping("/login/loginDept.do") + public String loginDept( + HttpServletRequest req, + HttpServletResponse res, + HttpSession session, + RedirectAttributes redirectAttrs, + ModelMap model) throws Exception { + + String url = req.getRequestURL().toString(); + String deptReturnUrl = url.replaceAll(req.getRequestURI(), "/"); + String deptHostName = StringUtil.getHostName(url); + + log.debug("REQ URL = " + url); + log.debug("deptJsessionId = " + session.getId()); + log.debug("deptHostName = " + deptHostName); + log.debug("deptReturnUrl = " + deptReturnUrl); + + redirectAttrs.addFlashAttribute("deptJsessionId", session.getId()); + redirectAttrs.addFlashAttribute("deptHostName", deptHostName); + redirectAttrs.addFlashAttribute("deptReturnUrl", deptReturnUrl); + + return "redirect:/login/loginForm.do"; + } /** * 로그아웃 후의 처리를 담당한다. 스프링 시큐리티에서 로그아웃이 수행된 후, 호출된다. diff --git a/src/main/java/nlib/util/StringUtil.java b/src/main/java/nlib/util/StringUtil.java index eaf66979..e9c3bc50 100644 --- a/src/main/java/nlib/util/StringUtil.java +++ b/src/main/java/nlib/util/StringUtil.java @@ -1,13 +1,19 @@ package nlib.util; +import java.net.URL; import java.sql.Timestamp; 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; /** *
    @@ -32,7 +38,9 @@ import egovframework.com.utl.fcc.service.EgovStringUtil;
      *
      */
     public class StringUtil extends EgovStringUtil {
    -
    +	
    +	private static final Logger log = LoggerFactory.getLogger(StringUtil.class);
    +	
     	/**
     	 * Null 이거나, 빈문자열(공백 포함)인 경우, true를 리턴한다.
     	 * 
    @@ -137,4 +145,31 @@ public class StringUtil extends EgovStringUtil {
     		Decoder decoder = Base64.getDecoder();
     		return new String(decoder.decode(str.getBytes()));
     	}
    +	
    +	/**
    +	 * URL 주소에서 호스트명을 리턴한다.
    +	 * 
    +	 * 프로토콜://호스트.도메인/URI 에서 호스트명 리턴 
    +	 * (ex) https://seoul.nculture.org/abc/def.do  -> seoul 을 리턴한다. 
    +	 * 
    +	 * @param url
    +	 * @return
    +	 * @throws Exception
    +	 */
    +	public static String getHostName(String url) throws Exception {
    +		if(isEmpty(url)) return "";
    +		
    +		String hostName = "";
    +		
    +		try {
    +			final URL urlObj = new URL(url);
    +			hostName = urlObj.getHost();
    +			if(isEmpty(hostName)) return "";
    +		} catch(Exception e) {
    +			log.error("[ERROR] getHostName(..) : " + e.toString());
    +			return "";
    +		}
    +		
    +		return (hostName.split("\\."))[0];
    +	}
     }
    diff --git a/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp b/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp
    index 06169234..4746cccf 100644
    --- a/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp
    +++ b/src/main/webapp/WEB-INF/jsp/nlib/login/loginForm.jsp
    @@ -67,5 +67,10 @@ message : ${message }
         
     
     
    +-------------------
    +" />
    +_______________
    +
    +
     
     
    \ No newline at end of file
    diff --git a/src/main/webapp/homes/mapo.jsp b/src/main/webapp/homes/mapo.jsp
    new file mode 100644
    index 00000000..a7a218a0
    --- /dev/null
    +++ b/src/main/webapp/homes/mapo.jsp
    @@ -0,0 +1,45 @@
    +<%@ page language="java" contentType="text/html; charset=UTF-8" %>
    +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    +<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %>
    +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
    +
    +
    +
    +
    +
    +
    +마포 문화원
    +
    +
    +
    + 

    + +

    마포 문화원

    + + 

    + +JSESSIONID = <%=session.getId() %> + + 

    + +

    로그인

    +로그인 + + 

    + +

    로그인이 필요한 화면 링크

    +프로퍼티갱신 + + 

    + + + + + diff --git a/src/main/webapp/homes/seoul.jsp b/src/main/webapp/homes/seoul.jsp new file mode 100644 index 00000000..d351a4f0 --- /dev/null +++ b/src/main/webapp/homes/seoul.jsp @@ -0,0 +1,52 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> + + + + + + +서울 문화원 + + + + 

    + +

    서울 문화원

    + + + 

    + +JSESSIONID = <%=session.getId() %> + + 

    + +

    로그인

    +로그인 + + 

    + +

    로그인이 필요한 화면 링크

    +프로퍼티갱신 + +<% +String coutTest = "서울특별시 마포구 "; +%> +" />
    +" /> + + 

    + + + + + diff --git a/src/main/webapp/login/index.jsp b/src/main/webapp/login/index.jsp index a8c362b1..1d3f2449 100644 --- a/src/main/webapp/login/index.jsp +++ b/src/main/webapp/login/index.jsp @@ -1,2 +1,4 @@ <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> - \ No newline at end of file + + +hello \ No newline at end of file From f9cceb2a802dae49572e1ecafad1c93d411e67ed Mon Sep 17 00:00:00 2001 From: KNKIM Date: Mon, 23 Aug 2021 16:17:56 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EB=8B=A4=EC=A4=91=20=ED=98=B8=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B8=EC=85=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ext/oauth/service/OAuthLogin.java | 30 ++ .../ext/oauth/service/OAuthUniversalUser.java | 9 + .../java/nlib/cmm/service/NlibProperty.java | 5 +- .../java/nlib/cmm/session/SessionConfig.java | 72 ++++ .../nlib/security/SpringSecurityConfig.java | 2 +- .../java/nlib/user/service/LoginService.java | 6 +- .../user/service/impl/LoginServiceImpl.java | 49 ++- .../java/nlib/user/web/LoginController.java | 391 +++++++++++++----- src/main/java/nlib/util/StringUtil.java | 2 +- src/main/resources/nlib/nlib.properties | 4 +- src/main/webapp/WEB-INF/web.xml | 5 + src/main/webapp/homes/seoul.jsp | 1 - 12 files changed, 474 insertions(+), 102 deletions(-) create mode 100644 src/main/java/nlib/cmm/session/SessionConfig.java 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 12575d38..5ce7211f 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthLogin.java @@ -20,7 +20,9 @@ public class OAuthLogin { private OAuth20Service oauthService; private OAuthVO oauthVO; + public OAuthLogin(OAuthVO oauthVO) { + this.oauthService = new ServiceBuilder(oauthVO.getClientId()) .apiSecret(oauthVO.getClientSecret()) .callback(oauthVO.getRedirectUrl()) @@ -30,6 +32,17 @@ public class OAuthLogin { this.oauthVO = oauthVO; } + public OAuthLogin(OAuthVO oauthVO, String deptJsessionId) { + + this.oauthService = new ServiceBuilder(oauthVO.getClientId()) + .apiSecret(oauthVO.getClientSecret()) + .callback(appendParam(oauthVO.getRedirectUrl(), "deptJsessionId", deptJsessionId)) + .scope("profile") + .build(oauthVO.getApi20Instance()); + + this.oauthVO = oauthVO; + } + public String getOAuthURL() { return this.oauthService.getAuthorizationUrl(); } @@ -100,6 +113,9 @@ public class OAuthLogin { // 성별 user.setGender(resNode.get("gender").asText()); + // 로그인 성공 + user.setValidLogin(true); + } else if (this.oauthVO.isKakao()) { user.setServiceName(OAuthConfig.KAKAO_SERVICE_NAME); JsonNode resNode = rootNode.get("properties"); @@ -110,4 +126,18 @@ public class OAuthLogin { return user; } + public String appendParam(String url, String paramName, String paramValue) { + if(StringUtil.isEmpty(url)) return ""; + if(StringUtil.isEmpty(paramName)) return url; + + if(StringUtil.isEmpty(paramValue)) paramValue = ""; + + if(url.contains("?")) url += "&"; + else url += "?"; + + url += paramName + "=" + paramValue; + + 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 9d42345e..052033d2 100644 --- a/src/main/java/egovframework/com/ext/oauth/service/OAuthUniversalUser.java +++ b/src/main/java/egovframework/com/ext/oauth/service/OAuthUniversalUser.java @@ -20,6 +20,7 @@ public class OAuthUniversalUser { private String loginIp; private Date lastLogin; + private boolean isValidLogin = false; public boolean isValid() { return StringUtil.isNotEmpty(uid) && StringUtil.isNotEmpty(userId); @@ -121,4 +122,12 @@ public class OAuthUniversalUser { this.gender = gender; } + public boolean isValidLogin() { + return isValidLogin; + } + + public void setValidLogin(boolean isValidLogin) { + this.isValidLogin = isValidLogin; + } + } diff --git a/src/main/java/nlib/cmm/service/NlibProperty.java b/src/main/java/nlib/cmm/service/NlibProperty.java index 560fd8a0..a538ba1d 100644 --- a/src/main/java/nlib/cmm/service/NlibProperty.java +++ b/src/main/java/nlib/cmm/service/NlibProperty.java @@ -109,7 +109,10 @@ public class NlibProperty { if(loadProperties() < 0) return null; } - return properties.getProperty(name); + String value = properties.getProperty(name); + if(value != null) value = value.trim(); + + return value; } /** diff --git a/src/main/java/nlib/cmm/session/SessionConfig.java b/src/main/java/nlib/cmm/session/SessionConfig.java new file mode 100644 index 00000000..a52e396a --- /dev/null +++ b/src/main/java/nlib/cmm/session/SessionConfig.java @@ -0,0 +1,72 @@ +package nlib.cmm.session; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +import nlib.user.service.impl.LoginServiceImpl; +import nlib.util.StringUtil; + +@WebListener +public class SessionConfig implements HttpSessionListener { + + private static final Logger log = LoggerFactory.getLogger(LoginServiceImpl.class); + + 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()); + } + + @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()); + } + } + + 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/security/SpringSecurityConfig.java b/src/main/java/nlib/security/SpringSecurityConfig.java index 0e796bdb..8a6eb302 100644 --- a/src/main/java/nlib/security/SpringSecurityConfig.java +++ b/src/main/java/nlib/security/SpringSecurityConfig.java @@ -54,7 +54,6 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/js/**") .antMatchers("/temp/**") .antMatchers("/favicon/**") - .antMatchers("/homes/**") ; } @@ -85,6 +84,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/alert/**").permitAll() .antMatchers("/code/**").permitAll() .antMatchers("/homes/**").permitAll() + .antMatchers("/homes/**").permitAll() .anyRequest().authenticated() .and().formLogin() .loginPage("/login/loginForm.do") diff --git a/src/main/java/nlib/user/service/LoginService.java b/src/main/java/nlib/user/service/LoginService.java index 87c5f80a..cbdfcf5e 100644 --- a/src/main/java/nlib/user/service/LoginService.java +++ b/src/main/java/nlib/user/service/LoginService.java @@ -10,7 +10,11 @@ public interface LoginService { public String login(HttpServletRequest req, String username, String password); - public String loginOauth(HttpServletRequest req, String snsUserId); + public String loginOauth(HttpServletRequest req, String snsUserId, String deptJsessionId); + + public String loginDeptSSO(HttpServletRequest req, String snsUserId); + + public String loginDept(HttpServletRequest req, String snsUserId); public DataApiResVO logout(DataApiReqVO reqVO); diff --git a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java index 3305d0e7..cd99ff29 100644 --- a/src/main/java/nlib/user/service/impl/LoginServiceImpl.java +++ b/src/main/java/nlib/user/service/impl/LoginServiceImpl.java @@ -13,9 +13,11 @@ 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.session.SessionConfig; import nlib.restful.service.DataApiReqVO; import nlib.restful.service.DataApiResVO; import nlib.security.SecUserVO; @@ -133,7 +135,48 @@ public class LoginServiceImpl implements LoginService * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) * */ - public String loginOauth(HttpServletRequest req, String snsUserId) { + public String loginOauth(HttpServletRequest req, String snsUserId, String deptJsessionId) { + + // 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.getUserPwd()); + + 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(); + } + + return null; + } + + public String loginDeptSSO(HttpServletRequest req, String snsUserId) { // SNS 연동 사용자UID로 사용자정보 조회 if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso"; @@ -179,6 +222,8 @@ public class LoginServiceImpl implements LoginService return null; } + + /* SNS 연동 SSO를 통한 로그인 처리한다. * @@ -186,7 +231,7 @@ public class LoginServiceImpl implements LoginService * null이 아닌 경우, REDIRECT되어야 하는 URL(오류 코드 포함) * */ - public String loginSSO(HttpServletRequest req, String snsUserId) { + public String loginDept(HttpServletRequest req, String snsUserId) { // SNS 연동 사용자UID로 사용자정보 조회 if(StringUtil.isEmpty(snsUserId)) return "/login/loginForm.do?error=req-sns-sso"; diff --git a/src/main/java/nlib/user/web/LoginController.java b/src/main/java/nlib/user/web/LoginController.java index 8b93be46..743d648d 100644 --- a/src/main/java/nlib/user/web/LoginController.java +++ b/src/main/java/nlib/user/web/LoginController.java @@ -1,8 +1,6 @@ package nlib.user.web; -import java.io.IOException; -import java.net.URI; import java.util.Map; import javax.annotation.Resource; @@ -12,48 +10,26 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.support.RedirectAttributes; -import org.springframework.web.util.UriComponentsBuilder; - -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.github.scribejava.core.model.OAuth2AccessToken; import egovframework.com.ext.oauth.service.OAuthConfig; import egovframework.com.ext.oauth.service.OAuthLogin; import egovframework.com.ext.oauth.service.OAuthUniversalUser; import egovframework.com.ext.oauth.service.OAuthVO; import nlib.cmm.service.NlibProperty; -import nlib.cmm.snslogin.GoogleOAuthResponse; -import nlib.cmm.snslogin.KakaoController; -import nlib.cmm.snslogin.NaverLoginBO; +import nlib.cmm.session.SessionConfig; import nlib.user.service.LoginService; import nlib.util.StringUtil; @@ -125,32 +101,82 @@ public class LoginController { @RequestParam(required = false) String error, @RequestParam(required = false) String message, @RequestParam(required = false) String logout, + RedirectAttributes redirectAttrs, + @RequestParam Map paramMap, Model model, HttpSession session) { + //---------------------------------------------- + // 지방문화원 사이트에서 접속한 경우, 지방문화원 정보 확인 + //---------------------------------------------- + String deptJsessionId = paramMap.get("deptJsessionId"); + String deptHostName = paramMap.get("deptHostName"); + String deptReturnUrl = paramMap.get("deptReturnUrl"); + String deptHomeUrl = paramMap.get("deptHomeUrl"); + + log.debug("loginForm > deptJsessionId = " + deptJsessionId); + log.debug("loginForm > deptHostName = " + deptHostName); + log.debug("loginForm > deptReturnUrl = " + deptReturnUrl); + log.debug("loginForm > deptHomeUrl = " + deptHomeUrl); + + 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)); + + //---------------------------------------------- + // SNS 연동 URL 생성 + //---------------------------------------------- + OAuthLogin naverLogin = new OAuthLogin(naverAuthVO, deptJsessionId); + log.debug("naverLogin.getOAuthURL() = "+naverLogin.getOAuthURL()); + model.addAttribute("naverUrl", naverLogin.getOAuthURL()); + + OAuthLogin googleLogin = new OAuthLogin(googleAuthVO, deptJsessionId); + log.debug("googleLogin.getOAuthURL() = "+googleLogin.getOAuthURL()); + model.addAttribute("googleUrl", googleLogin.getOAuthURL()); + + OAuthLogin kakaoLogin = new OAuthLogin(kakaoAuthVO, deptJsessionId); + log.debug("kakaoLogin.getOAuthURL() = "+kakaoLogin.getOAuthURL()); + model.addAttribute("kakaoUrl", kakaoLogin.getOAuthURL()); 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.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) { @@ -184,53 +210,70 @@ public class LoginController { // 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, 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을 이용해서 사용자 제공정보 가져오기 - OAuthLogin oauthLogin = new OAuthLogin(oauthVO); - - OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시 - log.debug("Profile ===>>" + oauthUser); - - String loginResult = loginService.loginOauth(req, oauthUser.getUid()); - - // 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; - } - return "redirect:" + redirectUrl; - } +// @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 }) @@ -334,6 +377,128 @@ 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}) + 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 연동 콜백정보가 올바르지 않습니다."); + } + + String deptJsessionId = paramMap.get("deptJsessionId"); + + // 1. code를 이용해서 Access Token 받기 + // 2. Access Token을 이용해서 사용자 제공정보 가져오기 + OAuthLogin oauthLogin = new OAuthLogin(oauthVO, deptJsessionId); + + OAuthUniversalUser oauthUser = oauthLogin.getUserProfile(code); // 1,2번 동시 + log.debug("Profile ===>>" + oauthUser); + + 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", "정상적으로 로그인되었습니다."); + String deptHomeUrl = (String)session.getAttribute("deptHomeUrl"); + redirectUrl = deptHomeUrl + "/login/loginDeptSSO.do"; + } + // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 + else { + model.addAttribute("code", "GONEW"); + model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?"); + redirectUrl = loginResult; + } + + return "redirect:" + redirectUrl; + } + /** * 로그인을 처리한다. (스프링 시큐리티 로그인 수행) * @@ -371,23 +536,63 @@ public class LoginController { HttpServletRequest req, HttpServletResponse res, HttpSession session, - RedirectAttributes redirectAttrs, + @RequestParam(required = false) String returnUrl, ModelMap model) throws Exception { String url = req.getRequestURL().toString(); - String deptReturnUrl = url.replaceAll(req.getRequestURI(), "/"); + 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); - redirectAttrs.addFlashAttribute("deptJsessionId", session.getId()); - redirectAttrs.addFlashAttribute("deptHostName", deptHostName); - redirectAttrs.addFlashAttribute("deptReturnUrl", deptReturnUrl); + 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( + HttpServletRequest req, + HttpServletResponse res, + HttpSession session, + ModelMap model) throws Exception { + + String redirectUrl = "/index.do"; + + String snsUserId = SessionConfig.getLoginInfo(session.getId()); + String loginResult = loginService.loginDeptSSO(req, snsUserId); + + // oAuth를 통한 SNS연동이 실패한 경우 + if(loginResult == null) { + // 세션에 설정된 redirect 주소 확인 + String deptReturnUrl = (String)session.getAttribute("deptReturnUrl"); + + log.debug("loginDeptSSO > deptReturnUrl = " + deptReturnUrl); + if(StringUtil.isNotEmpty(deptReturnUrl)) { + redirectUrl = deptReturnUrl; + } + } + // SNS 로그인은 정상적이나, NLIB 시스템에 등록되지 않은 사용자 : 회원가입으로 전환 + else { + model.addAttribute("code", "GONEW"); + model.addAttribute("message", "먼저 회원가입하신 후, 이용 가능합니다. 해당 SNS 계정 정보로 회원가입을 진행하시겠습니까?"); + redirectUrl = loginResult; + } + + return "redirect:" + redirectUrl; - return "redirect:/login/loginForm.do"; } /** diff --git a/src/main/java/nlib/util/StringUtil.java b/src/main/java/nlib/util/StringUtil.java index e9c3bc50..493f07cd 100644 --- a/src/main/java/nlib/util/StringUtil.java +++ b/src/main/java/nlib/util/StringUtil.java @@ -156,7 +156,7 @@ public class StringUtil extends EgovStringUtil { * @return * @throws Exception */ - public static String getHostName(String url) throws Exception { + public static String getHostName(String url) { if(isEmpty(url)) return ""; String hostName = ""; diff --git a/src/main/resources/nlib/nlib.properties b/src/main/resources/nlib/nlib.properties index 2e5c1f71..ae930a98 100644 --- a/src/main/resources/nlib/nlib.properties +++ b/src/main/resources/nlib/nlib.properties @@ -91,13 +91,13 @@ 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 oauth2.client.provider.naver.user-name-attribute = response - #---------------------------------------- # \ub85c\uadf8\uc778/\ud68c\uc6d0\uac00\uc785\uad00\ub828 URL \uc815\ubcf4 #---------------------------------------- member.new.url = /member/insertMemberInfoForm.do member.login.url = /member/insertMemberInfoForm.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/web.xml b/src/main/webapp/WEB-INF/web.xml index 7c82d6bc..29244d90 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -45,6 +45,11 @@ org.springframework.web.context.ContextLoaderListener + + + + org.springframework.web.context.ContextLoaderListener + action diff --git a/src/main/webapp/homes/seoul.jsp b/src/main/webapp/homes/seoul.jsp index d351a4f0..6d88b279 100644 --- a/src/main/webapp/homes/seoul.jsp +++ b/src/main/webapp/homes/seoul.jsp @@ -4,7 +4,6 @@ <%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> -