package nlib.user.service.impl; import java.util.HashMap; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; 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.SecurityContextHolder; import org.springframework.stereotype.Service; import egovframework.com.ext.oauth.service.OAuthUniversalUser; import nlib.cmm.service.NlibProperty; import nlib.cmm.session.SessionConfig; 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") public class LoginServiceImpl implements LoginService { private static final Logger log = LoggerFactory.getLogger(LoginServiceImpl.class); @Autowired private AuthenticationManager authenticationManager; @Resource(name="loginDAO") private LoginDAO loginDAO; /* * 입력된 로그인정보를 받아 로그인 처리한다. * 정상인 경우 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); 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 joinCouncilCd, String councilJsessionId) { if(StringUtil.isEmpty(snsId)) return ERR_CODE_REQ_SNSLOGIN; // SNS 연동 사용자UID로 사용자정보 조회 NlibLoginVO nLoginParamVO = new NlibLoginVO(); nLoginParamVO.setSnsId(snsId); nLoginParamVO.setSnsType(oauthServiceName); nLoginParamVO.setJoinCouncilCd(joinCouncilCd); NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(nLoginParamVO); if(nLoginVO == null) { return ERR_CODE_REQ_MEMBERSHIP; } // 세션목록관리에 로그인 정상 가능 정보 추가 // TODO //SessionConfig.setLoginInfo(councilJsessionId, o); // 회원가입정보 존재하는 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 councilCd, OAuthUniversalUser oUser) { if(oUser == null) return ERR_CODE_REQ_SNSLOGIN; if(!oUser.isValid()) return ERR_CODE_REQ_SNSLOGIN; // SNS 연동 사용자UID로 사용자정보 조회 NlibLoginVO nLoginParamVO = new NlibLoginVO(); nLoginParamVO.setSnsId(oUser.getSnsId()); nLoginParamVO.setSnsType(oUser.getSnsType()); nLoginParamVO.setJoinCouncilCd(councilCd); NlibLoginVO nLoginVO = loginDAO.selectLoginUserInfo(nLoginParamVO); if(nLoginVO == null) { return ERR_CODE_REQ_MEMBERSHIP; } // Spring Security 로그인처리위한 token 생성하여 로그인 처리 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nLoginVO.getUsername(), 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인 경우, 정상적인 로그인 처리 완료 * 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인 경우, 정상적인 로그인 처리 완료 * 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 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; // } }