五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > CAS 單點登錄架設筆記

CAS 單點登錄架設筆記

文章來源:365jz.com     點擊數(shù):3607    更新時間:2009-10-12 09:41   參與評論

工作需要,對CAS進行了研究,網(wǎng)絡上看了些文章,但都不完善,自己就寫了一篇。

我在CAS部署過程中遇到了幾個問題,主要是中文亂碼的問題,畢竟是外國人寫的東西。對中文的支持不好。

相關的jar包可以在www.apache.org  www.jasig.org  www.springsource.org上找到

在CAS架設中遇到的問題和我的解決方案

1.CAS服務端用戶登入如果是中文請求會亂碼的問題

解決方案:CAS利用到spring,spring框架中提供了編碼過濾功能,利用它可以解決請求亂碼問題

 

2.CAS客戶端和服務端中文傳輸亂碼問題,雖然請求亂碼問題解決了,但是這個問題還是會存在,可能是數(shù)據(jù)傳輸過程中引起的

解決方案:BASE64服務端加密,客戶端解密(O(∩_∩)O~偶突發(fā)奇想來的)

 

3.中心同一個服務器,機房和辦公室訪問地址不同的問題(有的網(wǎng)站一個服務器有多個域名)

解決方案:重寫CAS客戶端CASFilter類,請注意,我們中心的CAS客戶端和CAS服務端在同一服務器上的,我是針對這環(huán)境下寫的

 

CAS架設環(huán)境

Windows
Tomcat 6.x
JDK 1.6
CAS server 3.34
cas-client-2.0.11(是耶魯大學的那個版本,不是最新版,最新不一定最好,下載時請注意)

 

 

配置CAS服務端

部署cas-server

下載最新的cas-server-3.3.4.zip 服務器端,解壓后找到cas-server-webapp.war,將這個war進行解壓到tomcatwebapps目錄下.

將剛才解壓出的目錄cas-server-webapp進行重命名為cas

啟動tomcat 輸入http://localhost:8080/cas/login 查看是否成功部署

下載地址: http://www.jasig.org/

推薦環(huán)境:JDK1.6 tomcat 6.0

配置數(shù)據(jù)源和身份驗證

用戶的認證信息通常保存在數(shù)據(jù)庫中,我們這里使用的是jtds數(shù)據(jù)庫連接。

將前面下載的cas-server-3.3.4.zip 包解開后,在 modules 目錄下可以找到包cas-server-support-jdbc-3.3.4.jar,再下載個jtdsjar包,將兩個包拷貝到cas\WEB-INF\lib目錄下

DataStore 依賴于 spring.jar, commons-collections.jar, commons-dbcp.jar, commons-pool.jar

apachespring官方網(wǎng)找到這四個包把它們拷貝到cas\WEB-INF\lib

 

在 cas-server-support-jdbc-3.3.4.jar包中,提供了 個基于 JDBC 的 AuthenticationHandler,分別為 BindModeSearchDatabaseAuthenticationHandler, QueryDatabaseAuthenticationHandler, SearchModeSearchDatabaseAuthenticationHandler

我們這里使用的是QueryDatabaseAuthenticationHandler,它是通過配置一個 SQL 語句查出密碼,與所給密碼匹配

 

根據(jù)密碼加密方式的不同,我們需要實現(xiàn)PasswordEncoder接口,來對輸入的密碼進行加密才能與數(shù)據(jù)庫中的密碼比較

 

建立一個項目,導入cas-server-core-3.3.4.jar

在項目中寫個類實現(xiàn)org.jasig.cas.authentication.handler.PasswordEncoder接口中的public String encode(String arg0)方法,這是用來輸入的密碼加密的。

項目導出成jar包,拷貝到cas\WEB-INF\lib

 

 

 

根據(jù)不同的密碼加密方式實現(xiàn),我這里是MD5加密,下文僅為參考,請根據(jù)需求變化

新建個caspasskey項目

源碼為

package org;

 

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

 

import org.jasig.cas.authentication.handler.PasswordEncoder;

 

public class MD5 implements PasswordEncoder {

 

@Override

public String encode(String arg0) {

MessageDigest digest = null;

if (digest == null) {

try {

 

digest = MessageDigest.getInstance("MD5");

catch (NoSuchAlgorithmException nsae) {

 

nsae.printStackTrace();

}

}

// Now, compute hash.

digest.update(arg0.getBytes());

 

 

byte[] bytes=digest.digest();

StringBuffer buf = new StringBuffer(bytes.length * 2);

for (int i= 0; i < bytes.length; i++) {

if (((int) bytes[i] & 0xff) < 0x10) {

buf.append("0");

}

buf.append(Long.toString((int) bytes[i] & 0xff, 16));

}

return buf.toString().toUpperCase();

}

 

}

 

導出為caspasskey.jar,拷貝到cas/WEB-INF/lib目錄下

 

 

打開文件cas/WEB-INF/deployerConfigContext.xml,

找到

<bean

class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

將它替換為

<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"> 

 <property name="dataSource" ref="casDataSource" /> 

  <property name="sql"         

      value="select 密碼 from 用戶表 where lower([用戶名]) = UPPER(?)" />  

      <property  name="passwordEncoder"  ref="myPasswordEncoder"/></bean>

 

  <bean id="myPasswordEncoder"    class="org.MD5"/>  ---org.MD5這是我上文自定義的加密類

 

 

找到

<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl" />在它的下方添加以下數(shù)據(jù)源代碼

<bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource">     

<property name="driverClassName">        

<value>net.sourceforge.jtds.jdbc.Driver</value> 

  </property>    

       <property name="url"> 

<value>jdbc:jtds:sqlserver://數(shù)據(jù)庫地址:1433/數(shù)據(jù)庫名</value>

         </property>     <property name="username"> 

          <value>數(shù)據(jù)庫訪問用戶名</value>     </property>   

            <property name="password">

              <value>數(shù)據(jù)庫訪問密碼</value>

              </property>

              </bean>

 

到此,數(shù)據(jù)庫與cas服務端的連接已完成,登入http://localhost:8080/cas/login,英文的用戶名測試登入是否成功!

 

CAS服務端提交表單utf-8中文亂碼解決方案

中文的用戶名登入,默認情況下是亂碼的,因為cas沒有對請求進行utf-8編碼

cas用到了spring的框架,我們可以直接利用spring的編碼器進行utf-8編碼

web.xml中添加

<filter>

<filter-name>encodingFilter</filter-name>

<filter-class>

org.springframework.web.filter.CharacterEncodingFilter

</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>utf-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>encodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

需要注意的是,此配置需要在 <filter-mapping>

<filter-name>CAS Client Info Logging Filter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>的上方

 

再測試,發(fā)現(xiàn)中文可以登入了。

 

中文用戶名客戶端亂碼解決方案

因為cas默認對中文是不支持的,在cas服務端與客戶端之間,如果有中文存在,會有中文亂碼的問題,雖然上文對請求進行了編碼,但是客戶端中文亂碼的問題始終存在。為了避免中文亂碼的存在,我的臨時解決方案是在服務器端對中文進行base64加密,在客戶端進行base64解密

 

找到org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver類的源代碼,這個類在cas-server-core-3.3.4.jar包中

找到 protected String extractPrincipalId(final Credentials credentials)方法,將

return usernamePasswordCredentials.getUsername();

改為

return (new sun.misc.BASE64Encoder()).encode(usernamePasswordCredentials.getUsername().getBytes());

 

這樣就可以在服務器端對所有用戶名進行base64加密了

 

服務器端配置到此結束

 

Tomcat SSL安全驗證

如果要實現(xiàn)CAS的單點登入,這是必須的

 

1. 生產(chǎn)密鑰

點擊開始à運行,輸入cmd

進入控制臺

Ø CD  X:\jdk根目錄\Java\jdk1.6.0_14\bin

Ø CD X:

Ø 下文中導入過程密碼統(tǒng)一使用changeit

keytool -genkey -alias cas-server -keyalg RSA -keypass changeit -storepass changeit -keystore casserver.keystore

輸入密碼后,在第一個提示輸入姓名的時候,輸入你的服務端地址或ip地址,localhost

國家輸入CN

keytool -export -alias cas-server  -storepass changeit -file casserver.cer -keystore  casserver.keystore

 

 

keytool -import -trustcacerts -alias server -file casserver.cer –keystore jre根目錄/lib/security/cacerts -storepass changeit 

 

如果操作成功,會在jdk bin目錄下看到casserver.cer  casserver.keystore 這兩個文件

打開tomcat目錄下conf/ server.xml 文件,找到

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

               maxThreads="150" scheme="https" secure="true"

               clientAuth="false" sslProtocol="TLS" />

將注釋去掉,修改為

<Connector port="8443" protocol="HTTP/1.1"  SSLEnabled="true"

               maxHttpHeaderSize="8192"

maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

enableLookups="false" disableUploadTimeout="true"

acceptCount="100" scheme="https" secure="false"

clientAuth="false" sslProtocol="TLS"

keystoreFile=" x:\casserver.keystore 所在的目錄\casserver.keystore" keystorePass="changeit"

/>

 

默認的密鑰有效期是3個月,可以根據(jù)自己需求修改

訪問https://localhost:8443/cas/login 測試是否部署成功

 

CAS客戶端配置

CAS客戶端配置非常的簡單,但這里需要進行些修改

以下是官方文檔中客戶端web.xml中配置

<filter>

<filter-name>CAS Filter</filter-name>

<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>

<param-value>https://compA:8443/cas/login</param-value><!—compAcas服務器的地址à

</init-param>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>

<param-value>https://compA:8443/cas/serviceValidate</param-value>

</init-param>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>

<param-value>compA:8080</param-value><!注意,這里compAcas客戶端的地址à

</init-param>

</filter>

 

<filter-mapping>

<filter-name>CAS Filter</filter-name>

<!對訪問/servlet/HelloWorldExample 進行攔截,轉向cas服務器端驗證à

<url-pattern>/servlet/HelloWorldExample</url-pattern>

</filter-mapping>

 

因為我們中心的網(wǎng)絡環(huán)境原因,機房和辦公室訪問同一臺服務器的地址是不同的,所以需要對CASFilter類的源代碼進行更改。注意,此設置修改僅對于CAS客戶端和cas服務端在同一服務器時

下載cas-client-2.0.11.zip解壓導入源碼,修改edu.yale.its.tp.cas.client.filter.CASFilter

注意:不要太高版本,2.0x是耶魯?shù)陌姹荆甙姹臼?/span>jasig的,實現(xiàn)的步驟全都變了.

 

1. 聲明兩個屬性

private String casclientport,casserverport;

2. init方法中添加

casclientport = config.getInitParameter(

                "edu.yale.its.tp.cas.client.filter.port");

casserverport = config.getInitParameter(

    "edu.yale.its.tp.cas.server.filter.port");

這是我自定義的,用來在xml中指定自定義的端口號

3. doFilter方法中添加

    casLogin="https://"+request.getServerName()+":"+casserverport+"/cas/login";//cas服務器的登入地址 request.getServerName()是可以根據(jù)客戶訪問的服務器端地址不同而變化的

casServerName=request.getServerName()+":"+casclientport;//注意,這是cas客戶端的地址

    casValidate="https://"+request.getServerName()+":"+casserverport+"/cas/serviceValidate";//cas服務器的驗證地址

 

修改客戶端web.xml

<!-- CAS  --> 

<filter>

<filter-name>CAS Filter</filter-name>

<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>

<param-value>/cas/login</param-value><!-- 默認無需修改 -->

</init-param>

<init-param> 

<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>

<param-value>/cas/serviceValidate</param-value><!-- 默認無需修改 -->

</init-param>

<init-param> 

<param-name>edu.yale.its.tp.cas.client.filter.port</param-name>

<param-value>8080</param-value><!-- 對應客戶端端口號 -->

</init-param>

<init-param> 

<param-name>edu.yale.its.tp.cas.server.filter.port</param-name>

<param-value>8443</param-value><!-- 對應服務器端口號 因為是ssl安全連接,所以是8443-->

</init-param>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>

<param-value>localhost:8080</param-value><!-- 這是服務器端驗證后訪問客戶端的地址-->

</init-param> 

</filter>

<!-- 對訪問/xxxxx的都進行攔截,并轉向cas服務器,進行登入驗證 -->

<filter-mapping>

<filter-name>CAS Filter</filter-name>

<url-pattern>/xxxxx</url-pattern>

</filter-mapping>

<!-- CAS end  -->

因為我們上文對中文在服務器端進行了base64加密,在客戶端,就需要進行解密

還是對CASFilter類進行修改

在讀doFilter方法中找到以下語句

        if (session != null// probably unncessary

            session.setAttribute(CAS_FILTER_USER, user);

將它修改為

      if (session != null// probably unncessary

        {

            session.setAttribute(CAS_FILTER_USER,  new String((new BASE64Decoder()).decodeBuffer(user)));

        }

這就是對base64加密的數(shù)據(jù)進行解密后再存放進客戶端的session.

 

 

到此客戶端存在的問題就解決了

 

測試在一個客戶端已http://localhost:8080/客戶端名/xxxxx

 

 

CAS權限認證我的方案

 

1. 我的理解是CAS主要解決用戶登入的問題,權限上還是由各應用系統(tǒng)來分配的,用戶在訪問受限的頁面時,通過過濾器判斷CAS是否已登入過了,并且在客戶端附加過了相關權限。

如果用戶未登入過,則登入CAS服務端進行用戶登入,登入后返回客戶端,再根據(jù)用戶名附加權限

如果用戶cas服務端已登入過了,但是他是第一次登入客戶端,則進入CAS服務端,獲取登入的用戶名,再返回客戶端進行根據(jù)用戶名附加權限

如果用戶已登入了CAS并且附加了權限,則不在進入CAS服務端驗證

 

 

 cas權限流程圖

 

 

全文到此結束,謝謝!

 

 

如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點擊進入論壇

發(fā)表評論 (3607人查看,0條評論)
請自覺遵守互聯(lián)網(wǎng)相關的政策法規(guī),嚴禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學習

業(yè)務咨詢

· 技術支持
· 服務時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權所有 鄂ICP備17013400號