課程目标
目标1:搭建單點登入服務端,開發單點登入用戶端
目标2:實作CAS 認證資料源設定
目标3:更換CAS 登入頁面
目标4:掌握CAS與SpringSecurity內建
目标5:完成使用者中心單點登入功能
1.開源單點登入系統CAS入門
1.1 什麼是單點登入
單點登入(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,使用者隻需要登入一次就可以通路所有互相信任的應用系統。
我們目前的系統存在諸多子系統,而這些子系統是分别部署在不同的伺服器中,那麼使用傳統方式的session是無法解決的,我們需要使用相關的單點登入技術來解決。

1.2 什麼是CAS
CAS 是 Yale 大學發起的一個開源項目,旨在為 Web 應用系統提供一種可靠的單點登入方法,CAS 在 2004 年 12 月正式成為 JA-SIG 的一個項目。CAS 具有以下特點:
【1】開源的企業級單點登入解決方案。
【2】CAS Server 為需要獨立部署的 Web 應用。
【3】CAS Client 支援非常多的用戶端(這裡指單點登入系統中的各個 Web 應用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。
從結構上看,CAS 包含兩個部分: CAS Server 和 CAS Client。CAS Server 需要獨立部署,主要負責對使用者的認證工作;CAS Client 負責處理對用戶端受保護資源的通路請求,需要登入時,重定向到 CAS Server。下圖是 CAS 最基本的協定過程:
SSO單點登入通路流程主要有以下步驟:
- 通路服務:SSO用戶端發送請求通路應用系統提供的服務資源。
- 定向認證:SSO用戶端會重定向使用者請求到SSO伺服器。
- 使用者認證:使用者身份認證。
- 發放票據:SSO伺服器會産生一個随機的Service Ticket。
- 驗證票據:SSO伺服器驗證票據Service Ticket的合法性,驗證通過後,允許用戶端通路服務。
- 傳輸使用者資訊:SSO伺服器驗證票據通過後,傳輸使用者認證結果資訊給用戶端。
1.3 CAS服務端部署
Cas服務端其實就是一個war包。
在資源cassourcecas-server-4.0.0-releasecas-server-4.0.0modules目錄下
cas-server-webapp-4.0.0.war 将其改名為cas.war放入tomcat目錄下的webapps下。啟動tomcat自動解壓war包。浏覽器輸入http://localhost:8080/cas/login ,可看到登入頁面
不要嫌棄這個頁面醜,我們後期可以再提升它的顔值。暫時把注意力放在功能實作上。
這裡有個固定的使用者名和密碼 casuser /Mellon
登入成功後會跳到登入成功的提示頁面
1.4 CAS服務端配置
1.4.1端口修改
如果我們不希望用8080端口通路CAS, 可以修改端口
(1)修改TOMCAT的端口
打開tomcat 目錄 confserver.xml 找到下面的配置
将端口8080,改為9100
(2)修改CAS配置檔案
修改cas的WEB-INF/cas.properties
server.name=http://localhost:9100
1.4.2去除https認證
CAS預設使用的是HTTPS協定,如果使用HTTPS協定需要SSL安全證書(需向特定的機構申請和購買) 。如果對安全要求不高或是在開發測試階段,可使用HTTP協定。我們這裡講解通過修改配置,讓CAS使用HTTP協定。
(1)修改cas的WEB-INF/deployerConfigContext.xml
找到下面的配置
這裡需要增加參數p:requireSecure=“false”,requireSecure屬性意思為是否需要安全驗證,即HTTPS,false為不采用
(2)修改cas的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml
找到下面配置
參數p:cookieSecure=“true”,同理為HTTPS驗證相關,TRUE為采用HTTPS驗證,FALSE為不采用https驗證。
參數p:cookieMaxAge="-1",是COOKIE的最大生命周期,-1為無生命周期,即隻在目前打開的視窗有效,關閉或重新打開其它視窗,仍會要求驗證。可以根據需要修改為大于0的數字,比如3600等,意思是在3600秒内,打開任意視窗,都不需要驗證。
我們這裡将cookieSecure改為false , cookieMaxAge 改為3600
(3)修改cas的WEB-INF/spring-configuration/warnCookieGenerator.xml
找到下面配置
我們這裡将cookieSecure改為false , cookieMaxAge 改為3600
1.5 CAS用戶端入門小Demo
1.5.1用戶端工程1搭建
(1)搭建工程引入依賴
建立Maven工程 (war)casclient_demo1 引入cas用戶端依賴并制定tomcat運作端口為9001
org.jasig.cas.client cas-client-core 3.3.3javax.servletservlet-api2.5providedorg.apache.maven.plugins maven-compiler-plugin 2.3.21.71.7org.apache.tomcat.maventomcat7-maven-plugin9001/
(2)添加web.xml
<?xml version="1.0" encoding="UTF-8"?>org.jasig.cas.client.session.SingleSignOutHttpSessionListenerCAS Single Sign Out Filterorg.jasig.cas.client.session.SingleSignOutFilterCAS Single Sign Out Filter/*CASFilterorg.jasig.cas.client.authentication.AuthenticationFiltercasServerLoginUrlhttp://localhost:9100/cas/loginserverNamehttp://localhost:9001CASFilter/*CAS Validation Filter org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFiltercasServerUrlPrefixhttp://localhost:9100/casserverNamehttp://localhost:9001CAS Validation Filter/*CAS HttpServletRequest Wrapper Filter org.jasig.cas.client.util.HttpServletRequestWrapperFilterCAS HttpServletRequest Wrapper Filter/*CAS Assertion Thread Local Filterorg.jasig.cas.client.util.AssertionThreadLocalFilterCAS Assertion Thread Local Filter/*
(3)編寫index.jsp
一品優購歡迎來到一品優購
request.getRemoteUser()為擷取遠端登入名
1.5.2用戶端工程2搭建
(1)建立Maven工程 (war)casclient_demo2 引入cas用戶端依賴并制定tomcat運作端口為9002
(2)建立web.xml,參照casclient_demo1 ,将serverName的值改為http://localhost:9002,一共兩處
(3)建立index.jsp ,内容顯示“歡迎來到二品優購”
1.5.3單點登入測試
(1)啟動cas部署的tomcat
(2)啟動用戶端工程1和用戶端工程2
(3)位址欄輸入http://localhost:9001/ 和http://localhost:9002/ ,位址均會跳轉到CAS登入頁
(4)輸入使用者名和密碼後,頁面跳轉回9002 ,再次通路9001也可以打開首頁面。
1.5.4單點登出
位址欄輸入 http://localhost:9100/cas/logout
即可看到退出後的提示頁面
我們可以将這個連結添加到index.jsp中
登出
但我們更希望登出後,能自動跳轉到某個頁面,那如何處理呢?
修改cas系統的配置檔案cas-servlet.xml
改為true後,可以在退出時跳轉頁面到目标頁面,修改index.jsp的退對外連結接
登出
2.CAS服務端資料源設定
2.1需求分析
我們現在讓使用者名密碼從我們的品優購的user表裡做驗證
2.2配置資料源
(1)修改cas服務端中web-inf下deployerConfigContext.xml ,添加如下配置
然後在配置檔案開始部分找到如下配置
其中
一句是使用固定的使用者名和密碼,我們在下面可以看到這兩個bean ,如果我們使用資料庫認證使用者名和密碼,需要将這句注釋掉。
添加下面這一句配置
(2)将以下三個jar包放入webappscasWEB-INFlib下
(這三個jar包在資源casjar目錄下)
用資料庫中的使用者名和密碼進行測試
3.CAS服務端界面改造
3.1需求分析
我們現在動手将CAS預設的登入頁更改為自己的品優購登陸頁
3.2改頭換面
3.2.1拷貝資源
(1)将品優購的登陸頁login.html拷貝到cas系統下WEB-INFviewjspdefaultui 目錄下
(2)将css js等檔案夾拷貝到 cas目錄下
(3) 将原來的casLoginView.jsp 改名(可以為之後的修改操作做參照),将login.html改名為casLoginView.jsp
3.2.2修改頁面
編輯casLoginView.jsp 内容
(1)添加指令
(2)修改form标簽
......
(3)修改使用者名框
(4)修改密碼框
(5)修改登陸按鈕
修改後效果如下:
3.3錯誤提示
在表單内加入錯誤提示框
測試:輸入錯誤的使用者名和密碼,提示是英文。這個提示資訊是在WEB-INFclasses目錄下的messages.properties檔案中
authenticationFailure.AccountNotFoundException=Invalid credentials.authenticationFailure.FailedLoginException=Invalid credentials.
設定國際化為zn_CN ,修改cas-servlet.xml
我們需要将此資訊拷貝到messages_zh_CN.properties下,并改為中文提示(轉碼)
authenticationFailure.AccountNotFoundException=使用者不存在.authenticationFailure.FailedLoginException=密碼錯誤.
第一個是使用者名不存在時的錯誤提示
第二個是密碼錯誤的提示
4. CAS用戶端與SpringSecurity內建
4.1 Spring Security測試工程搭建
(1)建立Maven項目casclient_demo3 ,引入spring依賴和spring secrity 相關依賴 ,tomcat端口設定為9003
(2)建立web.xml ,添加過濾器等配置
(3)建立配置檔案spring-security.xml
(4)添加html頁面
4.2 Spring Security與 CAS內建
(1)引入依賴
org.springframework.security spring-security-cas 4.1.0.RELEASEorg.jasig.cas.client cas-client-core 3.3.3org.slf4j log4j-over-slf4j
(2)修改spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
(3)建立UserDetailsServiceImpl
/** * 認證類 */public class UserDetailServiceImpl implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//建構角色集合List authorities=new ArrayList();authorities.add(new SimpleGrantedAuthority("ROLE_USER"));return new User(username, "" , authorities);}}
這個類的主要作用是在登陸後得到使用者名,可以根據使用者名查詢角色或執行一些邏輯。
4.3擷取登入名
我們在處理後端邏輯需要獲得登入名,那麼如何擷取單點登入的使用者名呢? 其實和我們之前獲得使用者名的方式是完全相同的,我們下面來做個測試。
(1)web.xml 添加springmvc
springmvcorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:springmvc.xmlspringmvc*.do
(2)建立springmvc.xml
(3)建立UserController
@RestControllerpublic class UserController {@RequestMapping("/findLoginUser")public void findLoginUser(){String name = SecurityContextHolder.getContext().getAuthentication().getName();System.out.println(name);}}
位址欄輸入http://localhost:9003/findLoginUser.do 即可在控制台看到輸出的登入名。
4.4登出
修改spring-security.xml
在頁面上添加連結
登出
建立index2.html,将index2.html設定為可匿名通路
5.品優購使用者中心
5.1需求分析
使用者中心實作單點登入。
5.2代碼實作
5.2.1使用者中心實作單點登入
(1)将使用者中心相關的頁面(home-開頭的)拷貝至 pinnyougou-user-web
(2)pom.xml 引入springSecurity、cas用戶端和springSecurity Cas整合包依賴(參照casclient_demo3)。
(3)web.xml 添加spring-security過濾器(參照參照casclient_demo3)設定首頁為home-index.html
home-index.html
(4)建構UserDetailsServiceImpl.java (參照casclient_demo3)
(5)添加spring-security.xml(參照casclient_demo3),并做以下修改
配置匿名通路資源
設定服務位址屬性
設定認證類
5.2.2頁面顯示使用者名
(1)pinyougou-user-web建立LoginController.java
@[email protected]("/login")public class LoginController {@RequestMapping("/name")public Map showName(){String name = SecurityContextHolder.getContext().getAuthentication().getName();//得到登陸人賬号Map map=new HashMap<>();map.put("loginName