zoukankan      html  css  js  c++  java
  • 单点登陆简单实现(完全跨域、单点退出)

    单点登陆活动图

    废话不多说直接上代码咯,什么好处,实现原理相关资料baidu去,基本都一样,就不复制了

    1.验证中心核心代码

    (1)登陆跳转注销代码   controller层代码

    [java] view plain copy
     
    1. package com.ffcs.sso.controller;  
    2.   
    3. import javax.servlet.http.HttpSession;  
    4.   
    5. import org.apache.commons.lang.StringUtils;  
    6. import org.slf4j.Logger;  
    7. import org.slf4j.LoggerFactory;  
    8. import org.springframework.beans.factory.annotation.Autowired;  
    9. import org.springframework.stereotype.Controller;  
    10. import org.springframework.ui.Model;  
    11. import org.springframework.web.bind.annotation.RequestMapping;  
    12. import org.springframework.web.bind.annotation.RequestMethod;  
    13. import org.springframework.web.bind.annotation.RequestParam;  
    14. import org.springframework.web.servlet.ModelAndView;  
    15.   
    16. import com.ffcs.sso.pojo.User;  
    17. import com.ffcs.sso.service.LogoutManagerService;  
    18. import com.ffcs.sso.service.TicketManagerService;  
    19. import com.ffcs.sso.service.UserManagerService;  
    20. import com.ffcs.sso.utils.Constant;  
    21. /** 
    22.  *  
    23.  * @author damon 
    24.  * 
    25.  */  
    26. @Controller  
    27. public class SSOController {  
    28.       
    29.     private final static Logger LOGGER=LoggerFactory.getLogger(SSOController.class);  
    30.    
    31.     @Autowired  
    32.     private TicketManagerService ticketManagerService;  
    33.       
    34.     @Autowired  
    35.     private UserManagerService userManagerService;  
    36.       
    37.     @Autowired  
    38.     private LogoutManagerService logoutManagerService;  
    39.   
    40.     /** 
    41.      * 主页 
    42.      * @return 
    43.      */  
    44.     @RequestMapping(value="manager/index",method=RequestMethod.GET)  
    45.     public String index(){  
    46.           
    47.         return "index";  
    48.     }  
    49.     /** 
    50.      * 登陆首页 
    51.      * @return 
    52.      */  
    53.     @RequestMapping(value="login",method=RequestMethod.GET)  
    54.     public ModelAndView loginIndex(String queryParams,String targetUrl,ModelAndView modelAndView){  
    55.           
    56.         modelAndView.addObject("queryParams", queryParams);  
    57.           
    58.         modelAndView.addObject("targetUrl", targetUrl);  
    59.           
    60.         modelAndView.setViewName("login");  
    61.           
    62.         return modelAndView;  
    63.     }  
    64.       
    65.     @RequestMapping(value="login",method=RequestMethod.POST)  
    66.     public String login(@RequestParam(required = true) String account, @RequestParam(required = true) String password,  
    67.   
    68.             String targetUrl, String queryParams, Model model, HttpSession session) {  
    69.   
    70.         User user = userManagerService.getUserInfo(account, password);  
    71.   
    72.         if (user != null) {  
    73.   
    74.             String homeCookieId = session.getId();  
    75.   
    76.             session.setAttribute(Constant.SSO_IS_LOGIN, true);  
    77.   
    78.             session.setAttribute(Constant.SSO_LOGIG_INFO, account);  
    79.   
    80.             logoutManagerService.saveLoginUserInfo(homeCookieId, user);  
    81.   
    82.             if (StringUtils.isNotBlank(targetUrl)) {  
    83.   
    84.                 // 生成targetURL对应的票  
    85.   
    86.                 String ticket = ticketManagerService.generateTicket(targetUrl, homeCookieId);  
    87.   
    88.                 String params = StringUtils.isNotBlank(queryParams) ? "&" + queryParams : "";  
    89.   
    90.                 LOGGER.info("###################  用户账号:[{}]  对应主站cookieId:[{}] 登陆系统 :[{}]", account, homeCookieId, targetUrl);  
    91.   
    92.                 return "redirect:" + targetUrl + "?" + Constant.SSO_TICKET + "=" + ticket + params;  
    93.   
    94.             }  
    95.             return "redirect:manager/index";  
    96.   
    97.         } else {  
    98.   
    99.             model.addAttribute("error", "用户名或密码错误!");  
    100.   
    101.             if (StringUtils.isNotBlank(targetUrl)) {  
    102.   
    103.                 model.addAttribute("targetUrl", targetUrl);  
    104.             }  
    105.             return "login";  
    106.         }  
    107.     }  
    108.       
    109.     /** 
    110.      * 重定向到子系统并生成票 
    111.      * @param targetUrl 
    112.      * @param queryParams 
    113.      * @param modelAndView 
    114.      * @param session 
    115.      * @return 
    116.      */  
    117.     @RequestMapping(value="redirect",method=RequestMethod.GET)  
    118.     public ModelAndView redirect(@RequestParam(value="targetUrl",required=true)String targetUrl,  
    119.               
    120.             String queryParams,ModelAndView modelAndView,HttpSession session) {  
    121.       
    122.         if(session.getAttribute(Constant.SSO_IS_LOGIN)==null){  
    123.               
    124.             modelAndView.setViewName("redirect:login");  
    125.               
    126.             modelAndView.addObject("targetUrl", targetUrl);  
    127.               
    128.             modelAndView.addObject("queryParams", queryParams);       
    129.           
    130.             //重定向到login方法,带上目标网页地址  
    131.           
    132.         }else{  
    133.               
    134.             String homeCookieId=session.getId();  
    135.               
    136.             String account=(String) session.getAttribute(Constant.SSO_LOGIG_INFO);  
    137.               
    138.             //生成targetURL对应的票  
    139.               
    140.             String ticket=ticketManagerService.generateTicket(targetUrl,homeCookieId);  
    141.                       
    142.             String params=StringUtils.isNotBlank(queryParams)?"&"+queryParams:"";  
    143.               
    144.             modelAndView.setViewName("redirect:" + targetUrl + "?" + Constant.SSO_TICKET + "=" + ticket + params);    
    145.   
    146.             LOGGER.info("############### 用户账号:[{}] 主站cookieId:[{}] 重定向到系统:[{}] 对应ticket:[{}]", account, homeCookieId, targetUrl, ticket);  
    147.         }  
    148.           
    149.         return modelAndView;  
    150.     }  
    151.       
    152.     /** 
    153.      * 单点注销 
    154.      * @param session 
    155.      * @return 
    156.      */  
    157.     @RequestMapping(value="logout",method=RequestMethod.GET)  
    158.     public String logout(HttpSession session){  
    159.           
    160.         if(session.getAttribute(Constant.SSO_IS_LOGIN)!=null){  
    161.           
    162.             String cookieId=session.getId();  
    163.               
    164.             String account=(String) session.getAttribute(Constant.SSO_LOGIG_INFO);  
    165.               
    166.             logoutManagerService.logout(cookieId);  
    167.               
    168.             session.invalidate();     
    169.                   
    170.             LOGGER.info("########### 单点退出用户账号:[{}] 对应主站cookieId为:[{}] ",account,cookieId);  
    171.         }  
    172.         return "redirect:login";  
    173.     }     
    174.       
    175. }  

    (2)生成票管理接口代码(对外restful webservice发布)

    [java] view plain copy
     
    1. package com.ffcs.sso.service;  
    2.   
    3. import java.util.UUID;  
    4.   
    5. import net.rubyeye.xmemcached.MemcachedClient;  
    6.   
    7. import org.apache.commons.lang.StringUtils;  
    8. import org.springframework.beans.factory.annotation.Autowired;  
    9. import org.springframework.beans.factory.annotation.Qualifier;  
    10. import org.springframework.stereotype.Service;  
    11.   
    12. import com.ffcs.sso.exception.SSOException;  
    13. import com.ffcs.sso.pojo.TicketInfo;  
    14. import com.ffcs.sso.pojo.TicketResponseInfo;  
    15. import com.ffcs.sso.pojo.User;  
    16. import com.ffcs.sso.utils.Constant;  
    17. /** 
    18.  *  
    19.  * 票管理 
    20.  *  
    21.  *  
    22.  *  damon 
    23.  * 
    24.  */  
    25. @Service  
    26. public class TicketManagerServiceImpl implements TicketManagerService{    
    27.       
    28.     @Autowired  
    29.     @Qualifier(value="memcachedSSOClient")  
    30.     private MemcachedClient memcachedClient;  
    31.     @Autowired  
    32.     private LogoutManagerService logoutManagerService;  
    33.   
    34.     @Override  
    35.     public String generateTicket(String target,String homeCookieId){  
    36.           
    37.         if(StringUtils.isBlank(target)){  
    38.               
    39.             throw new IllegalArgumentException("target不可以为空!");  
    40.               
    41.         }  
    42.           
    43.         if(StringUtils.isBlank(homeCookieId)){  
    44.               
    45.             throw new IllegalArgumentException("homeCookieId不可以为空!");  
    46.               
    47.         }  
    48.           
    49.         String ticket=UUID.randomUUID().toString();  
    50.       
    51.         try {  
    52.               
    53.             memcachedClient.set(ticket, Constant.MAX_TICKET_INACTIVE_INTERVAL, new TicketInfo(ticket,target,homeCookieId));  
    54.               
    55.             return ticket;  
    56.               
    57.         } catch (Exception e) {  
    58.   
    59.             throw new SSOException(e);  
    60.         }  
    61.     }  
    62.     @Override   
    63.     public TicketResponseInfo validateTicket(String ticket,String target,  
    64.               
    65.             String subCookieId,String subCookieName,String subLogoutPath){  
    66.           
    67.         if(StringUtils.isBlank(ticket)){  
    68.   
    69.             throw new IllegalArgumentException("ticket不可以为空!");  
    70.         }  
    71.           
    72.         if(StringUtils.isBlank(target)){  
    73.   
    74.             throw new IllegalArgumentException("target不可以为空!");  
    75.         }  
    76.           
    77.         if(StringUtils.isBlank(subCookieId)){  
    78.   
    79.             throw new IllegalArgumentException("subCookieId不可以为空!");  
    80.         }  
    81.   
    82.         if(StringUtils.isBlank(subCookieName)){  
    83.   
    84.             throw new IllegalArgumentException("subCookieName不可以为空!");  
    85.         }  
    86.           
    87.         if(StringUtils.isBlank(subLogoutPath)){  
    88.   
    89.             throw new IllegalArgumentException("subLogoutPath不可以为空!");  
    90.         }  
    91.   
    92.         try {  
    93.               
    94.             TicketInfo ticketInfo = memcachedClient.get(ticket);  
    95.               
    96.             if(ticketInfo==null||!target.equals(ticketInfo.getTargetUrl())){  
    97.                   
    98.                 //返回空验证不通过  
    99.                   
    100.                 return new TicketResponseInfo(false);  
    101.             }  
    102.               
    103.             //删除票保存的临时信息  
    104.               
    105.             memcachedClient.delete(ticket);  
    106.               
    107.             String homeCookieId=ticketInfo.getHomeCookieId();  
    108.               
    109.             //验证后保存登出信息(原本验证和登出信息分开提交,一并提交减少访问次数)  
    110.               
    111.             logoutManagerService.saveSubWebsiteLogouInfo(homeCookieId, subLogoutPath, subCookieId, subCookieName);  
    112.                
    113.             User user= logoutManagerService.getLoginUserInfo(homeCookieId);  
    114.               
    115.             return new TicketResponseInfo(true,user.getAccount(),homeCookieId);  
    116.   
    117.         } catch (Exception e) {  
    118.               
    119.             throw new SSOException(e);  
    120.         }   
    121.       
    122.     }  
    123.   
    124.   
    125. }  

    (3)单点退出接口(对外restful webservice发布

    [java] view plain copy
     
    1. package com.ffcs.sso.service;  
    2.   
    3. import java.util.Set;  
    4.   
    5. import net.rubyeye.xmemcached.MemcachedClient;  
    6.   
    7. import org.apache.commons.lang.StringUtils;  
    8. import org.apache.http.HttpResponse;  
    9. import org.apache.http.client.HttpClient;  
    10. import org.apache.http.client.methods.HttpPost;  
    11. import org.slf4j.Logger;  
    12. import org.slf4j.LoggerFactory;  
    13. import org.springframework.beans.factory.annotation.Autowired;  
    14. import org.springframework.beans.factory.annotation.Qualifier;  
    15. import org.springframework.stereotype.Service;  
    16.   
    17. import com.ffcs.sso.exception.SSOException;  
    18. import com.ffcs.sso.pojo.ActivationInfo;  
    19. import com.ffcs.sso.pojo.LogoutInfo;  
    20. import com.ffcs.sso.pojo.User;  
    21. import com.ffcs.sso.utils.Constant;  
    22.   
    23. /** 
    24.  * 单点退出 
    25.  *  
    26.  * damon 
    27.  */  
    28.   
    29.   
    30. @Service  
    31. public class LogoutManagerServiceImpl implements LogoutManagerService {  
    32.       
    33.     private static final Logger LOGGER=LoggerFactory.getLogger(LogoutManagerServiceImpl.class);  
    34.       
    35.     private final String LOGOUT_PREFIX="LOGOUT_";  
    36.   
    37.     @Autowired  
    38.     @Qualifier("memcachedSSOClient")  
    39.     private MemcachedClient memcachedClient;  
    40.       
    41.     @Autowired  
    42.     private HttpClient httpClient;  
    43.   
    44.     @Override  
    45.     public boolean saveSubWebsiteLogouInfo(String homeCookieId, String logoutPath,String subCookieId,String subCookieName) {  
    46.           
    47.         if(StringUtils.isBlank(homeCookieId)){  
    48.               
    49.             throw new IllegalArgumentException("homeCookieId 不可以为空!");  
    50.         }  
    51.         if(StringUtils.isBlank(logoutPath)){  
    52.           
    53.             throw new IllegalArgumentException("logoutPath 不可以为空!");  
    54.         }  
    55.         if(StringUtils.isBlank(subCookieId)){  
    56.               
    57.             throw new IllegalArgumentException("subWebSite 不可以为空!");  
    58.         }  
    59.         ActivationInfo info=null;  
    60.           
    61.         Set<LogoutInfo> logoutInfos=null;  
    62.           
    63.         try {  
    64.               
    65.             info=memcachedClient.get(LOGOUT_PREFIX + homeCookieId);  
    66.               
    67.             if(info==null){  
    68.                   
    69.                 info=new ActivationInfo();  
    70.       
    71.             }  
    72.             logoutInfos=info.getLogoutInfo();  
    73.               
    74.             logoutInfos.add(new LogoutInfo(logoutPath,subCookieId,subCookieName));  
    75.               
    76.             info.setLogoutInfo(logoutInfos);  
    77.               
    78.             memcachedClient.set(LOGOUT_PREFIX + homeCookieId, Constant.MAX_USERINFO_INACTIVE_INTERVAL, info);  
    79.                   
    80.             LOGGER.debug("############### 保存子站登出信息 ,子站登出地址 url:{}, 子站cookie:{}, 主站cookie:{}", logoutPath, subCookieId, homeCookieId);  
    81.               
    82.             return true;  
    83.           
    84.         } catch (Exception e) {  
    85.               
    86.             throw new SSOException(e);  
    87.         }   
    88.   
    89.     }  
    90.   
    91.     @Override  
    92.     public void logout(String homeCookieId) {  
    93.           
    94.         if(StringUtils.isBlank(homeCookieId)){  
    95.               
    96.             throw new IllegalArgumentException("cookieId 不可以为空!");  
    97.         }  
    98.            
    99.         ActivationInfo info=null;  
    100.           
    101.         Set<LogoutInfo> logoutInfos=null;  
    102.           
    103.         try {  
    104.               
    105.             info = memcachedClient.get(LOGOUT_PREFIX+homeCookieId);  
    106.               
    107.             memcachedClient.delete(LOGOUT_PREFIX+homeCookieId);  
    108.               
    109.             if(info==null|| (logoutInfos=info.getLogoutInfo())==null){  
    110.                   
    111.                 LOGGER.debug("##############  用户 cookieId:[{}] 未登陆任何系统   !",homeCookieId);  
    112.   
    113.                 return;  
    114.             }     
    115.         } catch (Exception e) {  
    116.               
    117.             LOGGER.error("###############   Memcached获取单点登出信息失败", e);  
    118.               
    119.             return;  
    120.         }   
    121.           
    122.         for (LogoutInfo logoutInfo:logoutInfos) {  
    123.   
    124.             HttpPost post=null;  
    125.               
    126.             try {  
    127.   
    128.                 post = new HttpPost(logoutInfo.getLogoutPath());  
    129.                   
    130.                 post.setHeader("charset", "UTF-8");  
    131.                   
    132.                 post.setHeader("Connection", "close");    
    133.                   
    134.                 //添加cookie模拟回调时候子系统能找到session  
    135.                   
    136.                 post.setHeader("Cookie",logoutInfo.getSubCookieName()+"="+logoutInfo.getSubCookieId());  
    137.   
    138.                 HttpResponse response = httpClient.execute(post);  
    139.   
    140.                 LOGGER.debug("########## 登出子站  :[{}] 主站cookie:[{}] 子站cookie:[{}]  登出返回状态码:[{}]  ",  
    141.                           
    142.                         logoutInfo.getLogoutPath(), homeCookieId, logoutInfo.getSubCookieId(),  response.getStatusLine().getStatusCode());  
    143.                   
    144.             } catch (Exception e) {  
    145.                   
    146.                 LOGGER.error("########## 注销子系统失败,子系统信息:{}",logoutInfo.toString(),e);  
    147.               
    148.             }  finally {  
    149.   
    150.                 if(post!=null){  
    151.                       
    152.                     post.releaseConnection();                 
    153.                 }  
    154.             }  
    155.         }  
    156.     }  
    157.     @Override  
    158.     public void saveLoginUserInfo(String homeCookieId,User userInfo){  
    159.           
    160.         try {  
    161.               
    162.             ActivationInfo info=memcachedClient.get(LOGOUT_PREFIX+homeCookieId);  
    163.               
    164.             if(info==null){  
    165.                   
    166.                 info=new ActivationInfo();  
    167.             }  
    168.               
    169.             info.setUserInfo(userInfo);  
    170.               
    171.             memcachedClient.set(LOGOUT_PREFIX+homeCookieId, Constant.MAX_USERINFO_INACTIVE_INTERVAL, info);  
    172.               
    173.         } catch (Exception e) {  
    174.               
    175.             throw new SSOException("#############  保存用户登陆信息失败 ",e);  
    176.         }  
    177.           
    178.           
    179.     }  
    180.     @Override  
    181.     public User getLoginUserInfo(String homeCookieId){  
    182.           
    183.         ActivationInfo info = null;  
    184.           
    185.         try {  
    186.             info=memcachedClient.get(LOGOUT_PREFIX+homeCookieId);  
    187.               
    188.             if(info!=null){  
    189.                   
    190.                 return info.getUserInfo();            
    191.             }  
    192.               
    193.             throw new RuntimeException("找不到该cookie:["+homeCookieId+"]的用户信息");  
    194.               
    195.         } catch (Exception e) {  
    196.               
    197.             throw new SSOException("############# 获取登陆用户信息失败 ####",e);  
    198.         }   
    199.           
    200.     }  
    201.   
    202.     @Override  
    203.     public boolean updateUserInfoTimeout(String homeCookieId) {  
    204.           
    205.         if(StringUtils.isBlank(homeCookieId)){  
    206.               
    207.             throw new IllegalArgumentException("homeCookieId 不可以为空!");  
    208.         }  
    209.           
    210.         try {  
    211.               
    212.             return memcachedClient.touch(LOGOUT_PREFIX+homeCookieId, Constant.MAX_USERINFO_INACTIVE_INTERVAL);  
    213.           
    214.         } catch (Exception e) {  
    215.               
    216.             LOGGER.error("############ 定时更新主站登陆用户信息失败 ",e);  
    217.         }   
    218.         return false;  
    219.   
    220.     }  
    221.       
    222. }  



    2.客户端代码

    (3)过滤器代码

    [java] view plain copy
     
    1. package com.ffcs.sso.filter;  
    2.   
    3. import java.io.IOException;  
    4. import java.net.URLEncoder;  
    5. import java.util.Iterator;  
    6. import java.util.Map;  
    7. import java.util.Map.Entry;  
    8.   
    9. import javax.servlet.Filter;  
    10. import javax.servlet.FilterChain;  
    11. import javax.servlet.FilterConfig;  
    12. import javax.servlet.ServletException;  
    13. import javax.servlet.ServletRequest;  
    14. import javax.servlet.ServletResponse;  
    15. import javax.servlet.http.HttpServletRequest;  
    16. import javax.servlet.http.HttpServletResponse;  
    17. import javax.servlet.http.HttpSession;  
    18.   
    19. import org.apache.commons.lang.StringUtils;  
    20. import org.apache.http.client.methods.HttpGet;  
    21. import org.apache.http.client.methods.HttpPut;  
    22. import org.slf4j.Logger;  
    23. import org.slf4j.LoggerFactory;  
    24.   
    25. import com.ffcs.sso.exception.HttpRequestException;  
    26. import com.ffcs.sso.pojo.TicketResponseInfo;  
    27. import com.ffcs.sso.utils.Constant;  
    28. import com.ffcs.sso.utils.HttpClientUtils;  
    29. import com.ffcs.sso.utils.JsonUtil;  
    30.   
    31. public class SSOFilter implements Filter {  
    32.       
    33.     private final static Logger LOGGER=LoggerFactory.getLogger(SSOFilter.class);  
    34.   
    35.     private String ticketValidateURL;  
    36.       
    37.     private String redirectLoginURL;  
    38.       
    39.     private String updateUserInfoTimeOutURL;  
    40.   
    41.     @Override  
    42.     public void destroy() {  
    43.           
    44.     }  
    45.   
    46.     @Override  
    47.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
    48.           
    49.         HttpServletRequest request = (HttpServletRequest) req;  
    50.           
    51.         HttpServletResponse response = (HttpServletResponse) res;  
    52.           
    53.         HttpSession session=request.getSession();  
    54.           
    55.         if(session.getAttribute(Constant.SSO_IS_LOGIN)==null){  
    56.           
    57.             String targetUrl = request.getRequestURL().toString();  
    58.   
    59.             String ticket = request.getParameter(Constant.SSO_TICKET);        
    60.               
    61.             //子站单点退出路径  
    62.               
    63.             String subLogoutPath = request.getScheme()+"://"+request.getServerName()+":"  
    64.                       
    65.                         +request.getServerPort()+ request.getContextPath() +"/"+Constant.SSO_LOGOUT_SUFFIX;  
    66.                    
    67.             TicketResponseInfo responseInfo=new TicketResponseInfo(false);  
    68.               
    69.             if(StringUtils.isNotBlank(ticket)){  
    70.                   
    71.                 //校验票如果校验通过同时保存子站的登出信息(减少提交次数,原本验证成功后在提交登出信息),并返回主站的cookieId和主站登陆的账号  
    72.                   
    73.                 responseInfo=validateTicketInfo(ticket,targetUrl,Constant.SSO_SUB_COOKIE_NAME,session.getId(),subLogoutPath);  
    74.             }  
    75.   
    76.             if(!responseInfo.isSuccess()){  
    77.                   
    78.                 String queryParams =this.getQureyParams(request);  
    79.   
    80.                 String params=StringUtils.isNotBlank(queryParams)?"&queryParams="+URLEncoder.encode(queryParams,"UTF-8"):"";  
    81.                   
    82.                 //重定向到主站判断系统是否登陆过  
    83.                   
    84.                 response.sendRedirect(redirectLoginURL + "?targetUrl=" + targetUrl + params);  
    85.                       
    86.                 LOGGER.debug("############## 重定向到主系统:" + redirectLoginURL + "?targetUrl=" + targetUrl + params);                      
    87.                   
    88.                 return;  
    89.             }  
    90.               
    91.             session.setAttribute(Constant.SSO_IS_LOGIN, true);  
    92.               
    93.             session.setAttribute(Constant.SSO_ACCOUNT, responseInfo.getAccount());  
    94.               
    95.             session.setAttribute(Constant.SSO_HOME_COOKIEID, responseInfo.getHomeCookieId());     
    96.         }  
    97.   
    98.         Long updateInterval = (System.currentTimeMillis() - session.getLastAccessedTime()) / 1000;  
    99.           
    100.         if( updateInterval > Constant.SSO_HOME_USERINFO_UPDATE_TIMEOUT){  
    101.               
    102.             //更新主站用户信息超时时间  
    103.               
    104.             updateUserInfoTimeOut((String)session.getAttribute(Constant.SSO_HOME_COOKIEID));  
    105.                   
    106.             LOGGER.debug("############## 更新主站用户信息超时时间,间隔{}秒   ########",Constant.SSO_HOME_USERINFO_UPDATE_TIMEOUT);                   
    107.       
    108.         }  
    109.           
    110.         chain.doFilter(request, response);  
    111.                   
    112.         return;  
    113.     }  
    114.   
    115.     private String getQureyParams(HttpServletRequest request) {  
    116.           
    117.         StringBuilder queryParams=new StringBuilder();  
    118.           
    119.         Map<String,String[]> map=request.getParameterMap();  
    120.           
    121.         Iterator<Entry<String, String[]>>  params=map.entrySet().iterator();  
    122.           
    123.         boolean tag=false;  
    124.           
    125.         while (params.hasNext()) {  
    126.               
    127.             Map.Entry<String,String[]> entry = params.next();  
    128.               
    129.             if(!entry.getKey().equals(Constant.SSO_TICKET)){  
    130.                   
    131.                 String[] values=entry.getValue();  
    132.                   
    133.                 for(String value:values){  
    134.   
    135.                     if(tag){  
    136.                           
    137.                         queryParams.append("&");  
    138.                     }  
    139.                     queryParams.append(entry.getKey()).append("=").append(value);                         
    140.                 }  
    141.                 tag=true;  
    142.             }  
    143.         }  
    144.         return queryParams.toString();  
    145.     }  
    146.       
    147.     private void updateUserInfoTimeOut(String homeCookieId){  
    148.       
    149.         HttpPut put=new HttpPut(updateUserInfoTimeOutURL);  
    150.           
    151.         //添加cookie主站那边能够找到session  
    152.           
    153.         put.setHeader("Cookie",Constant.SSO_HOME_COOKIE_NAME+"="+homeCookieId);  
    154.           
    155.         put.setHeader("accept", "text/plain; charset=UTF-8");  
    156.           
    157.         try {  
    158.               
    159.             HttpClientUtils.getResponse(put);  
    160.               
    161.         } catch (HttpRequestException e) {  
    162.               
    163.             LOGGER.error("###################### 定时更新主站用户信息失败 ",e);  
    164.         }  
    165.     }  
    166.   
    167.     /** 
    168.      * 根据ticket验证是否正确,验证通过返回主站的cookieId 
    169.      *  
    170.      * @param ticket 
    171.      *  
    172.      * @param target 
    173.      *  
    174.      * @return  返回验证空失败  成功cookieId 
    175.      */  
    176.     private TicketResponseInfo validateTicketInfo(String ticket, String target,String subCookieName,  
    177.               
    178.             String subCookieId, String subLogoutPath) {  
    179.           
    180.         HttpGet httpget = new HttpGet(ticketValidateURL + "/"+ ticket + "?target=" + target  
    181.                   
    182.                 +"&subCookieId="+subCookieId+"&subCookieName="+subCookieName+"&subLogoutPath="+subLogoutPath);  
    183.           
    184.         httpget.setHeader("accept", "application/json; charset=UTF-8");  
    185.           
    186.         String result;  
    187.           
    188.         try {  
    189.               
    190.             result = HttpClientUtils.getResponse(httpget);  
    191.               
    192.             return JsonUtil.fromJson(result, TicketResponseInfo.class);  
    193.               
    194.         } catch (HttpRequestException e) {  
    195.               
    196.             throw new RuntimeException("############### 子站验证ticket失败  ",e);  
    197.         }     
    198.           
    199.           
    200.     }  
    201.   
    202.     @Override  
    203.     public void init(FilterConfig filterConfig) {  
    204.           
    205.         if (filterConfig != null) {  
    206.               
    207.             LOGGER.info("#######   SSOFilter:Initializing filter");  
    208.         }  
    209.           
    210.         this.ticketValidateURL = filterConfig.getInitParameter("ticketValidateURL");  
    211.           
    212.         this.redirectLoginURL=filterConfig.getInitParameter("redirectLoginURL");  
    213.   
    214.         this.updateUserInfoTimeOutURL=filterConfig.getInitParameter("updateUserInfoTimeOutURL");  
    215.     }  
    216.       
    217. }  


    (2)登出过滤器代码(比较简单,服务端通过httpclient回调这个路口进行退出,服务端必须把客户端登陆的cookie返回过来,不然找不到session)

    [java] view plain copy
     
    1. package com.ffcs.sso.filter;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.Filter;  
    6. import javax.servlet.FilterChain;  
    7. import javax.servlet.FilterConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.ServletRequest;  
    10. import javax.servlet.ServletResponse;  
    11. import javax.servlet.http.HttpServletRequest;  
    12.   
    13. public class LogoutFilter implements Filter{  
    14.       
    15.     @Override  
    16.     public void destroy() {  
    17.           
    18.           
    19.     }  
    20.   
    21.     @Override  
    22.     public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {  
    23.           
    24.         HttpServletRequest request = (HttpServletRequest) req;  
    25.           
    26.         request.getSession().invalidate();  
    27.           
    28.         return;  
    29.           
    30.     }  
    31.   
    32.     @Override  
    33.     public void init(FilterConfig filterConfig) {  
    34.   
    35.     }  
    36.       
    37. }  


    (3)客户端web.xml配置

    [java] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    3.     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"  
    4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
    5.     version="3.0">  
    6.     <filter>  
    7.         <filter-name>DisableUrlSessionFilter</filter-name>  
    8.         <filter-class>com.ffcs.sso.filter.DisableUrlSessionFilter</filter-class>  
    9.     </filter>  
    10.     <filter-mapping>  
    11.         <filter-name>DisableUrlSessionFilter</filter-name>  
    12.         <url-pattern>/*</url-pattern>  
    13.     </filter-mapping>  
    14.   
    15.     <filter>  
    16.         <filter-name>sessionFilter</filter-name>  
    17.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
    18.     </filter>  
    19.     <filter-mapping>  
    20.         <filter-name>sessionFilter</filter-name>  
    21.         <url-pattern>/*</url-pattern>  
    22.     </filter-mapping>  
    23.   
    24.     <filter>  
    25.         <filter-name>LogoutFilter</filter-name>  
    26.         <filter-class>com.ffcs.sso.filter.LogoutFilter</filter-class>  
    27.     </filter>  
    28.     <filter-mapping>  
    29.         <filter-name>LogoutFilter</filter-name>  
    30.         <url-pattern>/SSO_LOGOUT</url-pattern>  
    31.     </filter-mapping>  
    32.     <listener>  
    33.         <description>spring监听器</description>  
    34.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    35.     </listener>  
    36.     <listener>  
    37.         <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    38.     </listener>  
    39.     <context-param>  
    40.         <param-name>contextConfigLocation</param-name>  
    41.         <param-value>classpath:spring.xml</param-value>  
    42.     </context-param>  
    43.   
    44.     <filter>  
    45.         <description>字符集过滤器</description>  
    46.         <filter-name>encodingFilter</filter-name>  
    47.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
    48.         <init-param>  
    49.             <description>字符集编码</description>  
    50.             <param-name>encoding</param-name>  
    51.             <param-value>UTF-8</param-value>  
    52.         </init-param>  
    53.     </filter>  
    54.     <filter-mapping>  
    55.         <filter-name>encodingFilter</filter-name>  
    56.         <url-pattern>/*</url-pattern>  
    57.     </filter-mapping>  
    58.   
    59.     <filter>  
    60.         <filter-name>SSOFilter</filter-name>  
    61.         <filter-class>com.ffcs.sso.filter.SSOFilter</filter-class>  
    62.         <init-param>  
    63.             <!-- 获取票保存的信息 ,并发送单点登陆子站信息  GET方式 -->  
    64.             <param-name>ticketValidateURL</param-name>   
    65.             <param-value>http://127.0.0.1:8080/SSO/webservice/ticket</param-value>  
    66.         </init-param>  
    67.         <init-param>  
    68.             <!-- 定时更新主站用户超时信息,防止子站用户没过期,主站登陆信息已经过期  PUT方式 -->  
    69.             <param-name>updateUserInfoTimeOutURL</param-name>  
    70.             <param-value>http://127.0.0.1:8080/SSO/webservice/userinfo/timeout</param-value>  
    71.         </init-param>  
    72.         <init-param>  
    73.             <!-- 重定向获取 -->  
    74.             <param-name>redirectLoginURL</param-name>  
    75.             <param-value>http://127.0.0.1:8080/SSO/redirect</param-value>  
    76.         </init-param>  
    77.     </filter>  
    78.     <filter-mapping>  
    79.         <filter-name>SSOFilter</filter-name>  
    80.         <url-pattern>/*</url-pattern>  
    81.     </filter-mapping>  
    82.     <servlet>  
    83.         <servlet-name>springMvc</servlet-name>  
    84.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    85.         <init-param>  
    86.             <param-name>contextConfigLocation</param-name>  
    87.             <param-value>classpath:spring-mvc.xml</param-value>  
    88.         </init-param>  
    89.         <!-- <load-on-startup>1</load-on-startup> -->  
    90.     </servlet>  
    91.     <servlet-mapping>  
    92.         <servlet-name>springMvc</servlet-name>  
    93.         <url-pattern>/</url-pattern>  
    94.     </servlet-mapping>  
    95.   
    96.     <!-- 浏览器不支持put,delete等method,由该filter将/blog?_method=delete转换为标准的http delete方法 -->  
    97.     <filter>  
    98.         <filter-name>HiddenHttpMethodFilter</filter-name>  
    99.         <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
    100.     </filter>  
    101.   
    102.     <filter-mapping>  
    103.         <filter-name>HiddenHttpMethodFilter</filter-name>  
    104.         <servlet-name>springMvc</servlet-name>  
    105.     </filter-mapping>  
    106.     <error-page>  
    107.         <error-code>404</error-code>  
    108.         <location>/error/404.jsp</location>  
    109.     </error-page>  
    110.     <error-page>  
    111.         <error-code>500</error-code>  
    112.         <location>/error/500.jsp</location>  
    113.     </error-page>  
    114. </web-app>  

     

    ok基本差不多核心代码就这么多了,写的不好别拍砖,不好的大家请指点哈,有空在把session集群这块在发布上来这样加上nginx就能够进行集群了大笑大笑

     

    肿么挂附件哟。。。。。。。。

  • 相关阅读:
    搭建自己的技术博客系列(三)让你的博客拥有评论功能!
    搭建自己的技术博客系列(二)把 Hexo 博客部署到 GitHub 上
    Excel2003 去除重复项
    Delphi 7拦截滚轮事件不响应滚轮的上下滚动
    APSC4xSeries_Ver32.exe在win764位提示缺少DLL错误解决办法
    Win7装在其他盘 (非C盘)办法
    Delphi7 安装ICS,与简单使用
    Python学习笔记
    使用IP spoofer 功能
    python在windows里怎么配置apache呢,
  • 原文地址:https://www.cnblogs.com/tdalcn/p/8343192.html
Copyright © 2011-2022 走看看