SSO之CAS單點登陸詳細搭建 :
環境說明:
同一個機器上環境以下:
操做系統:windows7 64位
JDK版本:1.7.0_80
web容器版本:apache-tomcat-7.0.70 64位
服務端:cas-3.5.2.1.zip
服務端如今地址:https://github.com/apereo/cas/archive/v4.2.3.zip
客戶端:cas-client-3.3.3-release.zip
客戶端下載地址:http://developer.jasig.org/cas-clients/
eclipse版本:eclipse-jee-luna-SR2-win32-x86_64.ziphtml
一、將cas-3.5.2.1 cas-client-3.3.3 標準maven工程導入eclipse 打包編譯;java
二、修改本機 C:\Windows\System32\drivers\etc\hosts (CAS單點登陸系統是基於JAVA安全證書的 https 訪問,要使用CAS單點登陸必需要配置域名, cas是不能經過ip訪問的.)
附件-->記事本管理員權限編輯hosts文件,加入以下三行代碼後保存。
127.0.0.1 server.flyer.com
127.0.0.1 client1.flyer.com
127.0.0.1 client2.flyer.commysql
解釋:
server.flyer.com =>> 對應部署cas server的tomcat,這個虛擬域名還用於服務端證書生成
client1.flyer.com =>> 對應部署client1客戶端應用的tomcat
client2.flyer.com =>> 對應部署client2客戶端應用的tomcatgit
三、安全證書配置github
3.一、管理員模式打開cmd命令窗口,生成證書,在cmd窗口輸入如下命令:
C:\Users\Administrator>keytool -genkey -alias ssoflyer -keyalg RSA -keysize 1024 -keypass flyer2016 -validity 365 -keystore D:\app\flyer.keystore -storepass flyer2016
說明:-alias自定義的別名;
-keypass指定證書密鑰庫的密碼;
-storepass和前面keypass密碼相同,不然下面tomcat配置https會訪問失敗;
-keystore指定證書的位置,例如:D:\app\目錄,密鑰庫名稱能夠自定義,例如:flyer.keystore
特別注意:您的名字與姓氏是什麼?該項必定要使用網站的域名,例如: server.flyer.com ,Cas Client使用httpclient訪問cas server的時候,會嚴格的檢查證書。
示例以下:
C:\Users\Administrator>keytool -genkey -alias ssoflyer -keyalg RSA -keysize 1024 -keypass flyer2016 -validity 365 -keystore D:\app\flyer.keystore -storepass flyer2016
您的名字與姓氏是什麼?
[Unknown]: server.flyer.com
您的組織單位名稱是什麼?
[Unknown]: HCZX_hczx
您的組織名稱是什麼?
[Unknown]: kaifabumen
您所在的城市或區域名稱是什麼?
[Unknown]: longgangbantian
您所在的州或省份名稱是什麼?
[Unknown]: guangdong
該單位的兩字母國家代碼是什麼
[Unknown]: 0755
CN=server.flyer.com, OU=HCZX_hczx, O=kaifabumen, L=longgangbantian, ST=guangdong, C=0755 正確嗎?
[否]: y
web
3.二、導出證書:
在cmd窗口繼續輸入如下命令,導出證書:
C:\Users\Administrator>keytool -export -alias ssoflyer -keystore D:\app\flyer.keystore -file D:\app\ssoflyer.crt -storepass flyer2016sql
說明:-alias後面的名稱要與生成證書的命令裏面的alias的名稱一致;
–keystore後面指定證書存放的位置,上面定義的D:\app\目錄;
證書名稱要與【生成證書】對應的命令裏的keystore名稱一致.這裏是flyer.keystore;
-file後面才crt路徑,指定在D:\app\目錄;
–storepass的證書密碼要與上面輸入的密碼一致.數據庫
3.三、客戶端導入證書express
在cmd窗口輸入命令:
添加 keypair JDK
keytool -importcert -alias ssoflyer -file D:\app\ssoflyer.crt -keystore %JAVA_HOME%\jre\lib\security\cacerts -storepass changeit -noprompt
查看 keypair: JDK
keytool -list -alias ssoflyer -keystore %JAVA_HOME%\jre\lib\security\cacerts -storepass changeit
刪除 keypair: JDK
keytool -delete -keystore %JAVA_HOME%\jre\lib\security\cacerts -alias ssoflyer -storepass changeitapache
添加 keypair: JRE
keytool -importcert -alias ssoflyer -file D:\app\ssoflyer.crt -keystore D:\app\Java\jre1.7.0_80\lib\security\cacerts -storepass changeit -noprompt
查看 keypair: JRE
keytool -list -alias ssoflyer -keystore D:\app\Java\jre1.7.0_80\lib\security\cacerts -storepass changeit
刪除 keypair: JRE
keytool -delete -keystore D:\app\Java\jre1.7.0_80\lib\security\cacerts -alias ssoflyer -storepass changeit
說明:-file指定證書的位置,上一步導出證書的位置,即D:\app\ssoflyer.crt;
實際測試過程當中,最好jdk jre的security中都把證書導入;
這裏-storepass的密碼必需要輸入changeit,不能輸入上面指定的密碼 flyer2016 ,不然導入客戶端證書會有問題。
四、部署CAS-Server相關的Tomcat
apache-tomcat-7.0.70-server配置HTTPS 編輯D:\app\apache-tomcat-7.0.70-server\conf\server.xml,找到下面片斷:
註釋:
<!--APR library loader. Documentation at /docs/apr.html
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
-->
拷貝一份,修改爲:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="D:/app/flyer.keystore" keystorePass="flyer2016"
clientAuth="false" sslProtocol="TLS" />
其中,keystoreFile就是建立證書的路徑,keystorePass就是建立證書的密碼.
啓動tomcat 驗證https是否配置成功,瀏覽器訪問,在地址欄輸入
https://server.flyer.com:8443/ 出現tomcat歡迎頁,代表tomcat的https配置OK.
點擊【我已充分了解可能的風險】,點擊出現的【添加例外】—【確認安全例外】!
部署CAS-Server,將打包編譯好的cas.war,把改文件copy到D:\app\apache-tomcat-7.0.70-server\webapps\webapps 目錄下。
啓動tomcat,在瀏覽器地址欄輸入:https://server.flyer.com:8443/cas ,出現CAS服務端的登陸驗證首頁,表示配置OK.
用mysql來進行用戶名密碼驗證,具體配置以下:
用戶名和密碼確定須要和數據庫進行交互驗證的,如何配置呢?
【說明】:我本地使用的是mysql數據庫。
一、修改工程cas-server-webapp 中的 deployerConfigContext.xml文件
<bean
class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
<property name="dataSource" ref="casDataSource"></property>
<property name="tableUsers" value="cas_login"></property>
<property name="fieldUser" value="user_name"></property>
<property name="fieldPassword" value="passwords"></property>
<property name="passwordEncoder" ref="MD5PasswordEncoder"></property>
</bean>
<bean id="MD5PasswordEncoder"
class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-arg index="0">
<value>MD5</value>
</constructor-arg>
</bean>
<!-- 定義數據源 -->
<bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/appstore?useUnicode=true&characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root123456" />
<property name="minEvictableIdleTimeMillis" value="-1" />
<property name="validationQuery" value="select 1 from dual" />
</bean>
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="casDataSource" />
<constructor-arg index="1"
value="select user_name username from cas_login where user_name=?" />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="user_name" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="username" value="user_name" />
</map>
</property>
</bean>
五、部署CAS客戶端相關的Tomcat
首先,客戶端應用是要和CAS服務端進行交互的,因此這裏須要jar文件,放在客戶端應用的lib目錄下。分別是:
apache-tomcat-7.0.70-client1\webapps\castest\WEB-INF\lib
cas-client-core-3.3.3.jar
commons-logging-1.1.1.jar
log4j-1.2.15.jar
slf4j-api-1.7.1.jar
slf4j-log4j12-1.7.1.jar
建立一個jsp
apache-tomcat-7.0.70-client1\webapps\castest\index.jsp
配置D:\app\apache-tomcat-7.0.70-client1客戶端1:
修改tomcat的啓動端口:
編輯D:\app\apache-tomcat-7.0.70-client1\conf\server.xml文件,找到以下2處內容:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改成:
<Connector port="8088" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
修改成:
<Connector port="8021" protocol="AJP/1.3" redirectPort="8443" />
<Server port="8005" shutdown="SHUTDOWN">
修改成:
<Server port="8006" shutdown="SHUTDOWN">
啓動這個tomcat,即運行D:\app\apache-tomcat-7.0.70-client1\bin\startup.bat。
瀏覽器輸入 http://client1.flyer.com:8088/castest/ 顯示到剛編輯的jsp標識配置正常。
編輯D:\app\apache-tomcat-7.0.70-client1\webapps\castest\WEB-INF\web.xml,在最下面加入以下配置:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<description>Servlet and JSP Examples.</description>
<display-name>Servlet and JSP Examples</display-name>
<!-- 用於單點退出,該過濾器用於實現單點登出功能,可選配置-->
<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>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://server.flyer.com:8443/cas/login</param-value>
</init-param>
<init-param>
<!--這裏的客戶端server是服務端的IP-->
<param-name>serverName</param-name>
<param-value>http://client1.flyer.com:8088</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
2.ValidationFilter
該過濾器負責對請求參數Ticket進行驗證(ticket參數是負責子系統與CAS進行驗證交互的憑證)
casServerUrlPrefix:CAS服務訪問地址
serverName:當前應用所在的主機名
-->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://server.flyer.com:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://client1.flyer.com:8088</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
3.HttpServletRequestWrapperFilter
這個是HttpServletRequest的包裹類,讓他支持getUserPrincipal,getRemoteUser方法來取得用戶信息
-->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
4.AssertionThreadLocalFilter
這個類把Assertion信息放在ThreadLocal變量中,這樣應用程序不在web層也可以獲取到當前登陸信息
Assertion assertion = AssertionHolder.getAssertion();
-->
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
配置完成後,啓動CAS服務端tomcat,再啓動該客戶端1的tomcat,在瀏覽器訪問:
http://client1.flyer.com:8088/castest
看看是否跳轉到了CAS認證界面,回車以後
認證觀察會發現瀏覽器的地址欄中(我用的是火狐瀏覽器),URL信息是這樣的:
https://server.flyer.com:8443/cas/login?service=http%3A%2F%2Fclient1.flyer.com%3A8088%2Fcastest%2F
因爲你沒有登陸CAS認證系統,CAS認證系統攔截到你訪問的客戶端應用,首先進入到認證系統登陸界面,同時URL後面加上你想訪問的地址信息,當你登陸成功後,CAS服務會轉向到你剛剛訪問的地址,也就是:
http://client1.flyer.com:8088/castest/
六、配置第二臺tomcat,參見上步的server.xml修改
修改編輯D:\app\apache-tomcat-7.0.70-client2\webapps\castest\WEB-INF\web.xml文件,加入的內容就是上面在第一個客戶端的web.xml內容一致:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<description>Servlet and JSP Examples.</description>
<display-name>Servlet and JSP Examples</display-name>
<!-- 用於單點退出,該過濾器用於實現單點登出功能,可選配置-->
<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>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://server.flyer.com:8443/cas/login</param-value>
</init-param>
<init-param>
<!--這裏的客戶端server是服務端的IP-->
<param-name>serverName</param-name>
<param-value>http://client2.flyer.com:8088</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
2.ValidationFilter
該過濾器負責對請求參數Ticket進行驗證(ticket參數是負責子系統與CAS進行驗證交互的憑證)
casServerUrlPrefix:CAS服務訪問地址
serverName:當前應用所在的主機名
-->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://server.flyer.com:8443/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://client2.flyer.com:8088</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
3.HttpServletRequestWrapperFilter
這個是HttpServletRequest的包裹類,讓他支持getUserPrincipal,getRemoteUser方法來取得用戶信息
-->
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
4.AssertionThreadLocalFilter
這個類把Assertion信息放在ThreadLocal變量中,這樣應用程序不在web層也可以獲取到當前登陸信息
Assertion assertion = AssertionHolder.getAssertion();
-->
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
至此,2個客戶端也已經配置完畢,啓動配置好的三個tomcat分別爲:CAS服務端tomcat、2個客戶端tomcat
下面截圖,根據上面所示進行測試,看看是否與上面說的流程一致:
首先,打開火狐瀏覽器,地址欄輸入:
http://client2.flyer.com:8089/castest2