內部邀請碼: C8E245J (不寫邀請碼,沒有現金送)
國內私募機構九鼎控股打造,九鼎投資是在全國股份轉讓系統掛牌的公眾公司,股票代碼為430719,為“中國PE第一股”,市值超1000億元。
以下文章大部分參考 http://zxs19861202.iteye.com/blog/890965 的內容,按照文章中制作后,補充了部分細節,形成了此片文章。
文章中 CAS 基礎環境:
cas-server-3.5.2
cas-client-3.2.1
----------------------------------------------------------------------------------------------------------------------------------------
服務器端配置
----------------------------------------------------------------------------------------------------------------------------------------
程序中也可能遇到需要得到更多如姓名,手機號,email等更多用戶信息的情況。
cas 各種版本配置方式也不盡相同,這里講的是目前最新版本3.4.4(同樣適合 3.5.2 版本)。配置方式如下,
一、首先需要配置屬性attributeRepository,首先,你需要到WEB-INF目錄找到
deployerConfigContext.xml文件,同時配置 attributeRepository 如下:
<bean class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao" id="attributeRepository">
<constructor-arg index="0" ref="casDataSource"/>
<constructor-arg index="1" value="select * from userinfo where {0}"/>
<property name="queryAttributeMapping">
<map>
<entry key="username" value="loginname"/> // 這里的key需寫username,value對應數據庫用戶名字段
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="id" value="id"/>
<entry key="mobile" value="mobile"/>
<entry key="email" value="email"/>
</map>
</property>
</bean>
其中:
queryAttributeMapping 是組裝sql用的查詢條件屬性,上述配置后,結合封裝成查詢sql就是 select * from userinfo where loginname=#username#
resultAttributeMapping 是sql執行完畢后返回的結構屬性, key對應數據庫字段,value對應客戶端獲取參數。
二、配置用戶認證憑據轉化的解析器
也是在 deployerConfigContext.xml 中,找到 credentialsToPrincipalResolvers,為 UsernamePasswordCredentialsToPrincipalResolver 注入 attributeRepository,那么 attributeRepository 就會被觸發並通過此類進行解析,紅色為新添部分。
<property name="credentialsToPrincipalResolvers">
<list>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
<bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver"/>
</list>
</property>
三、(在 CAS Server 3.5.2 中測試通過)修改 deployerConfigContext.xml 中的 org.jasig.cas.services.InMemoryServiceRegistryDaoImpl 的 屬性 registeredServices
修改 registeredServices 列表中的每個協議中的 allowedAttributes 屬性的值,列出的每個值,在客戶端就可以訪問了
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegexRegisteredService">
<property name="id" value="0" />
<property name="name" value="HTTP and IMAP" />
<property name="description" value="Allows HTTP(S) and IMAP(S) protocols" />
<property name="serviceId" value="^(https?|imaps?)://.*" />
<property name="evaluationOrder" value="10000001" />
<property name="allowedAttributes"> // 客戶端需要使用的對象的屬性名稱
<list>
<value>uid</value>
<value>email</value>
<value>mobile</value>
<value>phone</value>
<value>sex</value>
<value>identify_type</value>
<value>identify_id</value>
<value>birth</value>
<value>fax</value>
<value>isMarry</value>
<value>userno</value>
<value>login_account</value>
</list>
</property>
</bean>
此步驟灰常重要,可以看看 org.jasig.cas.services.RegexRegisteredService 的源碼,其中的 allowedAttributes 是關鍵
【提示】網上說 ignoreAttributes 屬性控制,查看了 CAS 3.5.2 版本的 AbstractRegisteredService 源碼后,發現其默認值就是 false,即:添加屬性后,客戶端就可見了
四、(按照上述配置后,萬里長征就差最后一步了)修改 WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp
在server驗證成功后,這個頁面負責生成與客戶端交互的xml信息,在默認的casServiceValidationSuccess.jsp中,只包括用戶名,並不提供其他的屬性信息,因此需要對頁面進行擴展,如下,紅色為新添加部分
<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="${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}">
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>
</c:forEach>
</cas:attributes>
</c:if>
<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>
</cas:authenticationSuccess>
</cas:serviceResponse>
通過完成上面四個步驟的配置后,server端的工作就完成了,那么如何在客戶端獲取這些信息呢?下面進行說明:
----------------------------------------------------------------------------------------------------------------------------------------
客戶端獲取用戶信息
----------------------------------------------------------------------------------------------------------------------------------------
java客戶端獲取用戶信息:
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
Map attributes = principal.getAttributes();
String email=attributes .get("email");
php客戶端;
$email=phpCAS::getAttribute('email');