技術點:
1、設置Cookie的路徑為setPath(/).即Tomcat的目錄下都有效
2、設置Cookie的域setDomain(.itcast.com);即bbs.itcast.com,或是mail.itcast.com有效。即跨域。
3、設置Cookie的時間。即使用戶不選擇在幾天內自動登錄,也應該保存Cookie以保存在當前浏覽器沒有關閉的情況下有效。
4、使用Filter自動登錄。
實現步驟
1:首先要准備出幾個虛擬主機並配置hosts文件,即本機DNS修改本機的C:WindowsSystem32driversetc下的hosts文件。
# 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
增加幾個Host節點,通過Cookie實現自動登錄,必須配置的虛擬主頁滿足xxx.itcast.cn,即主域名必須保持一致。
一般web應用中一般部署在web.xml文件中,單點退出相關配置如下:
CAS Authentication Filter org.jasig.cas.client.authentication.AuthenticationFilter casServerLoginUrl http://www.server.com:8080/login serverName http://www.bbs.com:8080 renew false gateway false CAS Validation Filter org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter casServerUrlPrefix http://www.server.com:8080 serverName http://www.bbs.com:8080 CAS HttpServletRequest Wrapper Filter org.jasig.cas.client.util.HttpServletRequestWrapperFilter CAS Assertion Thread Local Filter org.jasig.cas.client.util.AssertionThreadLocalFilter CAS Authentication Filter /protected/* CAS Validation Filter /* CAS HttpServletRequest Wrapper Filter /* CAS Assertion Thread Local Filter /* CAS Validation Filter /proxyCallback index.jsp
說明:我們看到單點退出的相關類結構,web.xml配置了單點退出的相關類(1個監聽器SingleSignOutHttpSessionListener,2個過濾器SingleSignOutFilter,SimpleServerLogoutHandler)。
實現利用了session存儲機制,SessionStoreManager是個單例類,用於管理session的存儲、刪除;SessionMappingStorage是session的存儲、刪除的執行者,可以看到實際存儲的結構是一個artifactId、sessionId為名值對的HashMap表;監聽器SingleSignOutHttpSessionListener的作用是session銷毀時,調用session管理單例類SessionStoreManager進行session的刪除銷毀;
SingleSignOutFilter的作用有2個:一個是在單點訪問攔截安全資源時調用單例類SessionStoreManager存儲session,另一個是在單點退出時調用單例類SessionStoreManager刪除session;SimpleServerLogoutHandler的作用是將客戶端的退出請求轉發到SSO服務器端,集中處理做各個子系統的單點退出。
1、登錄的主頁如下: <%@ page language=java import=java.util.* pageEncoding=UTF-8%> <%@ taglib uri=http://java.sun.com/jsp/jstl/core prefix=c%>
在同一台服務器上,多個站點自動登錄....>>:<%=session.getId()%>
/** * 用戶登錄 */ 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); } }
/** * 自動登錄 */ 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 {} }
/** * 安全退出刪除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); } }
這種是基於最簡單的方式實現的單點登錄,效果圖在下篇博客中的
使用基於CAS單點登錄流程實例與效果圖