NC65 系统用户登陆验证逻辑
业务场景:
假设登陆用户名为:liangsl,登陆密码为:1234qwer 。
业务逻辑代码:
String sql = "select * from sm_user where user_code = 'liangsl' ";
UserVO userVO = null;
try {
userVO = (UserVO) new BaseDAO().executeQuery(sql, new BeanProcessor(UserVO.class));
} catch (DAOException e) {
e.printStackTrace();
}
boolean check = nc.vo.uap.rbac.util.RbacUserPwdUtil.checkUserPassword(userVO, "1234qwer");
NC65 系统的登录接口
nc.login.bs.INCLoginService.loginForceStaticPWD(LoginRequest loginRequest, boolean isForceLogin) throws BusinessException;
nc.login.bs.INCLoginService.login(LoginRequest loginRequest, boolean isForceLogin) throws BusinessException
//nc.login.bs.impl.LoginEngine
package nc.login.bs.impl;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import nc.bcmanage.vo.BusiCenterVO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.common.RuntimeEnv;
import nc.bs.framework.comn.NetStreamContext;
import nc.bs.framework.core.util.ObjectCreator;
import nc.bs.framework.server.ClientRequestHolder;
import nc.bs.framework.server.ISecurityTokenCallback;
import nc.bs.framework.util.KeyUtil;
import nc.bs.logging.Logger;
import nc.bs.ml.NCLangResOnserver;
import nc.bs.pub.operatelog.itf.IOperatelogService;
import nc.itf.org.IPowerOrgQryService;
import nc.itf.uap.sfapp.SecurityLogInfo;
import nc.itf.uap.sfapp.SecurityLogVarItem;
import nc.itf.uap.sfapp.securityLog.SecurityLogManageFacade;
import nc.login.bs.ILoginVerifyPlugin;
import nc.login.bs.LoginVerifyBean;
import nc.login.bs.LoginVerifyException;
import nc.login.vo.AttachedProps;
import nc.login.vo.ILoginConstants;
import nc.login.vo.INCUserTypeConstant;
import nc.login.vo.LoginFailureVO;
import nc.login.vo.LoginRequest;
import nc.login.vo.LoginResponse;
import nc.login.vo.NCSession;
import nc.login.vo.SystemConfig;
import nc.vo.ml.Language;
import nc.vo.org.GroupVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFTime;
import nc.vo.pub.operatelog.OperateLogConst;
import nc.vo.pub.operatelog.OperateLogVO;
import nc.vo.sm.UserVO;
import nc.vo.uap.rbac.userpassword.PasswordSecurityLevelFinder;
import nc.vo.uap.rbac.userpassword.PasswordSecurityLevelVO;
public class LoginEngine {
private static LoginEngine instance = null;
private SecureRandom random = null;
private ThreadLocal<BusiCenterVO> bcTl = new ThreadLocal<BusiCenterVO>();
private ThreadLocal<UserVO> userTl = new ThreadLocal<UserVO>();
private List<ILoginVerifyPlugin> verifyPluginList = null;
// private Encode encode = new Encode();
private SystemConfig sc = null;
private LoginEngine() {
super();
initialize();
}
private void initialize() {
sc = SystemConfigParser.getSystemConfig();
new Thread(new SessionCheckRunnable(), "Server Session Time Check Thread").start();
}
public static LoginEngine getInstance() {
if (instance == null) {
synchronized (LoginEngine.class) {
if (instance == null) {
instance = new LoginEngine();
}
}
}
return instance;
}
private SecureRandom getRandom() {
if (random == null) {
random = new SecureRandom();
}
return random;
}
private String genSessionID() {
long rand = getRandom().nextLong();
long currentTimeMillis = System.currentTimeMillis();
return new StringBuffer("").append(currentTimeMillis).append(rand).toString();
}
public NCSession verify(LoginRequest request, LoginVerifyBean verifyBean,LoginResponse response) throws LoginVerifyException, BusinessException {
bcTl.set(null);
userTl.set(null);
if (verifyBean == null) {
// verifyBean = new LoginVerifyBean();
throw new RuntimeException("LoginVerifyBean can't be null");
}
int result = ILoginConstants.UNKNOWN_ERROR;
// 检查业务中心
String bcCode = request.getBusiCenterCode();
BusiCenterVO bcVO = verifyBean.findBusiCenter(bcCode);
if (bcVO == null) {
throw new LoginVerifyException(ILoginConstants.BUSICENTER_NOT_FIND);
}
bcTl.set(bcVO);
UFDate today = new UFDate(System.currentTimeMillis());
result = verifyBean.checkBusiCenter(bcVO, today);
if (result != ILoginConstants.BUSICENTER_VALIDATE) {
throw new LoginVerifyException(result);
}
// 验证用户
String dsName = bcVO.getDataSourceName();
String userCode = request.getUserCode();
UserVO user = verifyBean.findUser(dsName, userCode);
if (user == null) {
throw new LoginVerifyException(ILoginConstants.USER_NAME_WRONG);
}
userTl.set(user);
result = verifyBean.checkUser(user, today);
if (result != ILoginConstants.USER_IDENTITY_LEGAL) {
throw new LoginVerifyException(result);
}
result = verifyBean.checkClient(user);
if (result != ILoginConstants.USER_IDENTITY_LEGAL) {
throw new LoginVerifyException(result);
}
// IdentityVerifyResult verifyResult =
// verifyBean.identityVerify(request, user);
// if(response != null){
// response.getAttachedProps().putAttachProp(verifyResult);
// }
//添加解锁逻辑代码 author 宁虎
if(user.getUser_type() != INCUserTypeConstant.USER_TYPE_SUPER_ADM){
result = verifyBean.identifyUserIsAutoLock(user);
if (result == ILoginConstants.USER_LOCKED) {
throw new LoginVerifyException(result);
}
}
result = verifyBean.identityVerify(request, user, response);// verifyResult.getVerifyResult();
if (result != ILoginConstants.USER_IDENTITY_LEGAL) {
//2012-12-11 sujb add 身份认证,记录安全日志
//getService().writeSecurityLogSync(writeSecurityLog(false,user.getIdentityverifycode(),response));
throw new LoginVerifyException(result);
}
// else{
// //2012-12-11 sujb add 身份认证,记录安全日志
// getService().writeSecurityLogSync(writeSecurityLog(true,user.getIdentityverifycode(),response));
// }
// 产生session
NCSession session = generateSession(request, bcVO, user);
return session;
}
public LoginResponse login(LoginRequest request, boolean isForceLogin, LoginVerifyBean verifyBean) throws BusinessException {
if (verifyBean == null) {
throw new RuntimeException("LoginVerifyBean can't be null");
}
LoginResponse response = new LoginResponse();
try {
NCSession session = verify(request, verifyBean,response);
//add by maokun 登录成功后需要设置一下正确的用户编码
InvocationInfoProxy.getInstance().setUserCode(session.getUserCode());
response.setNcSession(session);
//注册认证结果
ISecurityTokenCallback sc = NCLocator.getInstance().lookup(ISecurityTokenCallback.class);
sc.token((verifyBean.getSysID()).getBytes("UTF-8"), session.getSessionID().getBytes("UTF-8"));
//
processVerifyPlugins(request, session);
int result = ILoginConstants.UNKNOWN_ERROR;
result = ServerEnvironmentCenter.getInstance().registerUserSession(verifyBean.getSysID(), session, isForceLogin);
if (result != ILoginConstants.REGISTER_USER_SUCCESS) {
throw new LoginVerifyException(result);
}
dealWithLoginSuccess(session, request, response, verifyBean);
//2012-12-11 sujb add 身份认证,记录安全日志
getService().writeSecurityLogSync(
writeSecurityLog(true, userTl.get() == null ? "" : userTl
.get().getIdentityverifycode(), response));
return response;
} catch (LoginVerifyException e) {
dealWithLoginFailure(e.getLoginResult(), request, response, verifyBean);
// 2012-12-11 sujb add 身份认证,记录安全日志
getService().writeSecurityLogSync(
writeSecurityLog(false, userTl.get() == null ? "" : userTl
.get().getIdentityverifycode(), response));
return response;
} catch (Exception e) {
// 2012-12-11 sujb add 身份认证,记录安全日志
getService().writeSecurityLogSync(
writeSecurityLog(false, userTl.get() == null ? "" : userTl
.get().getIdentityverifycode(), response));
Logger.error(e.getMessage(), e);
throw new BusinessException(e.getMessage(), e);
}
}
private NCSession generateSession(LoginRequest request, BusiCenterVO bcVO, UserVO user) {
NCSession session = new NCSession();
session.setSessionID(genSessionID());
session.setClientHostIP(InvocationInfoProxy.getInstance().getClientHost());
session.setClientHostName(InvocationInfoProxy.getInstance().getClientHost());
session.setServerHostIP(ClientRequestHolder.getServerHost());
session.setServerHostName(ClientRequestHolder.getServerHost());
session.setServerHostPort(ClientRequestHolder.getServerPort());
session.setLangCode(request.getLangCode());
session.setBusiCenterCode(bcVO.getCode());
session.setBusiCenterName(bcVO.getName());
session.setDsName(bcVO.getDataSourceName());
session.setUserCode(user.getUser_code());
// session.setUserPWD(encode.encode(request.getUserPWD()));//(user.getUser_password());
session.setUserID(user.getPrimaryKey());
session.setUserName(user.getUser_name());
session.setLoginTime(System.currentTimeMillis());
Integer userType = user.getUser_type();
session.setUserType(userType);
session.putAttrbute("IMServer", getHost());
// if(userType == UserVO.USER_TYPE_GROUPADMIN){
// session.setUserType(INCUserTypeConstant.USER_TYPE_GROUP_ADM);
// }else if(userType == UserVO.USER_TYPE_COMMON){
// session.setUserType(INCUserTypeConstant.USER_TYPE_USER);
// }else if(userType == UserVO.USER_TYPE_ACCADMIN){
// session.setUserType(INCUserTypeConstant.USER_TYPE_BUSICNETER_ADM);
// }else{
// session.setUserType(INCUserTypeConstant.USER_TYPE_SUPER_ADM);
// }
return session;
}
private Properties getHomeProperties() {
Properties props = new Properties();
String fsp = System.getProperty("file.separator");
String path = RuntimeEnv.getInstance().getNCHome()
+ "/ierp/sf/imconfig/NCService.properties";
path = path.replace("/", fsp).replace("\\", fsp);
InputStream is = null;
try {
is = new FileInputStream(path);
props.load(is);
} catch (IOException ex) {
Logger.error(ex.getMessage(), ex);
// ex.printStackTrace();
}finally{
if(is!=null){
try {
is.close();
} catch (IOException ex) {
// e.printStackTrace();
Logger.error(ex.getMessage(), ex);
}
}
}
return props;
}
public String getHost() {
Properties props = getHomeProperties();
String useGateWayFlag = props.getProperty("IsUseGateway");
String loginAddress = null;
String clientIp = ClientRequestHolder.getServerHost() +":"+ ClientRequestHolder.getServerPort();
if(useGateWayFlag != null && useGateWayFlag.equals("Y")){
String innerGageWay = props.getProperty("NCServiceHost") +":"+ props.getProperty("NCServicePort");
if(props.getProperty("externalGateWayHost") != null && !props.getProperty("externalGateWayHost").equals("") && props.getProperty("externalGateWayPort") != null &&!props.getProperty("externalGateWayPort").equals("")){
String externalGateWay = props.getProperty("externalGateWayHost") +":"+ props.getProperty("externalGateWayPort");
if(clientIp.equals(externalGateWay)){
loginAddress = externalGateWay;
}else{
loginAddress = innerGageWay;
}
}else{
loginAddress = innerGageWay;
}
}else{
loginAddress = props.getProperty("NCServiceHost") +":"+ props.getProperty("NCServicePort");
}
return loginAddress;
}
private LoginFailureVO generateFailureVO(int loginResult, LoginRequest request) {
LoginFailureVO failVO = new LoginFailureVO();
failVO.setTime(System.currentTimeMillis());
failVO.setFailureType(loginResult);
failVO.setBcCode(request.getBusiCenterCode());
failVO.setUserCode(request.getUserCode());
failVO.setClientHost(InvocationInfoProxy.getInstance().getClientHost());
failVO.setClientIP(InvocationInfoProxy.getInstance().getClientHost());
failVO.setServerName(ClientRequestHolder.getServerHost());
failVO.setServerPort(ClientRequestHolder.getServerPort());
BusiCenterVO bcVO = bcTl.get();
if (bcVO != null) {
failVO.setBcName(bcVO.getName());
}
UserVO user = userTl.get();
if (user != null) {
failVO.setUserID(user.getPrimaryKey());
failVO.setUserName(user.getUser_name());
failVO.setUserType(user.getUser_type());
int userType = user.getUser_type();
if (userType == INCUserTypeConstant.USER_TYPE_USER || userType == INCUserTypeConstant.USER_TYPE_GROUP_ADM) {
try {
IPowerOrgQryService powerQry = (IPowerOrgQryService) NCLocator.getInstance().lookup(IPowerOrgQryService.class.getName());
GroupVO[] groups = powerQry.getGroupVOsByUserID(user.getPrimaryKey());
int count = groups == null ? 0 : groups.length;
String pkGroup = (String) request.getAttachedProp(GroupVO.class.getName() + ".pk");
GroupVO groupVO = null;
if (pkGroup != null && pkGroup.trim().length() > 0) {// 查找指定的集团
for (int i = 0; i < count; i++) {
if (groups[i].getPk_group().equals(pkGroup)) {
groupVO = groups[i];
break;
}
}
}
if (groupVO == null) {
// 用户所属集团
String user_belongGroup = user.getPk_group();
for (int i = 0; i < count; i++) {// 查找用户所属集团
if (groups[i].getPk_group().equals(user_belongGroup)) {
groupVO = groups[i];
break;
}
}
}
if (groupVO == null && groups != null && groups.length > 0) {
groupVO = groups[0];
}
if(groupVO.getCode() == null){
failVO.setGroupCode("SystemManage");
}else{
failVO.setGroupCode(groupVO.getCode());
}
if(groupVO.getName() == null){
failVO.setGroupName("System");
}else{
failVO.setGroupName(groupVO.getName());
}
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}
}
}
return failVO;
}
private void dealWithLoginFailure(int loginResult, LoginRequest request, LoginResponse response, LoginVerifyBean verifyBean) throws BusinessException {
response.setLoginResult(loginResult);
LoginFailureVO failVO = generateFailureVO(loginResult, request);
BusiCenterVO bcVO = bcTl.get();
if (bcVO != null) {
String sysid = verifyBean.getSysID();
String dsName = bcVO.getDataSourceName();
String userCode = request.getUserCode();
ServerEnvironmentCenter.getInstance().registerFailure(sysid, dsName, userCode, failVO);
if (loginResult == ILoginConstants.USER_NAME_RIGHT_PWD_WRONG) {
int failureCount = ServerEnvironmentCenter.getInstance().getFailureCount(sysid, dsName, userCode);
UserVO user = userTl.get();
int maxLoginFailure = getMaxFailure(user);
if (failureCount > maxLoginFailure) {
verifyBean.lockUser(user);
ServerEnvironmentCenter.getInstance().clearAllFailure(sysid, dsName, userCode);
}
}
}
recordLoginFailureLog(request, loginResult);
// recordSysLogForLoginFailure(request, loginResult);
}
public int getMaxFailure(UserVO user) throws BusinessException
{
if (user.getPwdlevelcode()==null)
{
return sc.getMaxLoginFailure();
}
else
{
PasswordSecurityLevelVO plvo = PasswordSecurityLevelFinder.getPWDLV(user);
if(plvo==null)
{
return sc.getMaxLoginFailure();
}
else
{
return plvo.getErrorloginThreshold()==null?sc.getMaxLoginFailure():plvo.getErrorloginThreshold().intValue();
}
}
}
private void dealWithLoginSuccess(NCSession session, LoginRequest request, LoginResponse response, LoginVerifyBean verifyBean) {
response.setLoginResult(ILoginConstants.LOGIN_SUCCESS);
BusiCenterVO bcVO = bcTl.get();
UserVO user = userTl.get();
String dsName = bcVO.getDataSourceName();
ServerEnvironmentCenter.getInstance().clearAllFailure(verifyBean.getSysID(), dsName, session.getUserCode());
AttachedProps props = response.getAttachedProps();
props.putAttachProp(BusiCenterVO.class.getName(), bcVO);
props.putAttachProp(UserVO.class.getName(), user);
props.putAttachProp(SystemConfig.class.getName(), sc);
Object preOpenNodes = request.getAttachedProp("preOpenNodes");
if(preOpenNodes != null){
props.putAttachProp("preOpenNodes", preOpenNodes);
}
verifyBean.onLoginSuccess(session, request, response);
if(dsName != null && dsName.trim().length() > 0){
recordLoginSuccessLog(session, response);
// recordSysLogForLoginSuccess(session, response);
}
}
private void recordLoginSuccessLog(NCSession session, LoginResponse response){
OperateLogVO logVO = new OperateLogVO();
//设备,入口
logVO.setDevice(OperateLogConst.PC_DEVICE+"");
logVO.setLogintype(OperateLogConst.RIA_LOGINTYPE+"");
logVO.setType(OperateLogVO.ENTERSYSTEM);
logVO.setEntersystemresult(0);
logVO.setDetail("login success");
logVO.setLogdate(new UFDate());
logVO.setLogtime(new UFTime());
logVO.setIp(session.getClientHostIP());
logVO.setPk_user(session.getUserID());
logVO.setUser_name(session.getUserName());
logVO.setUsertype(session.getUserType());
logVO.setPk_group(session.getGroupPK());
try {
IOperatelogService logService = NCLocator.getInstance().lookup(IOperatelogService.class);
String pk = logService.insertVO(logVO, session.getDsName());
logVO.setPrimaryKey(pk);
response.getAttachedProps().putAttachProp(OperateLogVO.class.getName(), logVO);
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}
}
private void recordLoginFailureLog(LoginRequest request,int result){
BusiCenterVO bcVO = bcTl.get();
if(bcVO == null)
return;
String dsName = bcVO.getDataSourceName();
if(dsName == null || dsName.trim().length() == 0)
return;
OperateLogVO logVO = new OperateLogVO();
//设备,入口
logVO.setDevice(request.getDeviceType()+"");
logVO.setLogintype(request.getLoginType()+"");
logVO.setType(OperateLogVO.ENTERSYSTEM);
logVO.setEntersystemresult(1);
String resultstr = "Erro Code is " + result;
if (result < 200) {
// resultstr = NCLangRes.getInstance().getString("loginui", resultstr, "loginresult-" + result);
resultstr = NCLangResOnserver.getInstance().getString(Language.ENGLISH_CODE,"loginui", resultstr, "loginresult-" + result);
}
logVO.setDetail("login failure:"+resultstr);
logVO.setLogdate(new UFDate());
logVO.setLogtime(new UFTime());
logVO.setIp(InvocationInfoProxy.getInstance().getClientHost());
UserVO user = userTl.get();
if(user != null){
logVO.setPk_user(user.getCuserid());
logVO.setUser_name(user.getUser_name());
logVO.setUsertype(user.getUser_type());
}else{
logVO.setUser_name(request.getUserCode());
}
IOperatelogService logService = NCLocator.getInstance().lookup(IOperatelogService.class);
try {
logService.insertVO(logVO, dsName);
} catch (BusinessException e) {
Logger.error(e.getMessage(), e);
}
}
// private void recordSysLogForLoginSuccess(NCSession session, LoginResponse response){
// SysOperLog log = new SysOperLog();
// log.setDetail("Login success");
// log.setOperType(SysOperType.LOGIN);
// log.setSessID(session.getSessionID());
// log.setStartTime(System.currentTimeMillis());
// log.setUsePK(session.getUserID());
// log.setUserCode(session.getUserCode());
// log.setUserName(session.getUserName());
// try {
// ISysOperLogService ser = NCLocator.getInstance().lookup(ISysOperLogService.class);
// String pk = ser.insertSysOperLog(log);
// log.setLogPK(pk);
// response.getAttachedProps().putAttachProp(SysOperLog.class.getName()+"login", log);
// } catch (Exception e) {
// Logger.error(e.getMessage(), e);
// }
// }
// private void recordSysLogForLoginFailure(LoginRequest request,int result){
// BusiCenterVO bcVO = bcTl.get();
// if(bcVO == null)
// return;
// String dsName = bcVO.getDataSourceName();
// if(dsName == null || dsName.trim().length() == 0)
// return;
// SysOperLog log = new SysOperLog();
// String resultstr = "Erro Code is " + result;
// if (result < 200) {
// resultstr = NCLangRes.getInstance().getString("loginui", resultstr, "loginresult-" + result);
// }
// log.setDetail("login failure:"+resultstr);
// log.setOperType(SysOperType.LOGIN);
// log.setStartTime(System.currentTimeMillis());
// log.setEndTime(System.currentTimeMillis());
// UserVO user = userTl.get();
// if(user != null){
// log.setUsePK(user.getPrimaryKey());
// log.setUserCode(user.getUser_code());
// log.setUserName(user.getUser_name());
// }else{
// log.setUserCode(request.getUserCode());
// }
//
// try {
// ISysOperLogService ser = NCLocator.getInstance().lookup(ISysOperLogService.class);
// String pk = ser.insertSysOperLog(log);
// log.setLogPK(pk);
// } catch (Exception e) {
// Logger.error(e.getMessage(), e);
// }
// }
private void processVerifyPlugins(LoginRequest request, NCSession session) throws BusinessException {
int count = getVerifyPluginList().size();
for (int i = 0; i < count; i++) {
ILoginVerifyPlugin plugin = getVerifyPluginList().get(i);
plugin.verify(request, session);
}
}
private List<ILoginVerifyPlugin> getVerifyPluginList() {
if (verifyPluginList == null) {
verifyPluginList = Collections.synchronizedList(new ArrayList<ILoginVerifyPlugin>());
List<String> clsNameList = new ArrayList<String>();
clsNameList.add("nc.bs.rbac.login.impl.GroupLoginVerifyPlugin");
for (int i = 0; i < clsNameList.size(); i++) {
String clsName = clsNameList.get(i);
Object obj =ObjectCreator.newInstance(clsName);// NewObjectService.newInstance(clsName);
if (obj instanceof ILoginVerifyPlugin) {
verifyPluginList.add((ILoginVerifyPlugin) obj);
}
}
}
return verifyPluginList;
}
/**
* 构造日志信息
* @param isSuccess
* @return
*/
private SecurityLogInfo writeSecurityLog(boolean isSuccess,String confEntryCode,LoginResponse response){
SecurityLogInfo logInfo = new SecurityLogInfo();
List<SecurityLogVarItem> logItem = new ArrayList<SecurityLogVarItem>();
logInfo.setAppTag("UAP");
logInfo.setLogType("Authentication");
if (isSuccess) {
logInfo.setLogLevel(60);
logInfo.setLogAbs("Authentication success");
logInfo.setOpResult("success");
SecurityLogVarItem item = new SecurityLogVarItem();
item.setAttributeName("Authentication");
item.setAttributeVar(confEntryCode);
item.setSecret(false);
logItem.add(item);
SecurityLogVarItem item1 = new SecurityLogVarItem();
item1.setAttributeName("Certifide result");
item1.setAttributeVar(String.valueOf(response.getLoginResult()));
item1.setSecret(false);
logItem.add(item1);
SecurityLogVarItem item2 = new SecurityLogVarItem();
item2.setAttributeName("Token");
item2.setAttributeVar(NetStreamContext.getToken()==null?"":KeyUtil.encodeToken(NetStreamContext.getToken()));
item2.setSecret(true);
logItem.add(item2);
logInfo.setOpDescript(logItem);
}else{
logInfo.setLogLevel(40);
logInfo.setLogAbs("Authentication failed");
logInfo.setOpResult("failure");
}
return logInfo;
}
/**
* 获取服务
* @return
*/
private SecurityLogManageFacade getService(){
return NCLocator.getInstance().lookup(SecurityLogManageFacade.class);
}
}