单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
--------------------------------------------------
www.bbs.itcast.cn和www.mail.itcast.cn可以使用cookie+filter的形式实现单点登录。
一级域名相同,二级域名不同
www.bbs.itcast.cn
www.mail.itcast.cn
--------------------------------------------------
1、使用Cookie解决单点登录
技术点:
1、设置Cookie的路径为setPath("/") .即Tomcat的目录下都有效
2、设置Cookie的域setDomain(".itcast.com");即bbs.itcast.com,或是mail.itcast.com有效。即跨域。
3、设置Cookie的时间。即使用户不选择在几天内自动登录,也应该保存Cookie以保存在当前浏览器没有关闭的情况下有效。
4、使用Filter自动登录。
实现步骤:
1、首先要准备出几个虚拟主机并配置hosts文件,即本机DNS。
127.0.0.1 localhost 127.0.0.1 www.bbs.itcast.cn 127.0.0.1 www.mail.itcast.cn
配置虚拟主机,主要通过修改tomcat_home/conf/server.xml文件完成:
<Host name="www.bbs.itcast.cn" appBase="bbs" unpackWARs="true" autoDeploy="true"/> <Host name="www.mail.itcast.cn" appBase="mail" unpackWARs="true" autoDeploy="true"/>
增加几个Host节点,通过Cookie实现自动登录,必须配置的虚拟主页满足xxx.itcast.cn,即主域名必须保持一致。
2、先在bbs(或是mail)虚拟目录下,开发一个可以自动登录的程序,使用Filter:
1、登录的主页如下:
<%@ 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>在同一台服务器上,多个站点自动登录(只要在一边登录成功,即可以自动登录到另一个程序).... </p> <c:if test="${empty sessionScope.user}"> <form name="f" method="post" action="<c:url value='/login'/>"> userName:<input type="text" name="userName"/><br/> passWord:<input type="text" name="password"/><br/> <input type="checkbox" name="check" 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/> </body> </html>
2、登录的Servlet程序如下:
public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName = request.getParameter("userName"); String password = request.getParameter("password"); String check = request.getParameter("check"); //是否选中了7天自动登录 if(userName!=null && !userName.trim().equals("") && userName.startsWith("it")//用户名是it开始,且密码是pwd开始的可以登录 && password !=null && !password.trim().equals("") && password.startsWith("pwd")){ System.err.println("登录成功。。。。。"); request.getSession().setAttribute("user", userName); //无论如何,都要设置cookie,如果没有选择自动登录,则只在当前页面的跳转时有效,否则设置有效期间为7天。 Cookie cookie = new Cookie("sso",userName); cookie.setPath("/"); //如果路径为/则为整个tomcat目录有用 cookie.setDomain(".itcast.cn"); //设置对所有*.itcast.cn为后缀的域名效 if(check!=null){ int time = 1*60*60*24*7; //1秒*60=1分*60分=1小时*24=1天*7=7天 cookie.setMaxAge(time); } response.addCookie(cookie); }else{ System.err.println("登录不成功。。。。。。"); } response.sendRedirect(request.getContextPath() + "/index.jsp"); } }
3、自动登录的Filter程序如下:
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.err.println("开始自动登录验证.....");//此类中应该对登录的servlet直接放行。根据判断url决定。 HttpServletRequest request = (HttpServletRequest) req; HttpSession s = request.getSession(); if (s.getAttribute("user") != null) {//如果用户已经登录则直接放行 System.err.println("用户已经登录,没有必须要再做自动登录。。。。"); } else { Cookie[] cookies = request.getCookies(); if (cookies != null&&cookies.length>0) { for (Cookie ck : cookies) { if (ck.getName().equals("sso")) {// 是否是自动登录。。。。 System.err.println("自动登录成功。。。。。"); String userName = ck.getValue(); s.setAttribute("user", userName); } } } } chain.doFilter(req, response); }
<filter> <filter-name>autoLogin</filter-name> <filter-class>cn.itcast.sso.filter.AutoLoginFilter</filter-class> </filter> <filter-mapping> <filter-name>autoLogin</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
4、正常退出的Servlet如下
public class LoginOutServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession s = req.getSession(); //获取Session Cookie cookie = new Cookie("user","");//必须声明一个完全相同名称的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"); } }