1.修改host实现跨域的单点登录

由于需要演示跨域,需要先进行域名设置。不会的先看我的另一篇文章mac配置自定义域名;设置如下:

127.0.0.1 www.sso.com 127.0.0.1 www.crm.com 127.0.0.1 www.wms.com

2.服务端

2.1.检测客户端在服务端是否已经登录了。(checkLogin方法)

(1)获取session中的token。

(2)如果token不为空,说明服务端已经登录过了,此时重定向到客户端的地址,并把token带上。

(3)如果token为空,跳转到统一认证中心的的登录页面,并把redirectUrl放入到request域中。

2.2.统一认证中心的登录方法(login方法)

2.2.1判断用户提交的账号密码是否正确。

2.2.2如果正确

(1)创建token(可以使用UUID,保证唯一就可以)

(2)把token放入到session中。

(3)这个token要知道有哪些客户端登陆了,创建Map<String,List<String[]> clientMap;(为单点注销做准备)

SSOUtil.clientMap.put(token,new ArrayList());(把这些数据放入到数据库中也是可以的,我们就做比较简单的,模拟一下。)

(4)转发到redirectUrl地址,把token带上。

 2.2.3如果错误

转发到login.jsp,还需要把redirectUrl参数放入到request域中。

2.3.统一认证中心认证token方法(verify方法),返回值为String,贴@ResponseBody

2.3.1如果SSOUtil.clientMap.get(token)有数据clientList,说明token是有效的。

(1)clientList把客户端传入的客户端登出地址(clientLogOutUrl)和会话ID(jsessionid)保存到集合中。

(2)返回true字符串。

2.3.2如果SSOUtil.clientMap.get(token)为null,说明token是无效的,返回false字符串。

2.4代码实现如下

package com.wolfcode.ssoServer.controller;import com.wolfcode.ssoServer.util.MockDatabaseUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpSession;
import java.util.UUID;@Controller
public class SSOServerController {@RequestMapping("/checkLogin")public String checkLogin(String redirectUrl, HttpSession session, Model model){//1.判断是否有全局的会话String token = (String) session.getAttribute("token");if(StringUtils.isEmpty(token)){//表示没有全局会话//跳转到统一认证中心的登陆页面.model.addAttribute("redirectUrl",redirectUrl);return "login";}else{//有全局会话//取出令牌信息,重定向到redirectUrl,把令牌带上  http://www.wms.com:8089/main?tokenmodel.addAttribute("token",token);return "redirect:"+redirectUrl;}}@RequestMapping("/login")public String login(String username,String password,String redirectUrl,HttpSession session,Model model){if("zhangsan".equals(username)&&"666".equals(password)){//账号密码匹配//1.创建令牌信息String token = UUID.randomUUID().toString();//2.创建全局的会话,把令牌信息放入会话中.session.setAttribute("token",token);//3.需要把令牌信息放到数据库中.MockDatabaseUtil.T_TOKEN.add(token);//4.重定向到redirectUrl,把令牌信息带上.  http://www.crm.com:8088/main?token=model.addAttribute("token",token);return "redirect:"+redirectUrl;}//如果账号密码有误,重新回到登录页面,还需要把redirectUrl放入request域中.model.addAttribute("redirectUrl",redirectUrl);return "login";}/*** 校验token是否由统一认证中心产生的**/@RequestMapping("/verify")@ResponseBodypublic String verifyToken(String token,String clientUrl,String jsessionid){if(MockDatabaseUtil.T_TOKEN.contains(token)){//说明令牌有效,返回truereturn "true";}return "false";}
}

3.客户端

拦截客户端的请求判断是否有局部的session

3.1如果有局部的session,放行请求。

3.2如果没有局部session

3.2.1请求中有携带token参数

3.2.1.1如果有,使用HttpURLConnection发送请求校验token是否有效。

(1)如果token有效,建立局部的session。

(2)如果token无效,重定向到统一认证中心页面进行登陆。

3.2.1.2如果没有,重定向到统一认证中心页面进行登陆。

3.2.2请求中没有携带token参数,重定向到统一认证中心页面进行登陆。

3.3代码实现

package com.wolf.ssoCrmclient.filter;import com.wolf.ssoCrmclient.util.HttpUtil;
import com.wolf.ssoCrmclient.util.SSOClientUtil;
import org.apache.commons.lang3.StringUtils;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;@WebFilter(filterName = "SSOClientFilter", urlPatterns = { "/*" })
public class SSOClientFilter implements Filter {public void destroy() {}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException,IOException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;HttpSession session = req.getSession();//1.判断是否有局部的会话Boolean isLogin = (Boolean) session.getAttribute("isLogin");if (isLogin != null && isLogin) {//有局部会话,直接放行.chain.doFilter(request, response);return;}//判断地址栏中是否有携带token参数.String token = req.getParameter("token");if (token!=null&&!("".equals(token))) {//token信息不为null,说明地址中包含了token,拥有令牌.//判断token信息是否由认证中心产生的.String httpURL = SSOClientUtil.SERVER_URL_PREFIX + "/verify";Map<String, String> params = new HashMap<String, String>();params.put("token", token);try {String isVerify = HttpUtil.sendHttpRequest(httpURL, params);if ("true".equals(isVerify)) {//如果返回的字符串是true,说明这个token是由统一认证中心产生的.//创建局部的会话.session.setAttribute("isLogin", true);//放行该次的请求chain.doFilter(request, response);return;}} catch (Exception e) {e.printStackTrace();}}//没有局部会话,重定向到统一认证中心,检查是否有其他的系统已经登录过.// http://www.sso.com:8443/checkLogin?redirectUrl=http://www.crm.com:8088SSOClientUtil.redirectToSSOURL(req, resp);}public void init(FilterConfig config) throws ServletException {}}

4.单点注销步骤

4.1客户端

在登陆的按钮链接写上统一认证中心的登出方法即可。

实现如下:

package com.wolf.ssoCrmclient.controller;import com.wolf.ssoCrmclient.util.SSOClientUtil;
import org.springframework.util.StreamUtils;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;@WebServlet(name = "LogOutServlet",urlPatterns = "/logOut")
public class LogOutServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getSession().invalidate();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}

登录后的页面添加退出按钮:

<a href="${serverLogOutUrl}" >退出</a>

过滤器添加如下:

params.put("clientUrl", SSOClientUtil.getClientLogOutUrl());
params.put("jsessionid", session.getId());

4.2服务端

1.编写logOut方法,调用session.invalidate()

2.创建session的监听器,在session的监听器的销毁方法写如下逻辑

2.1获取session中的token。

2.2根据token在SSOUtil.clientMap获取所有客户端的登出地址和会话id。

2.3通过HttpUtil选项调用客户端的登出方法。

3.将session监听器注册到web.xml中。

实现如下:

1.编写logOut方法

    @RequestMapping("/logOut")public String logOut(HttpSession session){//销毁全局会话session.invalidate();return "logOut";}

2.创建session的监听器

package com.wolfcode.ssoServer.listener;import com.wolfcode.ssoServer.util.HttpUtil;
import com.wolfcode.ssoServer.util.MockDatabaseUtil;
import com.wolfcode.ssoServer.vo.ClientInfoVo;import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.List;public class MySessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {}@Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {HttpSession session = httpSessionEvent.getSession();String token = (String) session.getAttribute("token");//删除t_token表中的数据MockDatabaseUtil.T_TOKEN.remove(token);List<ClientInfoVo> clientInfoVoList = MockDatabaseUtil.T_CLIENT_INFO.remove(token);try{for(ClientInfoVo vo:clientInfoVoList){//获取出注册的子系统,依次调用子系统的登出的方法HttpUtil.sendHttpRequest(vo.getClientUrl(),vo.getJsessionid());}}catch(Exception e){e.printStackTrace();;}}
}

3.将session监听器注册到web.xml中

  <listener><listener-class>com.wolfcode.ssoServer.listener.MySessionListener</listener-class></listener>

代码地址如下:https://download.csdn.net/download/u013938578/12212616

单点登录(4):单点登录实现(附源码)相关推荐

  1. C# winform 实现微信二维码登录、第三方登录(已实现、附源码)

    前言 应上级要求,在项目登录的时候实现第三方登录.很荣幸我接到了这个任务,但是我之前完全都没接触到.开发周期是三天,对于我们这种小白完全是从零开始.最后成功的实现这个功能固然重要,但是这个探索的过程才 ...

  2. Spring Boot 实现扫码登录,太赞了(附源码)!!

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐ 点击领取全栈资料:全栈资料 一.首先咱们需要一张表 二.角色都有哪些 三.接口都需要哪些? 四.步骤 五.疯狂贴代码 springBoot中 ...

  3. 【C#+SQL Server】实现模仿QQ的交友软件 四:主窗体设计讲解(附源码和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 其他几个部分文章链接如下 [C#+SQL Server]实现模仿QQ的交友软件 一:系统简介.功能展示与数据库设计(附源码和资源) [C#+SQL ...

  4. 【C#+SQL Server】实现模仿QQ的交友软件 三:申请账号窗体设计讲解(附源码和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 其他几个部分文章链接如下 [C#+SQL Server]实现模仿QQ的交友软件 一:系统简介.功能展示与数据库设计(附源码和资源) [C#+SQL ...

  5. 【C#+SQL Server】实现模仿QQ的交友软件 五:聊天窗体设计讲解(附源码和资源)

    需要源码和资源请 点赞关注收藏后评论区留言私信~~~ 其他几个部分文章链接如下 [C#+SQL Server]实现模仿QQ的交友软件 一:系统简介.功能展示与数据库设计(附源码和资源) [C#+SQL ...

  6. 【C#+SQL Server】实现模仿QQ的交友软件 一:系统简介、功能展示与数据库设计(附源码和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 其余几个部分文章链接如下 [C#+SQL Server]实现模仿QQ的交友软件 二:登录窗体设计讲解(附源码和资源) [C#+SQL Server] ...

  7. 通用权限管理系统组件 中集成多个子系统的单点登录(网站入口方式)附源码

    通用权限管理系统组件 (GPM - General Permissions Manager) 中集成多个子系统的单点登录(网站入口方式)附源码 上文中实现了直接连接数据库的方式,通过配置文件,自定义的 ...

  8. 黯然微信小程序杂记(二):小程序最新版登录并进行缓存模块的实现 附源码

    黯然微信小程序杂记(二):小程序最新版登录进行缓存模块的实现 附源码 一.功能描述 二.mine.wxml界面图片 三.mine.wxml代码 四.mine.wxss代码 五.mine.js代码 六. ...

  9. php jquery ajax登录,jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)

    弹出层主要用于展示丰富的页面信息,还有一个更好的应用是弹出表单层丰富交互应用.常见的应用有弹出登录表单层,用户提交登录信息,后台验证登录成功后,弹出层消失,主页面局部刷新用户信息.本文我们将给大家介绍 ...

  10. 小程序云开发实现登录与注册(附源码)

    小程序云开发实现登录与注册(附源码) 1. 看效果 2.wxss <view class="v1"><!-- v2父容器 子view使用绝对布局 -->&l ...

最新文章

  1. mysql持久连接_持久性连接,短连接和连接池
  2. VTK:相互作用之KeypressObserver
  3. for循环批量写文件 shell_shell之for循环的3个简单脚本
  4. 视频直播 > 最佳实践 > 如何降低延时
  5. bioconductor 安装包_R语言 | 你知道自己的Bioconductor版本么?
  6. WebSocket(1)---WebSocket介绍
  7. Python二维数组,坑苦了
  8. python子类调用父类构造函数_Java 子类调用父类的构造函数
  9. 用C/C++编程技术教你制作彩票随机程序
  10. 区块链产品经理规范与总结
  11. Python 面试宝典
  12. 基于S3C2440数码相框
  13. matplotlib 绘制直方图
  14. php抓取微信文章图片保存到本地
  15. 如何批量调整图片尺寸?
  16. RGB TFT-LCD彩条显示实验
  17. MOXA NPort5630串口设备联网服务器
  18. 115网盘里的资源转存百度网盘
  19. u盘锁定计算机,u盘锁电脑的方法介绍【图解】
  20. 天野商业脚本开发第三期培训

热门文章

  1. ABI and ISA
  2. navigation Bar、toolBar、tabbar 区别
  3. 监听JScrollPane按PageUp,PageDown事件
  4. coco数据集大小分类_VOC、COCO数据集类别
  5. 把Excel批注的“红三角”放在单元格左上角_Excel的批注功能,全部知道的不足10%,你会用的仅仅是冰山一角...
  6. 深入理解数据库当中的聚合函数
  7. BIOS没有开启虚拟化问题disabled by bios
  8. [Kafka] Kafka基本架构
  9. 女神节 | 那些奋斗在IT领域的“女神”们
  10. vxWorks系统ps2键盘,tty设备,vga设备的联系