程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> SSO 基於Cookie+fliter實現單點登錄 實例解析(一)

SSO 基於Cookie+fliter實現單點登錄 實例解析(一)

編輯:C++入門知識

SSO 基於Cookie+fliter實現單點登錄 實例解析(一)


接上文,SSO的理論講解,接下來實踐實踐!

 

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修改本機的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服務器端,集中處理做各個子系統的單點退出。

 

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%>

在同一台服務器上,多個站點自動登錄....>>:<%=session.getId()%>

歡迎你:${user}。>安全退出
相關站點:(只要在一邊登錄成功,即可以自動登錄到另一個程序)
mail.itcast.com
bbs.itcast.com

2、登錄的Servlet程序如下:

/**
 * 用戶登錄
 */
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);
	}
}

3、自動登錄的Filter程序如下:

/**
 * 自動登錄
 */
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 {}
}


4、正常退出的Servlet如下

/**
 * 安全退出刪除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單點登錄流程實例與效果圖

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved