- 第一部分:安裝配置 Tomcat
- 第二部分:安裝配置 CAS
- 第三部分:實現 ASP.NET WebForm Client
- 第四部分:實現基於資料庫的身份驗證
第五部分:擴充套件基於資料庫的身份驗證
1. 應用場景
前面提到的基於資料庫的集中身份驗證主要是通過使用者名稱、密碼的方式完成驗證操作,然而在實際使用過程中,使用者可能需要多種形式的認證手段,除了使用者名稱密碼的方式外,還可能通過郵箱或手機號登入,但不管使用何種方式登入,都對應同一使用者。下圖演示了淘寶網在登入時允許使用者以“手機號/會員名/郵箱”三種方式登入系統。
2. 資料庫設計
針對上述需求,重新設計資料庫欄位,如下圖所示:
輸入測試用資料,如下圖所示:
3. 自定義資料庫驗證Handler
關於自定義資料庫驗證Handler的文章比較多,我主要參考了《CAS擴充套件——自定義查詢資料庫驗證Handler》和《CAS重新實現登陸認證邏輯》。但是這兩篇文章介紹的相對較糙,對於不瞭解Java的人來說實施起來著實有點困難,所以在這裡我將兩人的東西綜合一下並給出詳盡的操作流程供參考。
說明:大家可以從解壓縮的“cas-server-3.5.1\cas-server-support-jdbc\src”資料夾下找到“QueryDatabaseAuthenticationHandler.java”的原始碼以及其它相關原始碼供參考。
(1)安裝Eclipse。Eclipse是非常常用的一種Java編輯器。為了完成元件編寫,我們首先需要安裝Eclipse。Eclipse的下載與安裝非常簡單,在這裡就不再贅述。
(2)啟動Eclipse,選擇“File/New/Java Project”,開啟新建專案對話方塊,在“Project Name”文字框中輸入“MultiCriteriaQueryDatabaseAuthenticationHandler”,單擊“Finish”按鈕。如下圖所示:
(3)在“Package Explorer”中右擊專案“MultiCriteriaQueryDatabaseAuthenticationHandler”,選擇“New/Folder”,在彈出的對話方塊中輸入“lib”並單擊“Finishe”按鈕。
(4)從解壓縮的“cas-server-3.5.1\modules”資料夾中找到“cas-server-core-3.5.1.jar”與“cas-server-support-jdbc-3.5.1.jar”兩個檔案,將其拷貝到新建的“lib”資料夾下。
(5)從網上搜索並下載“spring.jar”與“javax.validation-1.0.0.GA.jar”兩個檔案,也將其拷貝到新建的“lib”資料夾。重新整理後的專案如下圖所示:
(6)在“Package Explorer”中右擊專案“MultiCriteriaQueryDatabaseAuthenticationHandler”,選擇“Build Path/Add External Archives...”,依次將剛才拷貝到lib資料夾下的四個jar檔案新增至專案的“Reference Libraries”中。完成後的介面如下圖所示:
(7)在“src”資料夾上右擊,選擇“New/Class”,彈出新建Java類對話方塊。在Package文字框中輸入“org.jasig.cas.adaptors.jdbc”,在Name文字框中輸入“MultiCriteriaQueryDatabaseAuthenticationHandler”,單擊“Finish”按鈕。
(8)用下面的程式碼替換“MultiCriteriaQueryDatabaseAuthenticationHandler.java”檔案中的現有程式碼,單擊儲存按鈕儲存修改。

package org.jasig.cas.adaptors.jdbc; import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.dao.IncorrectResultSizeDataAccessException; import javax.validation.constraints.NotNull; public class MultiCriteriaQueryDatabaseAuthenticationHandler extends
AbstractJdbcUsernamePasswordAuthenticationHandler { @NotNull
private String getPwdSql; @NotNull
private String getUsernameSql; protected final boolean authenticateUsernamePasswordInternal(
UsernamePasswordCredentials credentials)
throws AuthenticationException {
final String id = getPrincipalNameTransformer().transform(
credentials.getUsername());
final String password = credentials.getPassword();
final String encryptedPassword = this.getPasswordEncoder().encode(
password); try {
String dbPassword = getJdbcTemplate().queryForObject(
this.getPwdSql, String.class, new Object[] { id, id, id }); String username = getJdbcTemplate().queryForObject(
this.getUsernameSql, String.class,
new Object[] { id, id, id }); credentials.setUsername(username);
return dbPassword.equals(encryptedPassword);
} catch (final IncorrectResultSizeDataAccessException e) {
// this means the username was not found.
return false;
}
} public void setGetPwdSql(final String getPwdSql) {
this.getPwdSql = getPwdSql;
} public void setGetUsernameSql(final String getUsernameSql) {
this.getUsernameSql = getUsernameSql;
}
}

(9)在“Package Explorer”中右擊專案“MultiCriteriaQueryDatabaseAuthenticationHandler”,選擇“Export...”開啟Export對話方塊。
(10)在“Export”對話方塊中選擇“JAR file”,單擊“Next”按鈕。
(11)在JAR檔案設定對話方塊中,去掉“lib”資料夾前面的對勾,同時去掉“.classpath”和“.project”前面的對勾,選擇JAR檔案的儲存路徑到桌面,單擊“Finish”按鈕。如下圖所示:
(12)將桌面上生成的“MultiCriteriaQueryDatabaseAuthenticationHandler.jar”檔案拷貝至“%TOMCAT_HOME%\webapps\cas\WEB-INF\lib”資料夾下。
(13)以管理員身份啟動文字編輯器,開啟“%TOMCAT_HOME%\webapps\cas\WEB-INF\deployerConfigContext.xml”。找到下面的程式碼(這段程式碼是上篇博文中我們新增進去的):
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="sql" value="select Password from users where username=?" />
<property name="dataSource" ref="dataSource" />
</bean>
(14)將上面這段程式碼註釋掉,並在其下插入如下配置資訊並儲存:
<bean class="org.jasig.cas.adaptors.jdbc.MultiCriteriaQueryDatabaseAuthenticationHandler">
<property name="getPwdSql" value="select password from users where username=? or email=? or mobile=?" />
<property name="getUsernameSql" value="select username from users where username=? or email=? or mobile=?" />
<property name="dataSource" ref="dataSource" />
</bean>
(15)重新啟動Tomcat服務。
4.測試自定義資料庫身份驗證Handler
從客戶端執行前面除錯好的WebForm程式(請參考:Yale CAS + .net Client 實現 SSO(3)),輸入使用者名稱“admin”或“[email protected]”或“12345678901”、密碼“123”,測試是否登入成功。可以看到,不管使用者使用郵件還是手機號登入,客戶端始終顯示使用者名稱,而非郵箱和手機號。這是因為在MultiCriteriaQueryDatabaseAuthenticationHandler.java程式碼中如下程式碼所決定的:
String username = getJdbcTemplate().queryForObject(
this.getUsernameSql, String.class,
new Object[] { id, id, id }); credentials.setUsername(username);
登入後的使用者介面如下圖所示: