咱們先按套路來,上點客套的:html
一、CAS的基本工做原理java
二、CAS的時序圖以下mysql
三、好吧好吧,下面廢話不說,我直接來乾貨web
A、hosts文件的配置,無關緊要,可是按照我以前看別人的博客,這個仍是方便安全證書的生成的算法
C:\Windows\System32\drivers\etc\hosts 文件中添加三條spring
127.0.0.1 demo.tch.comsql
127.0.0.1 app1.tch.com數據庫
127.0.0.1 app2.tch.comapache
demo.tch.com =>>對應部署cas server的tomcat,這個虛擬域名還用於證書生成
app1.tch.com =>> 對應部署app1的tomcat
app2.tch.com =>>對應部署app2的tomcat瀏覽器
B、生成安全證書
C:\Users\yang>keytool -genkey -alias ssodemo1 -keyalg RSA -keysize 1024 -keypass 123456 -keystore f:\sso\ssodemo.keystore -storepass 123456
keypass 和 storepass 兩個密碼要一致,不然下面tomcat 配置https 訪問失敗;
而後咱們將證書導出:
C:\Users\yang>keytool -export -alias ssodemo1 -keystore f:\sso\ssodemo.keystore -file f:\sso\ssodemo.crt -storepass 123456
有關keytool工具的詳細運用見:http://www.micmiu.com/lang/java/keytool-start-guide/
C、進行服務端的配置,這個比較重要,並且也是浪費我時間最多的一個地方,由於網上的博客不少東西寫的都不對,我也不知道他們是怎麼實現的,我把個人彎路show給你看:
服務端tomcat配置文件 conf/server.xml文件進行以下修改:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="F:/Study/Java/Projects/SSO/Demo/keys/ssodemo.keystore" keystorePass="123456" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"/> <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host name="demo.tch.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
對以上代碼進行截圖,而後對以上配置進行分析
CAS-Server下載地址:http://www.jasig.org/cas/download
本文以cas-server-3.4.11-release.zip爲例,解壓提取cas-server-3.4.11/modules/cas-server-webapp-3.4.11.war文件,把改文件copy到 G:\sso\tomcat-cas\webapps\目下,並重命名爲:cas.war.
啓動tomcat-cas,在瀏覽器地址欄輸入:https://demo.tch.com:8443/cas/login ,回車
寫這篇日誌的時候,不少東西我都已經修改了,可是以上表示成功了,真實的圖片容我給你盜個圖來
CAS-server的默認驗證規則:只要用戶名和密碼相同就認證經過(僅僅用於測試,生成環境須要根據實際狀況修改),輸入admin/admin 點擊登陸,就能夠看到登陸成功的頁面:
看到上述頁面表示CAS-Server已經部署成功。
上面的初體驗僅僅是簡單的身份驗證,實際應用中確定是要讀取數據庫的數據,下面咱們來進一步配置CAS服務器怎麼讀取數據庫的信息進行身份驗證。 首先打開
cas/WEB-INF/deployerConfigContext.xml
註釋掉:SimpleTestUsernamePasswordAuthenticationHandler這個驗證Handler,這個是比較簡單的,只是判斷用戶名和密碼相同便可經過,這個確定不能在實際應用中使用,棄用!緊接着添加以下代碼
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> <property name="dataSource" ref="dataSource"></property> <property name="sql" value="select password from t_admin_user where login_name=?"></property> <property name="passwordEncoder" ref="MD5PasswordEncoder"></property> </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:///wsriademo</value></property> <property name="username"><value>root</value></property> <property name="password"><value>root</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-3.4.3.1\modules\cas-server-support-jdbc-3.4.3.1.jar和mysql/Oracle驅動jar包到tomcat/webapp/cas/WEB-INF/lib目錄
QueryDatabaseAuthenticationHandler,是cas-server-support-jdbc提供的查詢接口其中一個,QueryDatabaseAuthenticationHandler是經過配置一個 SQL 語句查出密碼,與所給密碼匹配
dataSource,我就不用解釋了吧,就是使用JDBC查詢時的數據源
sql,語句就是查詢哪一張表,本例根據t_admin_user表的login_name字段查詢密碼,CAS會匹配用戶輸入的密碼,若是匹配則經過
而後修改cas/WEB-INF/cas.properties文件,修改以下兩行,具體含義我就很少說了
server.name=http://demo.tch.com:8080 server.prefix=${server.name}/cas
D、客戶端的配置
導入jar包
<dependency> <groupid>org.jasig.cas.client</groupid> <artifactid>cas-client-core</artifactid> <version>3.1.12</version> </dependency>
修改你客戶端中的web.xml文件進行修改,添加filter
<!-- sso 單點登陸sso 單點登陸sso 單點登陸sso 單點登陸sso 單點登陸sso 單點登陸sso 單點登陸--> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <!--該過濾器用於實現單點登出功能,可選配置。--> <!--<filter>--> <!--<filter-name>CAS Single Sign Out Filter</filter-name>--> <!--<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>--> <!--</filter>--> <!--<filter-mapping>--> <!--<filter-name>CAS Single Sign Out Filter</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>http://demo.tch.com:8080/cas/login</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://app1.tch.com:18080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--該過濾器負責對Ticket的校驗工做,必須啓用它--> <filter> <filter-name>CASValidationFilter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>http://demo.tch.com:8080/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://app1.tch.com:18080</param-value> </init-param> </filter> <filter-mapping> <filter-name>CASValidationFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器負責實現HttpServletRequest請求的包裹, 好比容許開發者經過HttpServletRequest的getRemoteUser()方法得到SSO登陸用戶的登陸名,可選配置。 --> <filter> <filter-name>CASHttpServletRequest WrapperFilter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter-mapping> <filter-name>CASHttpServletRequest WrapperFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 該過濾器使得開發者能夠經過org.jasig.cas.client.util.AssertionHolder來獲取用戶的登陸名。 好比AssertionHolder.getAssertion().getPrincipal().getName()。 --> <filter> <filter-name>CASAssertion Thread LocalFilter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CASAssertion Thread LocalFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
注*此時app1的http端口號爲1880,經過攔截來跳轉到cas服務,cas服務經過了用戶名和密碼以後攜帶cas生成的tickets回到客戶端。
在app1系統的intercepter攔截器中,根據AssertionHolder.getAssertion().getPrincipal().getName()取得當前登陸用戶的用戶名,來從本身的系統數據庫中取得用戶信息。同時在單獨登陸系統時,也不會受到cas系統干擾。
User user = (User) session.getAttribute("admin"); if(null == user){ if(null != AssertionHolder.getAssertion()){ String userName = AssertionHolder.getAssertion().getPrincipal().getName(); if(null != userName || !"".equals(userName)){ user = userService.queryUserByuserName(userName); } } }
E、預期流程:打開app1 url —->跳轉cas server驗證 —->顯示app1的應用 —->打開app2 url —->顯示app2應用 —->註銷cas server —->打開app1/app2url —->從新跳轉到cas server驗證.
F、
CAS服務端(cas-server)的界面只能在測試的時候用一下,真正系統上線確定須要定製開發本身的頁面,就像網易和CSDN的統一認證平臺同樣,全部子系統的認證都經過此平臺來轉接,你們能夠根據他們的頁面本身定製出適合所屬應用或者公司的界面;簡單介紹一下吧,複製 cas\WEB-INF\view\jsp\default\ui的一些JSP文件,每個文件的用途文件名已經區分了,本身修改了替換一下就能夠了。 例如:
參考資料:http://www.2cto.com/os/201402/281465.html
http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html