技術點:
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單點登錄流程實例與效果圖