问题由来
用于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>
这样自定义加密算法的实现就完成了。