1. 程式人生 > >CAS服務端返回更多的使用者登入資訊

CAS服務端返回更多的使用者登入資訊

cas server登入成功後,預設只能從cas server得到使用者名稱。但程式中也可能遇到需要得到更多如姓名,手機號,email等更多使用者資訊的情況。cas client拿到使用者名稱後再到資料庫中查詢,的確可以得到關於該使用者的更多資訊。但是如果使用者登入成功後,直接從cas server返回給cas client使用者的詳細資訊,這也是一個不錯的做法。這個好處,尤其是在分散式中得以彰顯,cas server可以把使用者資訊傳遞給各個應用系統,如果是上面那種做法,那麼各個系統得到使用者名稱後,都得去資料庫中查詢一遍,無疑是一件重複性工作。

1、首先需要配置屬性attributeRepository

WEB-INF目錄找到 deployerConfigContext.xml檔案,同時配置 attributeRepository如下:

<beanclass="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"id="attributeRepository">

<constructor-argindex="0"ref="dataSource"/>

<constructor-argindex="1"value="select * from t_user where {0}"

/>

<propertyname="queryAttributeMapping">

<map>

<!--這裡的key需寫username和登入頁面一致,value對應資料庫使用者名稱欄位-->

<entrykey="username"value="loginname"/>

</map>

</property>

<propertyname="resultAttributeMapping">

<map>

<!--key為對應的資料庫欄位名稱,value為提供給客戶端獲取的屬性名字,系統會自動填充值-->

<entrykey="suid"value="suid"/>

</map>

</property>

<!--   

   <property name="queryType"> 

       <value>OR</value> 

   </property>  

   -->

</bean>

切記:查詢出來的欄位名中間不能使用 _ (下劃線),否則獲取不到資料,如 cell_phone需要設定別名為 cellPhone.queryAttributeMapping是組裝sql用的查詢條件屬性,上述配置後,結合封裝成查詢sql就是 
select* from userinfo where loginname=#username#resultAttributeMapping
sql執行完畢後返回的結構屬性, key對應資料庫欄位,value對應客戶端獲取引數。如果要組裝多個查詢條件,需要加上下面這個,預設為AND.

<propertyname="queryType">

<value>OR</value>

</property>

2、修改serviceRegistryDao

deployerConfigContext.xml中的 beansidserviceRegistryDao的屬性 registeredServicesList。在 registeredServicesList中新增allowedAttributes屬性的值。列出的每個值,在客戶端就可以訪問了。

<util:listid="registeredServicesList">

<beanclass="org.jasig.cas.services.RegexRegisteredService"

p:id="0"p:name="HTTP andIMAP"p:description="Allows HTTP(S) and IMAP(S) protocols"

p:serviceId="^(http?|https?|imaps?)://.*"p:evaluationOrder="10000001">

<!--新增該屬性allowedAttributes -->

<propertyname="allowedAttributes">

<list>

<value>suid</value>

</list>

</property>

<!-- ignoreAttributestrue表示配置的 resultAttributeMapping 會返回--> 

      <propertyname="ignoreAttributes" value="true" />

</bean>

此步驟非常重要,可以看看org.jasig.cas.services.RegexRegisteredService的原始碼,其中的allowedAttributes是關鍵。

如果獲取不到屬性,則需要新增如下屬性值:

<!-- ignoreAttributestrue表示配置的 resultAttributeMapping會返回--> 

<propertyname="ignoreAttributes" value="true" /> 

3、修改casServiceValidationSuccess.jsp

WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp.server驗證成功後,這個頁面負責生成與客戶端互動的xml資訊,在預設的casServiceValidationSuccess.jsp中,只包括使用者名稱,並不提供其他的屬性資訊,因此需要對頁面進行擴充套件。如下:

<cas:serviceResponsexmlns: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:iftest="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)> 0}">

<cas:attributes>

<c:forEachvar="attr"items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">

<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>

</c:forEach>

</cas:attributes>

</c:if>

<c:iftest="${notempty pgtIou}">

<cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket>

</c:if>

<c:iftest="${fn:length(assertion.chainedAuthentications)> 1}">

<cas:proxies>

<c:forEachvar="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>

</cas:authenticationSuccess>

</cas:serviceResponse>

4CAS Client獲取使用者資訊

AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal(); 
Map attributes = principal.getAttributes(); 
String email = attributes.get(“suid”);