一、使用Cookie解决单点登陆
技术点:html
一、设置Cookie的路径为setPath("/").即Tomcat的目录下都有效java
二、设置Cookie的域setDomain(".itcast.com");即bbs.itcast.com,或是mail.itcast.com有效。即跨域。web
三、设置Cookie的时间。即便用户不选择在几天内自动登陆,也应该保存Cookie以保存在当前浏览器没有关闭的状况下有效。跨域
四、使用Filter自动登陆。浏览器
实现步骤tomcat
1:首先要准备出几个虚拟主机并配置hosts文件,即本机DNS修改本机的C:\Windows\System32\drivers\etc下的hosts文件。安全
- <span style="font-size:18px;"><span style="font-size:18px;"># localhost name resolution is handled within DNS itself.
- # 127.0.0.1 localhost
- # ::1 localhost
-
- 127.0.0.1 localhost
- 127.0.0.1 www.bbs.itcast.cn
- 127.0.0.1 www.news.itcast.cn
- 127.0.0.1 www.news.com
- 127.0.0.1 www.bbs.com
- 127.0.0.1 www.server.com
- </span></span>
增长几个Host节点,经过Cookie实现自动登陆,必须配置的虚拟主页知足xxx.itcast.cn,即主域名必须保持一致。服务器
通常web应用中通常部署在web.xml文件中,单点退出相关配置以下:
cookie
说明:咱们看到单点退出的相关类结构,web.xml配置了单点退出的相关类(1个监听器SingleSignOutHttpSessionListener,2个过滤器SingleSignOutFilter,SimpleServerLogoutHandler)。session
实现利用了session存储机制,SessionStoreManager是个单例类,用于管理session的存储、删除;SessionMappingStorage是session的存储、删除的执行者,能够看到实际存储的结构是一个artifactId、sessionId为名值对的HashMap表;监听器SingleSignOutHttpSessionListener的做用是session销毁时,调用session管理单例类SessionStoreManager进行session的删除销毁;
SingleSignOutFilter的做用有2个:一个是在单点访问拦截安全资源时调用单例类SessionStoreManager存储session,另外一个是在单点退出时调用单例类SessionStoreManager删除session;SimpleServerLogoutHandler的做用是将客户端的退出请求转发到SSO服务器端,集中处理作各个子系统的单点退出。
二、先在bbs(或是mail)虚拟目录下,开发一个能够自动登陆的程序,使用Filter:
- <span style="font-size:18px;"><span style="font-size:18px;">一、登陆的主页以下:
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- </head>
- <body>
- <p>在同一台服务器上,多个站点自动登陆....>>:<%=session.getId()%></p>
- <c:if test="${empty sessionScope.user}">
- <form name="f" method="post" action="<c:url value='/login'/>">
- Name:<input type="text" name="name"/><br/>
- Pwd:<input type="text" name="pwd"/><br/>
- <input type="checkbox" name="chk" value="7">一周内自动登陆<br/>
- <input type="submit" value="登陆"/>
- </form>
- </c:if>
- <c:if test="${not empty sessionScope.user}">
- 欢迎你:${user}。<a href="<c:url value='/loginout'/>">安全退出</a>
- </c:if>
- <br/>
- 相关站点:(只要在一边登陆成功,便可以自动登陆到另外一个程序)<br/>
- <a href="http://mail.itcast.com:7777">mail.itcast.com</a><br/>
- <a href="http://bbs.itcast.com:7777">bbs.itcast.com</a><br/>
- </body>
- </html>
- </span></span>
二、登陆的Servlet程序以下:
- <span style="font-size:18px;"><span style="font-size:18px;">/**
- * 用户登陆
- */
- public class LoginServlet extends HttpServlet{
- public void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- doPost(req, resp);
- }
- public void doPost(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- String nm = req.getParameter("name");
- String pwd = req.getParameter("pwd");
- String chk = req.getParameter("chk"); //是否选中了7天自动登陆
- String forward = "/index.jsp";
- if(nm!=null && !nm.trim().equals("") && nm.startsWith("it")//用户名是it开始,且密码是pwd开始的能够登陆
- && pwd !=null && !pwd.trim().equals("") &&
- pwd.startsWith("pwd")){
- System.err.println("登陆成功。。。。。");
- forward = "/jsps/welcome.jsp";
- //不管如何,都要设置cookie,若是没有选择自动登陆,则只在当前页面的跳转时有效,不然设置有效期间为7天。
- Cookie cookie = new Cookie("autologin",nm+"@"+pwd);
- cookie.setPath("/"); //若是路径为/则为整个tomcat目录有用
- cookie.setDomain(".itcast.com"); //设置对全部*.itcast.com为后缀的域名效
- if(chk!=null){
- int time = 1*60*60*24*7; //1秒*60=1分*60分=1小时*24=1天*7=7天
- cookie.setMaxAge(time);
- }
- resp.addCookie(cookie);
- req.getSession().setAttribute("user", nm);
- }else{
- System.err.println("登陆不成功。。。。。。");
- }
- req.getRequestDispatcher(forward).forward(req, resp);
- }
- }
-
- </span></span>
三、自动登陆的Filter程序以下:
- <span style="font-size:18px;"><span style="font-size:18px;">/**
- * 自动登陆
- */
- public class AutoLogin implements Filter {
- public void destroy() {}
- public void doFilter(ServletRequest req, ServletResponse resp,
- FilterChain chain) throws IOException, ServletException {
- System.err.println("开始自动登陆验证.....");//此类中应该对登陆的servlet直接放行。根据判断url决定。
- HttpServletRequest requ = (HttpServletRequest) req;
- HttpSession s = requ.getSession();
- if (s.getAttribute("user") != null) {//若是用户已经登陆则直接放行
- System.err.println("用户已经登陆,没有必需要再作自动登陆。。。。");
- } else {
- Cookie[] cookies = requ.getCookies();
- if (cookies != null) {
- for (Cookie ck : cookies) {
- if (ck.getName().equals("autologin")) {// 是不是自动登陆。。。。
- System.err.println("自动登陆成功。。。。。");
- String val = ck.getValue();
- String[] vals = val.split("@");
- s.setAttribute("user", vals[0]);
- }
- }
- }
- }
- chain.doFilter(req, resp);
- }
- public void init(FilterConfig filterConfig) throws ServletException {}
- }
- </span></span>
四、正常退出的Servlet以下
- <span style="font-size:18px;"><span style="font-size:18px;">/**
- * 安全退出删除Cookie
- */
- public class LoginOutServlet extends HttpServlet {
- public void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- HttpSession s = req.getSession(); //获取Session
- Cookie cookie = new Cookie("autologin","");//必须声明一个彻底相同名称的Cookie
- cookie.setPath("/");//路径也要彻底相同
- cookie.setDomain(".itcast.com");//域也要彻底相同
- cookie.setMaxAge(0);//设置时间为0,以直接删除Cookie
- resp.addCookie(cookie);
- s.removeAttribute("user");
- System.err.println("安全退出。。。。。");
- resp.sendRedirect(req.getContextPath()+"/index.jsp");
- }
- }
- </span></span>
这种是基于最简单的方式实现的单点登陆