단일 로그 인 시스템 기술 (SSO) 정리 (2)

시스템 의 두 가지 단일 로그 인 실현 방식:
1、  단일 로그 인 인증 시스템 에 직접 로그 인 합 니 다.
2、  로그 인 업무 시스템, 예 를 들 어 사용자 가 이때 처음으로 로그 인 하면 단일 로그 인 인증 인터페이스 로 전환 합 니 다.사용자 가 인증 을 통과 하면 업무 시스템 에 직접 로그 인 합 니 다.
 
[보충 설명]
단일 로그 인 인증 서버 주소:http://192.168.61.124:8080/SSOAuth_v1.0.0/
비 즈 니스 시스템 서버 주소:http://192.168.61.134:8080/sepmis_v1.3.0/
 
직접 로그 인 단일 로그 인 인증 시스템 절차:
1、  단일 로그 인 인증 서버 로그 인 페이지 를 열 고 사용자 이름 비밀 번 호 를 입력 하 십시오.
单点登录系统技术(SSO)梳理(二)_第1张图片
2、  인증 을 통과 하면 이 페이지 는 시스템 메 인 인터페이스 main. jsp 로 이동 합 니 다.이 때 main. jsp 페이지 를 불 러 오 는 동시에 페이지 백 엔 드 는 ajax 에서 jsonp 방식 으로 단일 로그 인 인증 서버 백 엔 드 Action 에 hello 요청 을 보 냅 니 다.매개 변 수 를 전달 해 야 합 니 다. 현재 사용자 코드 입 니 다.
main. jsp 페이지 의 핵심 코드 는 다음 과 같 습 니 다.
<%
    UserSession userSession = (UserSession)session.getAttribute(AppConst.USER_SESSION_ID);
    String userCode = "";
    String userName = "";
    
    if(null != userSession){
       userCode = userSession.getUserCode();
       userName = userSession.getUserType();
    }
%>  
 
<script type="text/javascript">
    $.ajax({  
       type: "get",  
       contentType: "application/json",
       url: "http://192.168.61.124:8080/SSOAuth_v1.0.0/hello.do?usercode=<%=userCode%>&callback=?",  
       crossDomain: true,
       success: function(data) {  
            $.each(data.msg, function () {
                $.getJSON(this); 
            });
       }
    });  
    </script>

3、  배경 에서 hello 요청 을 받 아들 이 고 전 달 된 매개 변수 사용자 코드 를 통 해 SysRealuser 표 에서 사용자 가 접근 할 수 있 는 업무 시스템 대상 을 판단 합 니 다.업무 시스템 대상 중 url 인 자 를 가 져 와 각 업무 시스템 setCookie Url 을 조직 합 니 다.그리고 제 이 슨 이 보 를 통 해 프론트 데스크 로 전 달 됩 니 다.
Url 형식: (빨간색 글꼴 은 변수)
http://192.168.61.134:8080/sepmis_v1.3.0/setCookie.do?userCode=xxx&&callback=?

코드 는 다음 과 같 습 니 다:
/**
     *                 ,          ,         action  
     *     json  ,         ajax            setcookie action  
     * @return result
     */
    public String hello(){
       try {
           List<SysInfo> tmp = getUserSysRealSys();
           UserSession userSession = AuthorityUtil.getSysUserSession();
           JSONObject jsonObject = new JSONObject();
           JSONArray jsonArray = new JSONArray();
           if(tmp!=null && tmp.size()>0){
              for(int i=0; i<tmp.size(); i++){
                  jsonArray.put(tmp.get(i).getSysUrl() + "/setCookie.do?userCode="+userSession.getUserCode()+"&callback=?");
              }
           }
            jsonObject.put("msg", jsonArray);
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");  
            response.setHeader("Cache-Control", "no-cache");  
           response.getWriter().write(jsonObject.toString());
           response.getWriter().flush();
           //    
           tmp = null;
           userSession = null;
           //    
           String info  = LoggerUtil.getInfoMsg("AJAX    ,              setCookie  ");
           log.info(info);
           return null;
       } catch (IOException ie) {
           this.exceptionMessage.setError(ie.toString());
           this.exceptionMessage.setClassName(this.getClass().getName());
           this.exceptionMessage.setMessage("AJAX      IO  !");
           log.error(ie.toString());
           return ERROR;
       } catch (Exception ex) {
           this.exceptionMessage.setError(ex.toString());
           this.exceptionMessage.setClassName(this.getClass().getName());
           this.exceptionMessage.setMessage("AJAX        !");
           log.error(ex.toString());
           return ERROR;
       }
    }

4、  프론트 데스크 톱 main. jsp 페이지 에서 전 송 된 URL 인 자 를 가 져 옵 니 다. 이 때 Success 코드 세그먼트 의 함 수 를 실행 합 니 다.
success: function(data) {  
            $.each(data.msg, function () {
                $.getJSON(this); 
            });

이 때 function 에서 매개 변수 data 는 전 송 된 URL 매개 변수 이 며, Jquery 에서 getJSON 방법 을 반복 적 으로 실행 합 니 다.이때 AJAX 기술 이 보 를 통 해 각 업무 시스템 에 setCookie 요청 을 보 냈 습 니 다. 이 작업 은 투명 한 로그 인 작업 으로 볼 수 있 고 사용 자 는 감지 할 수 없습니다.

5、  비 즈 니스 시스템 이 setCookie action 요청 을 수락 합 니 다.
코드 는 다음 과 같 습 니 다:
public String setCookie(){
       try{
           // -         
           StringBuilder hql = new StringBuilder(300);
           userCode = request.getParameter("userCode");
           hql.append("FROM SysUser WHERE userCode ='").append(userCode).append("'");
           List<SysUser> sysUserList = sysUserService.findByHql(hql.toString());
           if(sysUserList.size() > 0){
              Cookie cookie = new Cookie("sso", userCode);
              cookie.setPath("/");
              //  cookie    ,    ;
              //                  ,         ,  cookie    
              //cookie     60*60*24*365
              cookie.setMaxAge(60*60); 
              response.addCookie(cookie);
           }
       }catch(Exception ex){
           //      
           this.exceptionMessage.setError(ex.toString());
           this.exceptionMessage.setClassName(this.getClass().getName());
           this.exceptionMessage.setMessage("        !");
           log.info(ex.toString());
           return ERROR;
       }
       return null;
    }

비 즈 니스 시스템 은 setCookie 방법 을 통 해 이 사용 자 를 비 즈 니스 시스템 에 Cookie 를 사용자 로 컬 에 저장 합 니 다.
单点登录系统技术(SSO)梳理(二)_第2张图片
6、  입력 비 즈 니스 시스템 연결.
비 즈 니스 시스템 과 백 엔 드 는 filter 를 통 해 모든 요청 을 걸 러 내 고 사용자 가 현재 서버 도 메 인 에서 Cookie 값 을 가 져 와 검증 합 니 다. 검증 을 통 해 시스템 에 들 어가 고 검증 을 통 해 단일 로그 인 인증 페이지 로 돌아 가지 않 습 니 다.

SSOFilter. java 핵심 코드 는 다음 과 같 습 니 다.
/**
     * servlet filter     
     * @param ServletRequest
     * @param ServletResponse
     * @param FilterChain
     * @throws IOException,ServletException
     */
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
       //     cookie 
       String cookieValue = "";
       HttpServletRequest request = (HttpServletRequest) req;
       HttpServletResponse response = (HttpServletResponse) res;
       String url = request.getRequestURL().toString();
       //     
       String result = null;
       
       //         URL
       String[] urlArray = url.split(request.getContextPath());
       //     service  ,           action
       if (urlArray.length == 2 && ("/").equals(urlArray[1])) {
           response.sendRedirect(url+"loginSSO.do");
           return;
       }else {
           for(int i=0; i<urlArray.length; i++){
              if("/setCookie.do".equals(urlArray[i])){
                  result = "setCookie";
                  break;
              }
           }
       }
       
       //   HTTP   head      cookie
       Cookie[] diskCookies = request.getCookies();
       if (diskCookies != null) {
           log.info("【    -       】  COOKIES");
           for (int i = 0; i < diskCookies.length; i++) {
              cookieValue = diskCookies[i].getValue();
              log.info("【    -       】COOKIES       :" + diskCookies[i].getName() + "=" + cookieValue);
              if (SSO_AUTH.equals(diskCookies[i].getName())) {
                  result = SSOService(cookieValue);
                  if ("success".equals(result)) {
                     log.info("【           】");
                  } else {
                     log.info("【            】COOKIES    ");
                     response.sendRedirect(ssoLoginPage);
                  }
              } else if ("sso".equals(diskCookies[i].getName())) {
                  HttpSession session =  request.getSession(); 
                  session.setAttribute("sso", cookieValue);
                  result = "success";
              }
           }
       } else {
           log.info("【    -       】   COOKIES");
       }
       
       // COOKIES  ,          
       if (result.equals("failed")) {
           log.info("【    -       】COOKIES    ");
           response.sendRedirect(ssoLoginPage);
       //          
       } else if (result.equals("logout")) {
           log.info("【    -       】    ");
           //logoutService(cookieValue);
           response.sendRedirect(ssoLoginPage);
       //     
       } else {
           log.info("【    -       】    ");
           Throwable problem = null;
           try {
              chain.doFilter(req, res);
           } catch (Throwable t) {
              problem = t;
              t.printStackTrace();
           }
           if (problem != null) {
              if (problem instanceof ServletException) {
                  throw ((ServletException) problem);
              }
              if (problem instanceof IOException) {
                  throw ((IOException) problem);
              }
              sendProcessingError(problem, res);
           }
       }
    }
    
    /**
     *   httpclient        (SSOAuth)  cookie
     * 
     * @param cookievalue
     * @return String 
     * @throws IOException
     */
    private String SSOService(String cookievalue) throws IOException {
       String result = "failed";
       String authAction = "/sso/authcookie.do?cookieName=";
       String tmp = this.ssoServiceURL + authAction + cookievalue;
       //   http           (SSOAuth)  httpclient  
       HttpClient httpclient = new HttpClient();
       GetMethod httpget = new GetMethod(tmp);
       httpget.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
       try {
           //   getMethod
           int statusCode = httpclient.executeMethod(httpget);
           if (statusCode != HttpStatus.SC_OK) {
              log.error("HttpClient Method failed: " + httpget.getStatusLine());
           }
           //       
           result = httpget.getResponseHeader("result").getValue();
       } catch (HttpException e) {
           //        ,                 
           log.error("Please check your HttpClient address!");
           log.error(e.toString());
       } catch (IOException e) {
           //       
           log.error(e.toString());
       } finally {
           httpget.releaseConnection();
       }
       log.info("【    -       】    result=" + result);
       return result;
    }

업무 시스템 fileter 를 통 해 요청 에 따라 다른 작업 을 수행 합 니 다.업무 시스템 Cookie 를 가 져 온 후 HttpClient 클래스 를 사용 하여 단일 인증 중의 authckie 방법 을 호출 하여 사용자 Cookie 의 합 법성 을 검증 합 니 다.
RealSysLoginAction. java 클래스 authckie 방법 코드:
/**
     *       cookie ,               ,        ,
     *               。
     * @return result
     */
    public String authcookie(){
       try{
           String info = null;
           SysUser tmpUser = sysUserService.getSysUserById(getCookieName());
           if( tmpUser == null){
              response.setHeader("result", "failed");
              info  = LoggerUtil.getInfoMsg("         cookie 。");
           }else{
              response.setHeader("result", "success");
              info  = LoggerUtil.getInfoMsg("        cookie 。");
           }
           //    
           tmpUser = null;
           //    
           log.info(info);
           return null;
       }catch(Exception ex){
           this.exceptionMessage.setError(ex.toString());
           this.exceptionMessage.setClassName(this.getClass().getName());
           this.exceptionMessage.setMessage("          !");
           log.error(ex.toString());
           return ERROR;
       }
    }

이 로그 인 방법 은 기 존 업무 시스템 의 로그 인 action 방법 을 수정 해 야 합 니 다.
 
비 즈 니스 시스템 LoginSSOAAction. java 클래스, loginSSO 로그 인 방법
public String loginSSO(){
       try {
           //               
           String sysUserCode = ActionContext.getContext().getSession().get("sso").toString();
           log.info("【    】        :[sysUserCode="+sysUserCode+"]");
           
           SysUser sysUser_ = this.loginService.findByPk(sysUserCode);
           //           
           if (sysUser_ != null) {
              //          
                  // -         
                  StringBuilder hql = new StringBuilder(300);
                  hql.append("SELECT sg.sysRole FROM SysUserGroup su, SysGroupRole sg WHERE su.id.userCode = '").append(sysUserCode)
                     .append("' AND su.id.groupCode = sg.id.groupCode AND sg.sysRole.roleType = '").append(AppConst.ROLE_TYPE_01).append("'");
                  List<SysRole> rolesList = this.sysRoleService.findSysRoleList(hql.toString());
                  // -             ,             
                  // -           
                  Map<String, SysRole> funcPowersMap = new HashMap<String, SysRole>();
                  for (SysRole role : rolesList) {
                     funcPowersMap.put(role.getRoleCode(), role);
                  }
                  // -   UserSession
                  UserSession userSession = new UserSession();
                  userSession.setUserCode(sysUserCode);
                  userSession.setUserName(sysUser_.getUserName());
                  userSession.setComCode(sysUser_.getSysCompany().getComCode());
                  userSession.setComCname(sysUser_.getSysCompany().getComCname());
                  userSession.setAreaCode(sysUser_.getSysCompany().getSysArea().getAreaCode());
                  userSession.setComType(sysUser_.getSysCompany().getComType());
                  userSession.setComLevel(sysUser_.getSysCompany().getComLevel());
                  userSession.setFuncPowers(funcPowersMap);
                  //      session
                  ActionContext.getContext().getSession().put(AppConst.USER_SESSION_ID, userSession);
                  //  map  
                  funcPowersMap = null;
                  //    
                  StringBuffer infoBuffer = new StringBuffer();
                  infoBuffer.append("【    】     : ");
                  infoBuffer.append(userSession.getComCode());
                  infoBuffer.append("     : ");
                  infoBuffer.append(userSession.getUserCode());
                  infoBuffer.append(" (");
                  infoBuffer.append(userSession.getUserName());
                  infoBuffer.append(")     : ");
                  infoBuffer.append(new DateTime(DateTime.current(), DateTime.YEAR_TO_SECOND));
                  infoBuffer.append("     !");
                  log.info(infoBuffer.toString());
                  return SUCCESS;
              } else {
                  this.exceptionMessage.setClassName(this.getClass().getName());
                  this.exceptionMessage.setMessage("     !");
                  log.info("     !");
                  return ERROR;
              }
       } catch (Exception e) {
           //      
           this.exceptionMessage.setError(e.toString());
           this.exceptionMessage.setClassName(this.getClass().getName());
           this.exceptionMessage.setMessage("        !");
           log.info(e.toString());
           return ERROR;
       }
    }

单点登录系统技术(SSO)梳理(二)_第3张图片
비 즈 니스 시스템 총 filter 웹. xml 파일 에 설정 방법:
 <!--       Fileter start-->
     <filter>
        <filter-name>SSOFilter</filter-name>
        <filter-class>SSO.SSOFilter</filter-class>
        <init-param>
            <param-name>cookieName</param-name>
            <param-value>hzpCookies</param-value>
        </init-param>
        <init-param>
            <param-name>ssoServiceURL</param-name>
            <param-value>http://192.168.61.124:8080/SSOAuth_v1.0.0/</param-value>
        </init-param>
        <init-param>
            <param-name>ssoLoginPage</param-name>
            <param-value>http://192.168.61.124:8080/SSOAuth_v1.0.0/login.jsp</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SSOFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--       Fileter end-->

인증 을 통과 하지 않 고 업무 시스템 에 로그 인하 여 단일 로그 인 인증 으로 전환 합 니 다.
1、  비 즈 니스 시스템 서비스 주소 입력
2、  시스템 은 자동 으로 단일 로그 인 서버 로 이동 합 니 다. 아래 과정 은 위 와 같 습 니 다. "직접 로그 인 단일 로그 인 인증 시스템 프로 세 스"
그 원 리 는 filter 를 통 해 클래스 의 dofilter 방법 을 걸 러 내 고 Cookie 가 없 는 것 으로 판단 하면 단일 로그 인 인증 인터페이스 로 전환 하 는 것 이다.
필터 코드 는 다음 과 같 습 니 다:
//   HTTP   head      cookie
       Cookie[] diskCookies = request.getCookies();
       if (diskCookies != null) {
           log.info("【    -       】  COOKIES");
           for (int i = 0; i < diskCookies.length; i++) {
              cookieValue = diskCookies[i].getValue();
              log.info("【    -       】COOKIES       :" + diskCookies[i].getName() + "=" + cookieValue);
              if (SSO_AUTH.equals(diskCookies[i].getName())) {
                  result = SSOService(cookieValue);
                  if ("success".equals(result)) {
                     log.info("【           】");
                  } else {
                     log.info("【            】COOKIES    ");
                     response.sendRedirect(ssoLoginPage);
                  }
              } else if ("sso".equals(diskCookies[i].getName())) {
                  HttpSession session =  request.getSession(); 
                  session.setAttribute("sso", cookieValue);
                  result = "success";
              }
           }
       } else {
           log.info("【    -       】   COOKIES");
       }
       
       // COOKIES  ,          
       if (result.equals("failed")) {
           log.info("【    -       】COOKIES    ");
           response.sendRedirect(ssoLoginPage);
       //          
       } else if (result.equals("logout")) {
           log.info("【    -       】    ");
           //logoutService(cookieValue);
           response.sendRedirect(ssoLoginPage);
       //     
       } else {
           log.info("【    -       】    ");
           Throwable problem = null;
           try {
              chain.doFilter(req, res);
           } catch (Throwable t) {
              problem = t;
              t.printStackTrace();
           }
           if (problem != null) {
              if (problem instanceof ServletException) {
                  throw ((ServletException) problem);
              }
              if (problem instanceof IOException) {
                  throw ((IOException) problem);
              }
              sendProcessingError(problem, res);
           }
       }

좋은 웹페이지 즐겨찾기