package com.norteksoft.cas.authentication;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.handler.DefaultPasswordEncoder;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import javax.sql.DataSource;
public class UsernamePasswordAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {
private static final String LINK_CHAR="~~";
private SimpleJdbcTemplate simpleJdbcTemplate;
private DataSource dataSource;
private DefaultPasswordEncoder passwordEncoder;
@Override
protected boolean authenticateUsernamePasswordInternal(
UsernamePasswordCredentials credentials)throws AuthenticationException {
String username = getPrincipalNameTransformer().transform(credentials.getUsername());
final String password = credentials.getPassword();
if(username.contains("%")){//表示是swing“办公助手”中访问v1/tickets过来的,有%表示用户登录名或分支编码有中文,已进行编码URLEncoder.encode(username, "utf-8"),需要解码
try {
username = URLDecoder.decode(username, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return authenticate(username, password);
}
public boolean authenticate(final String username, final String password){
Object[] user = getUser(username);
String databasePassword = user[4].toString();
String encodePassword=password;
if(password!=null && password.length()!=32)encodePassword=passwordEncoder.encode(password);
return encodePassword.equals(databasePassword);
}
public UsernamePasswordAuthenticationHandler setJdbcTemplate(SimpleJdbcTemplate simpleJdbcTemplate) {
this.simpleJdbcTemplate=simpleJdbcTemplate;
return this;
}
//前台传过来的登录名是否带有公司或分支机构编码,并获得用户和公司、分支机构信息
private String[] getUserInfo(String username){
String[] names = new String[2];
if(username.indexOf(LINK_CHAR)>=0){
names = username.split(LINK_CHAR);//loginName==companyCode
return names;
}else{
names[0] = username;
names[1] = "";
}
return names;
}
/**
*
* @param username:loginName或loginName+=companyCode
* @return object[]:obj[0]是用户id,obj[1]是用户姓名,obj[2]是用户所在公司id,obj[3]是分支机构id,obj[4]是用户密码,obj[5]是用户登录名
*/
private Object[] getUser(String username){
String companyCode = "";
String[] names = getUserInfo(username);
String loginName = names[0];
//公司编码或分支机构编码
companyCode = names[1];
Long companyId = null;
Long subcompanyId = null;
Object[] user = null;
if(StringUtils.isNotEmpty(companyCode)){//如果公司编码或分支机构编码不为空(登录界面是带@的页面)
companyId = getCompanyIdByCode(companyCode);
if(companyId==null){
Object[] branchInfo = getBranchInfoByCode(companyCode);
if(branchInfo!=null){
subcompanyId = Long.parseLong(branchInfo[0].toString());
companyId = Long.parseLong(branchInfo[1].toString());
user = getUserInBranch(loginName,subcompanyId,companyId);
}
}else{
user = getUser(loginName,companyId);
}
}else{//登录界面是没有@的页面
companyId = getCompanyId(loginName);
user = getUser(loginName,companyId);
}
return user;
}
private final static String COMPANY_SQL = "select id from acs_company where code=? and deleted=0";
private final static String DEPARTMENT_SQL = "select id,fk_company_id from acs_department where code=? and deleted=0";
private final static String USER_DEPARTMENT_SQL = "select id, name,fk_company_id,sub_company_id,password,login_name from acs_user where login_name=? and deleted=0 and sub_company_id=? and fk_company_id=?";
private final static String USER_COMPANY_SQL = "select id, name,fk_company_id,sub_company_id,password,login_name from acs_user where login_name=? and deleted=0 and sub_company_id is null and fk_company_id=?";
private final static String COMPANY_ID_SQL = "select fk_company_id from acs_user where login_name=? and deleted=0";
/**
* 根据公司编码查询公司id
* @param username
* @return
*/
public Long getCompanyIdByCode(String companyCode){
List<Map<String, Object>> list = simpleJdbcTemplate.queryForList(COMPANY_SQL, companyCode);
if(list.isEmpty()) return null;
Object obj = list.get(0).get("id");
return Long.valueOf(obj.toString());
}
/**
* 根据分支机构编码查询分支机构信息
* @param username
* @return object[]:result[0]是分支机构id,result[1]是分支机构所在租户id
*/
public Object[] getBranchInfoByCode(String companyCode){
List<Map<String, Object>> list = simpleJdbcTemplate.queryForList(DEPARTMENT_SQL, companyCode);
if(list.isEmpty()) return null;
Object[] result = new Object[2];
result[0] = list.get(0).get("id");
result[1] = list.get(0).get("fk_company_id");
return result;
}
/**
* 在分支机构中查询用户ID和用户姓名
* @param username
* @return null 用户不存在
*/
public Object[] getUserInBranch(String username,Long subCompanyId,Long companyId){
List<Map<String, Object>> list = simpleJdbcTemplate.queryForList(USER_DEPARTMENT_SQL, username,subCompanyId,companyId);
if(list.size()<=0)return null;
Object[] result = new Object[6];
result[0] = list.get(0).get("id");
result[1] = list.get(0).get("name");
result[2] = list.get(0).get("fk_company_id");
result[3] = list.get(0).get("sub_company_id");
result[4] = list.get(0).get("password");
result[5] = list.get(0).get("login_name");
return result;
}
/**
* 在总公司(非分支机构内)内查询用户ID和用户姓名
* @param username
* @return null 用户不存在
*/
public Object[] getUser(String username,Long companyId){
List<Map<String, Object>> list = simpleJdbcTemplate.queryForList(USER_COMPANY_SQL, username,companyId);
if(list.size()<=0)return null;
Object[] result = new Object[6];
result[0] = list.get(0).get("id");
result[1] = list.get(0).get("name");
result[2] = list.get(0).get("fk_company_id");
result[3] = list.get(0).get("sub_company_id");
result[4] = list.get(0).get("password");
result[5] = list.get(0).get("login_name");
return result;
}
/**
* 根据用户名查询公司id
* @param username
* @return
*/
public Long getCompanyId(String username){
List<Map<String, Object>> list = simpleJdbcTemplate.queryForList(COMPANY_ID_SQL, username);
if(list.isEmpty()) return null;
Object obj = list.get(0).get("fk_company_id");
return Long.valueOf(obj.toString());
}
public void setDataSource(DataSource dataSource) {
simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
this.dataSource = dataSource;
}
public void setPasswordEncoder(DefaultPasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
}