cas配置全攻略(轉)


轉:http://www.blogjava.net/tufanshu/archive/2011/01/21/343290.html

經過將近兩天的測試,參考眾多網友的貢獻,終於完成了對cas的主要配置和測試,現記錄如下

基本需求:

1.cas server-3.4.5,casclient-3.2(官方版本),均可在cas官方網站下載,http://www.jasig.org

2.使用低成本的http協議進行傳輸,俺買不起ssl證書

3.通過jdbc進行用戶驗證

4.需要通過casserver提供除登錄用戶名以外的附加信息

參考資料:

1.cas官方網站的用戶幫助手冊和wiki

2.網友“城市獵人”的blog,http://yuzhwe.javaeye.com/blog/830143

3.網友“悟空悟道”的blog,http://llhdf.javaeye.com/blog/764385

4.其他網友貢獻的相關的blog,都是通過google出來,就不一一列出了,一並致謝!!!

好了,下面進入正題,如果您不想測試中出現異常情況,或是獲取不到相關數據,請關注文中的紅色字體部分。

(1)使用http協議的設置,如果您也像我一樣,買不起ssl數字證書,對安全的要求也不是特別的搞,下面的配置就可以幫助解決這個問題:

在cas-server-webapp中的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml文件中有如下配置

<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
  p:cookieSecure="true"     //默認為true,使用https,如果只需要http,修改為false即可
  p:cookieMaxAge="-1"
  p:cookieName="CASTGC"
  p:cookiePath="/cas" />

 (2)使用jdbc數據源進行用戶認證,需要修改cas的authenticationHandlers方式,在文件/WEB-INF/deployerConfigContext.xml有如下配置:

<property name="authenticationHandlers">
   <list>
    <!--
     | This is the authentication handler that authenticates services by means of callback via SSL, thereby validating
     | a server side SSL certificate.
     +-->
    <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
     p:httpClient-ref="httpClient" />
    <!--
     | This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS 
     | into production.  The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials
     | where the username equals the password.  You will need to replace this with an AuthenticationHandler that implements your
     | local authentication strategy.  You might accomplish this by coding a new such handler and declaring
     | edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules.
     +-->
    <!--<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />-->
     <bean  class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
         <property name="dataSource" ref="dataSource" />
        <property name="sql" value="select password from userInfo where username=? and enabled=true" />
         //用戶密碼編碼方式
         <property name="passwordEncoder"
           ref="passwordEncoderBean"/>
         </bean>  
   </list>
  </property>

該屬性中的list只要用一個認證通過即可,建議將紅色部分放在第一位,如果確認只用jdbc一種方式,其他認證方式均可刪除。另外需要在在文件中添加datasoure和passordEncoder兩個bean,如下

<!-- Data source definition -->
 <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://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8</value>    //如果使用mysql數據庫,應該加上后面的編碼參數,否則可能導致客戶端對TGT票據無法識別的問題
  </property>
  <property name="username"><value>root</value></property>
  <property name="password"><value>password</value></property>
 </bean>
 <bean id="passwordEncoderBean" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
        <constructor-arg value="SHA1" />  //cas 
server默認支持MD5和SHA1兩種編碼方式,如果需要其他的編碼方式例如SHA256,512等,可自行實現org.jasig.cas.authentication.handler.PasswordEncoder接口
    </bean>

附加備注:如果您是使用cas server的源碼自行編譯的話,需要在cas-server-web模塊的pom.xml中添加如下模塊的依賴:

<dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>cas-server-support-jdbc</artifactId>
       <version>${project.version}</version>
  </dependency>  

並添加對應數據庫的jdbc的jar包。

(3)讓cas server提供更多的用戶數據共客戶端使用

通過測試,由於cas的代碼更新過程中的變化較大,所以包兼容的問題好像一直存在,在測試中我就碰到過,花費時間比較多,建議同學們在使用過程中使用官方的最新的發布版本。在我使用的這個版本中,請參考前面的關於server和client端的版本說明,應該沒有包沖突的問題,測試通過。下面進行配置,配置文件:/WEB-INF/deployerConfigContext.xml
<property name="credentialsToPrincipalResolvers">
   <list>
       <!--<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />-->
    <!-- modify on 2011-01-18,add user info -->
    <bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" > 
      <property name="attributeRepository" >   //為認證過的用戶的Principal添加屬性
      <ref local="attributeRepository"/>
     </property> 
    </bean>
      <bean
     class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
   </list>
  </property>
 修改該文件中默認的 attributeRepositorybean配置
<!-- 在這里配置獲取更多用戶的信息 -->
 <bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
  <constructor-arg index="0" ref="dataSource" />
  <constructor-arg index="1" value="select id as UId, password_hint as ph from userInfo where username=? and enabled=true" />
  <property name="queryAttributeMapping">
   <map>
   <entry key="username" value="uid"/><!-- 這里必須這么寫,系統會自己匹配,貌似和where語句后面的用戶名字段的拼寫沒有什么關系 -->
   </map>
  </property>
   <!-- 要獲取的屬性在這里配置 -->
  <property name="resultAttributeMapping">
   <map>
   <entry key="UId" value="userId" /> //key為對應的數據庫字段名稱,value為提供給客戶端獲取的屬性名字,系統會自動填充值
   <entry key="ph" value="passwordHint" />   
   </map>
  </property>
</bean> 
備注:網上有很多的關於這個的配置,但是如果您使用的是我提供的版本或是高於這個版本,就應該象上面這樣配置,無用質疑,網上大部分的配置都是基於
person-directory-impl,person-directory-api 
1.1左右的版本,而最新的cas使用的是1.5的版本,經過查看源代碼和api docs確定最新版本的屬性參數如上配置。

修改該xml文件中最后一個默認的serviceRegistryDao bean中的屬性全部注釋掉,或者刪除,
這個bean中的RegisteredServiceImpl的ignoreAttributes屬性將決定是否添加attributes屬性內容,默認為false:不添加,只有去掉這個配置,
cas server才會將獲取的用戶的附加屬性添加到認證用的Principal的attributes中去,我在這里犯過這樣的錯誤,最后還是通過跟蹤源碼才發現的。
<bean
  id="serviceRegistryDao"
        class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
        <!--
            <property name="registeredServices">
                <list>
                    <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                        <property name="id" value="0" />
                        <property name="name" value="HTTP" />
                        <property name="description" value="Only Allows HTTP Urls" />
                        <property name="serviceId" value="http://**" />
                    </bean>

                    <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                        <property name="id" value="1" />
                        <property name="name" value="HTTPS" />
                        <property name="description" value="Only Allows HTTPS Urls" />
                        <property name="serviceId" value="https://**" />
                    </bean>

                    <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                        <property name="id" value="2" />
                        <property name="name" value="IMAPS" />
                        <property name="description" value="Only Allows HTTPS Urls" />
                        <property name="serviceId" value="imaps://**" />
                    </bean>

                    <bean class="org.jasig.cas.services.RegisteredServiceImpl">
                        <property name="id" value="3" />
                        <property name="name" value="IMAP" />
                        <property name="description" value="Only Allows IMAP Urls" />
                        <property name="serviceId" value="imap://**" />
                    </bean>
                </list>
            </property>-->
           </bean>

 修改WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp文件,如下:

<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
 <cas:authenticationSuccess>
  <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user>
  <c:if test="${not empty pgtIou}">
   <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>
  </c:if>
  <c:if test="${fn:length(assertion.chainedAuthentications) > 1}">
   <cas:proxies>
    <c:forEach var="proxy" items="${assertion.chainedAuthentications}"
     varStatus="loopStatus" begin="0"
     end="${fn:length(assertion.chainedAuthentications)-2}" step="1">
     <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy>
    </c:forEach>
   </cas:proxies>
  </c:if>
   <c:if
   test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)


0}">
   <cas:attributes>
    <c:forEach 
var="attr"
     items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"
     varStatus="loopStatus" 
begin="0"
     end="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)-1}"
     step="1">
     <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
    </c:forEach>
   </cas:attributes>
  </c:if>
 </cas:authenticationSuccess>
</cas:serviceResponse>
客戶端配置:
1.過濾器CAS Validation Filter:
<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>http://domainserver:8081/cas</param-value>
  </init-param>
</filter>
在客戶端獲取信息
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
String loginName = principal.getName();//獲取用戶名
Map<String, Object> attributes = principal.getAttributes();
if(attributes != null) {
 System.out.println(attributes.get("userId"));
 System.out.println(attributes.get("passwordHint")); 
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM