CAS4.2.4 连接Liferay6.2以上版本数据库用户表验证用户
Liferay6.2以上版本密码验证方式跟6.1以前有所变化,以前只是密码根据加密方式(比如SHA)就可以了,现在有新的加密方式(PBKDF2WITHHMACSHA1/160/128000),相同的密码同样的方式生成的密码密文是不相同的,但是使用旧的密文可以生产相同的密文,密码处理方式如下:
CompositePasswordEncryptor compositePasswordEncryptor =
new CompositePasswordEncryptor();
compositePasswordEncryptor.setDefaultPasswordEncryptor(
new DefaultPasswordEncryptor());
List<PasswordEncryptor> passwordEncryptors =
new ArrayList<PasswordEncryptor>();
passwordEncryptors.add(new BCryptPasswordEncryptor());
passwordEncryptors.add(new CryptPasswordEncryptor());
passwordEncryptors.add(new NullPasswordEncryptor());
passwordEncryptors.add(new PBKDF2PasswordEncryptor());
passwordEncryptors.add(new SSHAPasswordEncryptor());
compositePasswordEncryptor.setPasswordEncryptors(passwordEncryptors);
System.out.println(compositePasswordEncryptor.encrypt("PBKDF2WITHHMACSHA1/160/128000", "xifeng1010", "AAAAoAAB9ADcSisqHgHopVQvVwPMeJW+bHxk7qvsGxkYUxqc"));;
基于此处密码验证修改CAS验证方式,每个CAS版本不相同修改的类内容是不同的,注意找到CAS版本对应的类进行修改。
下载并编译CAS4.2.4,修改QueryDatabaseAuthenticationHandler代码如下
package org.jasig.cas.adaptors.jdbc;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.stereotype.Component;
import com.liferay.portal.PwdEncryptorException;
import com.liferay.portal.security.pwd.BCryptPasswordEncryptor;
import com.liferay.portal.security.pwd.CompositePasswordEncryptor;
import com.liferay.portal.security.pwd.CryptPasswordEncryptor;
import com.liferay.portal.security.pwd.DefaultPasswordEncryptor;
import com.liferay.portal.security.pwd.NullPasswordEncryptor;
import com.liferay.portal.security.pwd.PBKDF2PasswordEncryptor;
import com.liferay.portal.security.pwd.PasswordEncryptor;
import com.liferay.portal.security.pwd.SSHAPasswordEncryptor;
/**
* Class that if provided a query that returns a password (parameter of query
* must be username) will compare that password to a translated version of the
* password provided by the user. If they match, then authentication succeeds.
* Default password translator is plaintext translator.
*
* @author Scott Battaglia
* @author Dmitriy Kopylenko
* @author Marvin S. Addison
*
* @since 3.0.0
*/
@Component("queryDatabaseAuthenticationHandler")
public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
private static CompositePasswordEncryptor compositePasswordEncryptor = new CompositePasswordEncryptor();
public QueryDatabaseAuthenticationHandler() {
super();
compositePasswordEncryptor.setDefaultPasswordEncryptor(new DefaultPasswordEncryptor());
List<PasswordEncryptor> passwordEncryptors = new ArrayList<PasswordEncryptor>();
passwordEncryptors.add(new BCryptPasswordEncryptor());
passwordEncryptors.add(new CryptPasswordEncryptor());
passwordEncryptors.add(new NullPasswordEncryptor());
passwordEncryptors.add(new PBKDF2PasswordEncryptor());
passwordEncryptors.add(new SSHAPasswordEncryptor());
compositePasswordEncryptor.setPasswordEncryptors(passwordEncryptors);
}
@NotNull
private String sql;
@Override
protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
throws GeneralSecurityException, PreventedException {
if (StringUtils.isBlank(this.sql) || getJdbcTemplate() == null) {
throw new GeneralSecurityException("Authentication handler is not configured correctly");
}
final String username = credential.getUsername();
// final String encryptedPassword =
// this.getPasswordEncoder().encode(credential.getPassword());
try {
final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
final String encryptedPassword = compositePasswordEncryptor.encrypt("PBKDF2WITHHMACSHA1/160/128000",
credential.getPassword(), dbPassword);
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);
} catch (PwdEncryptorException e) {
throw new FailedLoginException("old password error");
}
return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
}
/**
* @param sql
* The sql to set.
*/
@Autowired
public void setSql(@Value("${cas.jdbc.authn.query.sql:}") final String sql) {
this.sql = sql;
}
@Override
@Autowired(required = false)
public void setDataSource(@Qualifier("queryDatabaseDataSource") final DataSource dataSource) {
super.setDataSource(dataSource);
}
}
编译此类并复制到classes目录下
修改\cas\WEB-INF 目录下的deployerConfigContext.xml文件
1,注释掉32行
<!--<alias name="acceptUsersAuthenticationHandler" alias="primaryAuthenticationHandler" />-->
2,添加对应的QueryDatabaseAuthenticationHandler的bean
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://192.168.3.172:3306/lportal?characterEncoding=utf-8&autoReconnect=true" />
<property name="username" value="portal" />
<property name="password" value="Portal10!" />
</bean>
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:sql="select password_ from User_ where screenName=?" />
完整代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<util:map id="authenticationHandlersResolvers">
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
</util:map>
<util:list id="authenticationMetadataPopulators">
<ref bean="successfulHandlerMetaDataPopulator" />
<ref bean="rememberMeAuthenticationMetaDataPopulator" />
</util:list>
<bean id="attributeRepository" class="org.jasig.services.persondir.support.NamedStubPersonAttributeDao"
p:backingMap-ref="attrRepoBackingMap" />
<!--<alias name="acceptUsersAuthenticationHandler" alias="primaryAuthenticationHandler" />-->
<alias name="personDirectoryPrincipalResolver" alias="primaryPrincipalResolver" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://192.168.3.172:3306/lportal?characterEncoding=utf-8&autoReconnect=true" />
<property name="username" value="portal" />
<property name="password" value="Portal10!" />
</bean>
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:sql="select password_ from User_ where screenName=?" />
<util:map id="attrRepoBackingMap">
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
<entry>
<key><value>memberOf</value></key>
<list>
<value>faculty</value>
<value>staff</value>
<value>org</value>
</list>
</entry>
</util:map>
<alias name="serviceThemeResolver" alias="themeResolver" />
<alias name="jsonServiceRegistryDao" alias="serviceRegistryDao" />
<alias name="defaultTicketRegistry" alias="ticketRegistry" />
<alias name="ticketGrantingTicketExpirationPolicy" alias="grantingTicketExpirationPolicy" />
<alias name="multiTimeUseOrTimeoutExpirationPolicy" alias="serviceTicketExpirationPolicy" />
<alias name="anyAuthenticationPolicy" alias="authenticationPolicy" />
<alias name="acceptAnyAuthenticationPolicyFactory" alias="authenticationPolicyFactory" />
<bean id="auditTrailManager"
class="org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager"
p:entrySeparator="${cas.audit.singleline.separator:|}"
p:useSingleLine="${cas.audit.singleline:false}"/>
<alias name="neverThrottle" alias="authenticationThrottle" />
<util:list id="monitorsList">
<ref bean="memoryMonitor" />
<ref bean="sessionMonitor" />
</util:list>
<alias name="defaultPrincipalFactory" alias="principalFactory" />
<alias name="defaultAuthenticationTransactionManager" alias="authenticationTransactionManager" />
<alias name="defaultPrincipalElectionStrategy" alias="principalElectionStrategy" />
<alias name="tgcCipherExecutor" alias="defaultCookieCipherExecutor" />
</beans>
缺少几个jar包,添加到lib目录下:
portal-impl-6.2.5.jar
portal-service-6.2.5.jar
cas-server-support-jdbc-4.2.4.jar
mysql-connector-java-5.1.36-bin.jar
最后在Liferay中配置CAS连接信息。
OK
相关资源下载地址:
cas-server-webapp.jar
CAS4.2.4 连接Liferay6.2以上版本数据库用户表验证用户 project