package org.apereo.cas.adaptors.jdbc; import java.security.GeneralSecurityException; import java.util.List; import java.util.Map; import javax.security.auth.login.AccountNotFoundException; import javax.security.auth.login.FailedLoginException; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import org.apereo.cas.authentication.AccountPasswordMustChangeException; import org.apereo.cas.authentication.HandlerResult; import org.apereo.cas.authentication.PreventedException; import org.apereo.cas.authentication.UsernamePasswordCredential; import org.apereo.cas.web.landtool.terra.OjdbcProperties; import org.apereo.cas.web.landtool.utils.Md5Util; import org.pac4j.oauth.profile.JsonObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import org.springframework.webflow.execution.Event; import com.zaxxer.hikari.HikariDataSource; @Component public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler { private String sql; @Autowired private OjdbcProperties properties; protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException, PreventedException { if (StringUtils.isBlank(this.sql) || getJdbcTemplate() == null) throw new GeneralSecurityException("Authentication handler is not configured correctly. No SQL statement or JDBC template is found."); String username = credential.getUsername(); String password = credential.getPassword(); try { String dbPassword = (String) getJdbcTemplate().queryForObject(this.sql, String.class, new Object[]{username}); //第一次登录,仍使用源方式认证 if (IsFirstLogin(username)) { if ((StringUtils.isNotBlank(originalPassword) && !matches(originalPassword, dbPassword)) || ( StringUtils.isBlank(originalPassword) && !StringUtils.equals(password, dbPassword))) throw new FailedLoginException("Password does not match value on record."); } else { if ((StringUtils.isNotBlank(originalPassword) && !validatePass(originalPassword, dbPassword))) throw new FailedLoginException("Password does not match value on record."); } } catch (IncorrectResultSizeDataAccessException e) { if (e.getActualSize() == 0) throw new AccountNotFoundException(username + " not found with SQL query"); throw new FailedLoginException("Multiple records found for " + username); } catch (DataAccessException e) { throw new PreventedException("SQL exception while executing query for " + username, e); } checkFirstLogin(username); return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null); } protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential) throws GeneralSecurityException, PreventedException { return authenticateUsernamePasswordInternal(credential, null); } public void setSql(String sql) { this.sql = sql; } public void checkFirstLogin(String username) throws AccountPasswordMustChangeException { String tempsql = "SELECT * FROM MAGBG.ORG_USER WHERE LOGINNAME='%s'"; String querysql = String.format(tempsql, username); List> list = getJdbcTemplate().queryForList(querysql); if (list != null && !list.isEmpty()) { if ("0".equals(list.get(0).get("ISFIRSTLOGIN").toString())) { throw new AccountPasswordMustChangeException(); } } } public boolean IsFirstLogin(String username) throws AccountPasswordMustChangeException { String tempsql = "SELECT * FROM MAGBG.ORG_USER WHERE LOGINNAME='%s'"; String querysql = String.format(tempsql, username); List> list = getJdbcTemplate().queryForList(querysql); if (list != null && !list.isEmpty()) { if ("0".equals(list.get(0).get("ISFIRSTLOGIN").toString())) { return true; } } return false; } @Override public void setDataSource(DataSource dataSource) { super.setDataSource(dataSource); } @Override protected JdbcTemplate getJdbcTemplate() { JdbcTemplate jt = super.getJdbcTemplate(); return jt; } public boolean validatePass(String originalPassword, String dbpassword) { return Md5Util.verify(originalPassword, Md5Util.reverse(dbpassword)); } }