CAS扩展——自定义加密算法

时间:2022-03-25 09:48:19

问题由来

    用于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>

    这样自定义加密算法的实现就完成了。