一、教程前言
1 教程目的:從頭到尾細細道來單點登錄服務器及客戶端應用的每個步驟
2 單點登錄(SSO):請看《CAS簡介》
3 本教程使用的SSO服務器是Yelu大學研發的CAS(Central Authentication Server),
4 官網:http://www.jasig.org/cas
5 本教程環境:
.Tomcat7.0.35
.JDK8
.CAS Server版本:cas-server-4.0.0-release
.CAS Client版本:cas-client-core-3.4.1-release
二、創建證書
證書是單點登錄認證系統中很重要的一把鑰匙,客戶端於服務器的交互安全靠的就是證書;本教程由於是演示所以就自己用JDK自帶的keytool工具生成證書;如果以后真正在產品環境中使用肯定要去證書提供商去購買,證書認證一般都是由VeriSign認證,
中文官方網站:http://www.verisign.com/cn/
用JDK自帶的keytool工具生成證書:
keytool -genkey -alias shaw -keyalg RSA -keystore d:/keys/shawKey
命令說明里頭的shaw 和shawKey是自己定義的名字,當然你也可以修改。
在輸入完密碼后提示輸入域名是我輸入的是sso.shaw.com,其實這個域名是不存在的,但是我為了演示所以虛擬了這個域名,技巧在於修改C:\Windows\System32\drivers\etc\hosts,添加內容如下:
127.0.0.1 sso.shaw.com
這樣在訪問sso.shaw.com的時候其實是訪問的127.0.0.1也就是本機
嚴重提醒:提示輸入域名的時候不能輸入IP地址
三、導出證書
命令:D:\keys>keytool -export -file d:/keys/shaw.crt -alias shaw -keystore d:/keys/shawkey
備注:里頭的shaw都可以換成你自己想要的名稱,當然要和之前生成的key一致。密碼是剛才生成設置的密碼。
至此導出證書完成,可以分發給應用的JDK使用了,接下來講解客戶端的JVM怎么導入證書。
生成證書碰到報錯可以參考一下內容:


四、為客戶端的JVM導入證書
命令:keytool -import -keystore D:/softWare/Java/jdk1.8.0_91/jre/lib/security/cacerts -file D:/keys/shaw.crt -alias shaw
為客戶端JVM導入證書,特別說明:D:\tools\jdk\1.6\jdk1.6.0_20\jre\lib\security — 是jre的目錄;密碼還是剛剛設置的密碼。至此證書的創建、導出、導入到客戶端JVM都已完成,下面開始使用證書到Web服務器中,本教程使用tomcat。
有可能會碰到報錯請參考:
keytool 錯誤: java.io.IOException: Keystore was tampered with, or password was incorrect
這里需要輸入的密碼不是證書的密碼執行keytool -import -keystore - file 這個命令提示需要輸入密碼。輸入 changeit,信任證書,OK
五、應用證書到Web服務器-Tomcat
說是應用起始做的事情就是啟用Web服務器(Tomcat)的SSL,也就是HTTPS加密協議,准備好一個干凈的tomcat,本教程使用的apache-tomcat-7.0.75,打開tomcat目錄的conf/server.xml文件,開啟87和92行的注釋代碼,並設置keystoreFile、keystorePass修改結果如下
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="D:/keys/shawkey" keystorePass="123456" />
參數說明:
瀏覽器提示證書錯誤,好的,那么我們點擊“繼續瀏覽此網站(不推薦)。 ”,現在進入Tomcat目錄了吧,如果是那么你又向成功邁進了一步。OK,接下來要配置CAS服務器了。
六、CAS服務器初體驗
1.CAS服務端下載:http://www.jasig.org/cas/download
2.下載完成后將cas-server-4.0.0-release.zip解壓,解壓cas-server-4.0.0-release/modules/cas-server-webapp-4.0.0.war,然后復制到你的tomcat/webapp目錄下
3.現在可以訪問CAS應用了,當然要使用HTTPS加密協議訪問,
例如本教程地址:https://sso.shaw.com:8443/cas-server-webapp-4.0.0/login ,現在打開了CAS服務器的頁面輸入 默認是 casuser/Mellon點擊登錄,所以如果你看到下面的這張圖片你就成功。
CAS登錄成功,你成功了嗎?如果沒有成功請再檢查以上步驟!
七、CAS服務器深入配置
上面的初體驗僅僅是簡單的身份驗證,實際應用中肯定是要讀取數據庫的數據,下面我們來進一步配置CAS服務器怎么讀取數據庫的信息進行身份驗證。
首先打開tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml文件,配置的地方如下,找到第107行處,注釋掉:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler"> <property name="users"> <map> <entry key="casuser" value="Mellon"/> </map> </property> </bean>
這個是比較簡單的,只是判斷用戶名和密碼相同即可通過,這個肯定不能在實際應用中使用,棄用!在下面添加下面的代碼:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource" /> <property name="sql" value="select password from t_admin_user where login_name=?" /> <property name="passwordEncoder" ref="MD5PasswordEncoder"/> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property> <property name="url"><value>jdbc:mysql://127.0.0.1:3306/user_tb</value></property> <property name="username"><value>root</value></property> <property name="password"><value>123456</value></property> </bean> <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"> <constructor-arg index="0"> <value>MD5</value> </constructor-arg> </bean>
復制cas-server-4.0.0\modules\cas-server-support-jdbc-4.0.0.jar和mysql驅動jar包到tomcat/webapp/cas/WEB-INF/lib目錄
配置解釋:
QueryDatabaseAuthenticationHandler是cas-server-support-jdbc提供的查詢接口其中一個,QueryDatabaseAuthenticationHandler是通過配置一個 SQL 語句查出密碼,與所給密碼匹配
dataSource我就不用解釋了吧,就是使用JDBC查詢時的數據源
sql語句就是查詢哪一張表,本例根據t_admin_user表的login_name字段查詢密碼,CAS會匹配用戶輸入的密碼,如果匹配則通過;下面是t_admin_user的表結構:
CREATE TABLE t_admin_user ( id BIGINT NOT NULL AUTO_INCREMENT, email VARCHAR(255), login_name VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255), password VARCHAR(255), PRIMARY KEY (id) ) ENGINE=InnoDB;
passwordEncoder,這個就算是自己加的鹽巴了,意思很明顯就是處理密碼的加密,看你的應用中數據庫保存的是明碼還是加密過的,比如本例是使用MD5加密的,所以配置了MD5PasswordEncoder這個Handler,cas內置了MD5的功能所以只需要配置一下就可以了;如果在實際應用中使用的是公司自己的加密算法那么就需要自己寫一個Handler來處理密碼,實現方式也比較簡單,創建一個類繼承org.jasig.cas.authentication.handler.PasswordEncoder然后在encode方法中加密用戶輸入的密碼然后返回即可。
我自己新增了一個用戶,然后在線md5生成了一個密碼為1的password。
復制配置過程中有可能會出現這樣問題:
cvc-complex-type.2.3: 元素 'beans' 必須不含字符 [子級], 因為該類型的內容類型為“僅元素”
解決方案:
打開一個記事本,命令行notepad,然后把配置復制進去,去掉多余的空格,重新回車,黏貼回去,就好了。
八、配置CAS客戶端
添加cas-client的jar包,有兩種方式:
傳統型:下載cas-client,地址:http://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core/3.4.1,在modules文件夾中有需要的jar包,請根據自己的項目情況選擇使用
Maven型:
<dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.4.1</version> </dependency>
設置filter,本文是在tomcat中的 webapps里頭自帶的examples實例,在里頭的web.xml添加如下代碼:
<!-- 用於單點退出,該過濾器用於實現單點登出功能,可選配置--> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <!-- 該過濾器用於實現單點登出功能,可選配置。 --> <filter> <filter-name>casSingleSignOutFilter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://sso.shaw.com:8443/cas/</param-value> </init-param> </filter> <filter-mapping> <filter-name>casSingleSignOutFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器負責用戶的認證工作,必須啟用它 --> <filter> <filter-name>CASFilter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://sso.shaw.com:8443/cas/login</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://127.0.0.1:8080</param-value> </init-param> <init-param> <param-name>useSession</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>redirectAfterValidation</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>ignorePattern</param-name> <param-value>/staticres/css/|/staticres/js/</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器負責對Ticket的校驗工作,必須啟用它 --> <filter> <filter-name>ticketValidationFilter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter </filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://sso.shaw.com:8443/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://127.0.0.1:8080</param-value> </init-param> </filter> <filter-mapping> <filter-name>ticketValidationFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器負責實現HttpServletRequest請求的包裹, 比如允許開發者通過HttpServletRequest的getRemoteUser()方法獲得SSO登錄用戶的登錄名,可選配置。 --> <filter> <filter-name>casHttpServletRequestWrapperFilter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter </filter-class> </filter> <filter-mapping> <filter-name>casHttpServletRequestWrapperFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器使得開發者可以通過org.jasig.cas.client.util.AssertionHolder來獲取用戶的登錄名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 --> <filter> <filter-name>casAssertionThreadLocalFilter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>casAssertionThreadLocalFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <error-page> <error-code>404</error-code> <location>/WEB-INF/jsp/error/error404.jsp</location> </error-page> <welcome-file-list> <welcome-file>/WEB-INF/jsp/login.jsp</welcome-file> </welcome-file-list>
測試:
本文只用一個tomcat,我們將cas-server-webapp-4.0.0改名為cas,將cas和examples放在webapps底下。如圖所示:
注意:examples-WEB-INF的lib里頭要有這幾個jar不然啟動會報錯。
啟動tomcat,在地址欄輸入http://127.0.0.1:8080/examples,瀏覽器會自動跳轉到cas登錄頁面
輸入之前的用戶名密碼,CAS登錄成功會跳轉到examples頁面,CAS系統整合成功。
特別注意:https連接不能跟ip地址,比如本文要用https://sso.shaw.com 這樣是可以的,要是https://127.0.0.1這樣服務器會報錯。
補充一下:如果是為一個老項目添加單點登錄功能,那么基本不需要其他的修改,設置好上面的filter即可;當然最好獲取用戶信息的地方都調用一個工具類,統一管理不容易出錯。
九、美化CAS服務器界面
CAS服務端(cas-server)的界面只能在測試的時候用一下,真正系統上線肯定需要定制開發自己的頁面,就想網易和CSDN的統一認證平台一樣,所有子系統的認證都通過此平台來轉接,大家可以根據他們的頁面自己定制出適合所屬應用或者公司的界面;簡單介紹一下吧,復制cas\WEB-INF\view\jsp\default\ui的一些JSP文件,每一個文件的用途文件名已經區分了,自己修改了替換一下就可以了。
例如:
登錄界面:casLoginView.jsp
登錄成功:casGenericSuccess.jsp
登出界面:casLogoutView.jsp
十、結束語
本文相關資源下載:
1.cas-server-webapp-4.0.0.war CAS服務端核心代碼
2.cas-client-core-3.4.1 CAS客戶端核心代碼
4.本文整合工程
CAS-Server下載地址:https://www.apereo.org/projects/cas/download-cas
CAS-Client下載地址:http://developer.jasig.org/cas-clients/
CAS官方教程: https://wiki.jasig.org/display/CASUM/CAS+on+Windows+Quick+Setup+Guide