CAS單點登陸實現案例

咱們先按套路來,上點客套的: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會匹配用戶輸入的密碼,若是匹配則經過

  • passwordEncoder,這個就算是本身加的鹽巴了,意思很明顯就是處理密碼的加密,看你的應用中數據庫保存的是明碼仍是加密過的,好比本例是使用MD5加密的,因此配置了MD5PasswordEncoder這個Handler,cas內置了MD5的功能因此只須要配置一下就能夠了;若是在實際應用中使用的是公司本身的加密算法那麼就須要本身寫一個Handler來處理密碼,實現方式也比較簡單,建立一個類繼承org.jasig.cas.authentication.handler.PasswordEncoder而後在encode方法中加密用戶輸入的密碼而後返回便可.

而後修改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文件,每個文件的用途文件名已經區分了,本身修改了替換一下就能夠了。 例如:

  • 登陸界面:casLoginView.jsp
  • 登陸成功:casGenericSuccess.jsp
  • 登出界面:casLogoutView.jsp

 

 

參考資料:http://www.2cto.com/os/201402/281465.html

                http://www.kafeitu.me/sso/2010/11/05/sso-cas-full-course.html

相關文章
相關標籤/搜索