問題由來
用於CAS系統登錄的密碼默認提供MD5和SHA加密的算法支持,但有時由於業務需要,以上兩種算法都不能提供足夠的支持,這時我們就需要自定義加密算法。比如筆者遇到的一個項目,密碼的加密方式,是將密碼MD5加密后再拼接數據庫中一個鹽值然后再MD5二次加密,這樣的需求條件就必須對加密算法進行擴展。
解決方案
CAS支持的加密方式(MD5/SHA)配置方法:
在tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml先找到:
1: <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
修改為:
1: <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
2: <property name="dataSource" ref="dataSource"></property>
3: <property name="sql" value="select password from user where id=?"></property>
4: <property name="passwordEncoder" ref="MD5PasswordEncoder"></property>
5: </bean>
QueryDatabaseAuthenticationHandler是cas-server-support-jdbc提供的查詢接口其中一個是通過配置一個 SQL 語句查出密碼,與所給密碼匹配;dataSource是使用JDBC查詢時的數據源;sql語句的用意是把符合該ID的用戶密碼取出來,cas會用它與用戶輸入的密碼進行比對。passwordEncoder是加密算法,表示將用戶輸入的密碼以何種方式進行加密,然后CAS會將此加密結果與數據庫中取出來的密碼進行比對。
最后在tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml末尾配置:
1: <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
2: <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
3: <property name="url"><value>jdbc:oracle:thin:@192.168.2.233:1521:ora11g</value></property>
4: <property name="username"><value>username</value></property>
5: <property name="password"><value>password</value></property>
6: </bean>
7:
8: <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
9: <constructor-arg index="0">
10: <value>MD5</value>
11: </constructor-arg>
12: </bean
至此支持MD5加密的CAS登錄配置就完成了。
從上面分析我們可以看到,加密算法的配置是在:
1: <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
2: <constructor-arg index="0">
3: <value>MD5</value>
4: </constructor-arg>
5: </bean>
也就是說我們只需要自定義一個加密類,將它裝配進來就可以了,於是我們新建一個類(注意此類應該實現CAS的PasswordEncoder接口):
1: public class UCPasswordEncoder implements PasswordEncoder {
2: private String salt;
3:
4: /**
5: * @return the salt
6: */
7: public String getSalt() {
8: return salt;
9: }
10:
11: /**
12: * @param salt
13: * the salt to set
14: */
15: public void setSalt(String salt) {
16: this.salt = salt;
17: }
18:
19: public String encode(final String password) {
20: return EncryptUtil.getMD5Str(EncryptUtil.getMD5Str(password) + salt);
21: }
22:
23: }
當中的salt是從數據庫中取出來的一個鹽值,該值會在另一個自定義的數據庫驗證類中取到並傳遞給UCPasswordEncoder,在此不再闡述。
EncryptUtil.getMD5Str(EncryptUtil.getMD5Str(password) + salt),也就是筆者項目要使用的加密算法(MD5結果+鹽值,再MD5加密)。
最后修改tomcat/webapp/cas/WEB-INF/deployerConfigContext.xml加密算法的配置:
1: <bean id="passwordEncoder"
2: class="com.cnblogs.leefreeman.sso.UCPasswordEncoder"
3: autowire="byName">
4: </bean>
這樣自定義加密算法的實現就完成了。