2019独角兽企业重金招聘Python工程师标准>>>
在cas-server 原始项目中,只提供了用户名及密码的验证
绑定的参数在login-webflow.xml如下:
验证类如下:org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler
需求: 对于用户的验证,可能我们不止只有username及password这两个。而验证的逻辑也可能很复杂。
此时就想绑定多个参数,及有自己的验证类。
实现:
1.参数的获取与绑定
参数的绑定在login-webflow.xml 中,如我们想绑定一个用户类型的参数usertype
最后参数会封装到一个叫org.jasig.cas.authentication.Credential 的类中,原项目中为org.jasig.cas.authentication.UsernamePasswordCredential
这里我们要定义自己Credential的如下:
import org.jasig.cas.authentication.UsernamePasswordCredential;
public class MyCredential extends UsernamePasswordCredential {
private static final long serialVersionUID = -7786406837239789068L;
private String usertype; //用户类型
public String getUsertype() {
return usertype;
}
public void setUsertype(String usertype) {
this.usertype = usertype;
}
}
修改login-webflow.xml 如下:
这样参数usertype就会自动封装致该类中了
2. 自定义验证逻辑
创建自己的验证类如:
import java.security.GeneralSecurityException;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.validation.constraints.NotNull;
import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
public class MyAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull
private String sql;
/** {@inheritDoc} */
@Override
protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
throws GeneralSecurityException, PreventedException {
MyCredential myCredential = null;
if(MyCredential.class.isInstance(credential)){
myCredential = (MyCredential) credential;
}else{
throw new IllegalAccessError("验证参数不匹配");
}
final String username = myCredential.getUsername();
final String encryptedPassword = this.getPasswordEncoder().encode(myCredential.getPassword());
try {
final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
if (!dbPassword.equals(encryptedPassword)) {
throw new FailedLoginException("Password does not match value on record.");
}
} catch (final IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() == 0) {
throw new AccountNotFoundException(username + " not found with SQL query");
} else {
throw new FailedLoginException("Multiple records found for " + username);
}
} catch (final DataAccessException e) {
throw new PreventedException("SQL exception while executing query for " + username, e);
}
return createHandlerResult(myCredential, new SimplePrincipal(username), null);
}
/**
* @param sql The sql to set.
*/
public void setSql(final String sql) {
this.sql = sql;
}
}
为了测试方便,复制了原有的验证逻辑。但可以看到,此时的UsernamePasswordCredential 参数实际上是我们自己定义的Credential
修改deployerConfigContext.xml,中authenticationManager bean的内容,用此类替换原有的类即可