问题:在第三章中,我们配置了cas的数据库验证方式,但是QueryDatabaseAuthenticationHandler 只支持单个条件查询,如
修改为
select password from user where user_account=?,只能按照某一字段查询,但是实际应用时一般可以使用账号、email、手机号皆可登录。而返回到客户端的数据则是你登录时输入的账号,实际应用可能需要返回更多数据。所以本章为大家讲解如何采用多条件查询,以及返回更多的数据列(单条数据,多列)。
我们先看源码
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 QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull
private String sql;
protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException {
final String username = getPrincipalNameTransformer().transform(credentials.getUsername());
final String password = credentials.getPassword();
final String encryptedPassword = this.getPasswordEncoder().encode(
password);
try {
<span style="color:#ff0000;">final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
return dbPassword.equals(encryptedPassword);
} catch (final IncorrectResultSizeDataAccessException e) {
// this means the username was not found.
return false;
}
}
/**
* @param sql The sql to set.
*/
public void setSql(final String sql) {
this.sql = sql;
}
}
大家可以看到,在getJdbcTemplate().queryForObject(this.sql, String.class, username); 用过spring-jdbc-template的同学都知道,这里面只设置了一个username参数,所以只能单条件查询,所以我们需要改造这个方法,创建一个我们自己的查询类
package org.jasig.cas.handler;
import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import javax.validation.constraints.NotNull;
/**
* 名称:org.jasig.cas.handler
* 描述:<br> 多条件查询
* 类型:JAVA<br>
* 最近修改时间:22/12/2014 19:01<br>
*
* @author Jack Chan
* @since 22/12/2014
*/
public class MultiQueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull
private String sql;
protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException {
final String username = getPrincipalNameTransformer().transform(credentials.getUsername());
final String password = credentials.getPassword();
final String encryptedPassword = this.getPasswordEncoder().encode(
password);
try {
//这里username个数对应我们的查询条件个数,只需要改这一处地方
<span style="color:#ff0000;">final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username, username, username);
return dbPassword.equals(encryptedPassword);
} catch (final IncorrectResultSizeDataAccessException e) {
// this means the username was not found.
return false;
}
}
/**
* @param sql The sql to set.
*/
public void setSql(final String sql) {
this.sql = sql;
}
}
然后修改deployerConfigContext.xml的
<property name="authenticationHandlers">
<list>
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" />
<!-- 数据库查询认证处理器 -->
<span style="color:#ff0000;"><bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="mysqlDataSource"/>
<property name="sql"
value="select password from user where user_account=? "/>
<property name="passwordEncoder" ref="myPasswordEncoder"></property>
</bean>
</list>
</property>
修改为