[竹迩专栏] 单点登录

[复制链接]   查看: 228|回复: 0
慢节奏 发表于 2017-8-23 19:02:10 | 显示全部楼层 |阅读模式
基础


单点登录:在多系统共存的环境下,用户在某处登录,不用在其他系统中登录,即用户一次登录获得其他系统的信任。


解决问题:


·存储信任


·验证信任


本文基于Redis+Cookie实现单点登录。


实现


SSO登录的主要逻辑.
  1. @Service
  2. public class UserServiceImpl implements UserService{
  3.         @Autowired
  4.         private JedisClient jedisClient;
  5.        
  6.         @Override
  7.         public String userLogin(HttpServletRequest request,HttpServletResponse response,
  8.                         String username,String password){
  9.                
  10.                 //根据用户名查询数据库.
  11.                 //这里模拟判断密码是否为123.
  12.                 if(!("123".equals(password)))
  13.                         return "Error";
  14.                
  15.                 //假设User对象从数据库中查询获得.
  16.                 //这里进行模拟.
  17.                 User user=new User();
  18.                 user.setUserid("1");
  19.                 user.setUsername(username);
  20.                 user.setPassword(password);
  21.                
  22.                 //用户名密码正确.
  23.                 //1.生成令牌Token(随机数).
  24.                 String Token=UUID.randomUUID().toString();
  25.                
  26.                 //2.保存用户信息到redis之前.密码先清空.
  27.                 user.setPassword(null);
  28.                
  29.                 //3.将用户信息写入redis中.
  30.                 //Key---Token.Value---User(转换为Json)
  31.                 jedisClient.set(Token,JsonUtils.objectToJson(user));
  32.                
  33.                 //4.设置过期时间.
  34.                 jedisClient.expire(Token,1800);
  35.                
  36.                 //5.将令牌Token写入到Cookie中.
  37.                 CookieUtils.setCookie(request,response,"T_Token",Token);
  38.                
  39.                 return "Success";
  40.         }
  41. }
复制代码


其他模块中的拦截器.
  1. public class LoginInterception implements HandlerInterceptor{
  2.         //Handler执行之前处理.
  3.         @Override
  4.         public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler)
  5.                         throws Exception{
  6.                
  7.                 //1.从Cookie中获取Token.
  8.                 String Token=CookieUtils.getCookieValue(request,"T_Token");
  9.                
  10.                 //2.根据Token从redis中查询User信息.
  11.                 //当前拦截器在其他模块中.调用SSO模块使用HttpClient.
  12.                 User user=userService.getUserByToken(Token);
  13.                
  14.                 //3.判断查询的结果是否为空.
  15.                 if(null==user){
  16.                         //跳转到登录页面.
  17.                         response.sendRedirect("");
  18.                         return false;
  19.                 }
  20.                
  21.                 //已经登录.
  22.                 return true;
  23.         }
  24.         //Handler执行之后.返回ModelAndView之前.
  25.         @Override
  26.         public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,
  27.                         ModelAndView modelAndView)throws Exception{
  28.         }
  29.         //返回ModelAndView之后.
  30.         @Override
  31.         public void afterCompletion(HttpServletRequest request,HttpServletResponse response,
  32.                         Object handler,Exception ex)
  33.                         throws Exception{
  34.         }
  35. }
复制代码


其他模块中getTokenByUser()方法
  1. //拦截器调用该方法使用HttpClient调用SSO模块方法.
  2. @Override
  3. public String getUserByToken(String Token){
  4.        
  5.         try{
  6.                
  7.                 //接收SSO模块返回的查询信息.
  8.                 String Json=HttpClientUtil.doGet(SSO_URL+Token);
  9.                
  10.                 //将Json转换为对象后返回.
  11.                 User user=JsonUtils.jsonToPojo(Json,User.class);
  12.                 return user;
  13.                                
  14.         }catch (Exception e){
  15.         }
  16.         return null;
  17. }
复制代码


SSO模块中接收Token查询Redis
  1. //拦截器调用该方法使用HttpClient调用SSO模块方法.
  2. @Override
  3. public String getUserByToken(String Token){
  4.        
  5.         //根据Token从Redis中查询信息.
  6.         String json=jedisClient.get(Token);
  7.        
  8.         //判断是否为空.
  9.         if(StringUtils.isBlank(json))
  10.                 return null;
  11.        
  12.         //增加过期时间.
  13.         jedisClient.expire(Token,1800);
  14.         return json;
  15. }
复制代码


人生得意须尽欢,就让傻逼去心酸。
*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright;  ©2015-2017  知了堂学习社区  Powered by  知了堂Edu!     ( 蜀ICP备16011312号-1 )