com.alogic.auth.local.DefaultAuthenticationHandler Maven / Gradle / Ivy
package com.alogic.auth.local;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.w3c.dom.Element;
import com.alogic.auth.AuthenticationHandler;
import com.alogic.auth.Constants;
import com.alogic.auth.Principal;
import com.alogic.auth.Session;
import com.alogic.auth.SessionManager;
import com.alogic.auth.SessionPrincipal;
import com.alogic.auth.UserModel;
import com.alogic.auth.util.SimpleUser;
import com.alogic.load.Loader;
import com.anysoft.util.BaseException;
import com.anysoft.util.Factory;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.XmlElementProperties;
import com.anysoft.util.XmlTools;
import com.anysoft.util.code.Coder;
import com.anysoft.util.code.CoderFactory;
import com.logicbus.backend.Context;
import com.logicbus.backend.message.JsonMessage;
/**
* AuthenticationHandler的缺省实现
*
*
* 本实现从配置文件中读取用户信息进行验证.
* 由于Principal通过Session进行存储,本实现不适合SSO场景.
*
* @author duanyy
* @since 1.6.10.10
*
* @version 1.6.11.1 [20171215 duanyy]
* - 增加获取登录id的方法
*
* @version 1.6.11.7 [20180107 duanyy]
* - 优化Session管理
*
* @version 1.6.11.14 [duanyy 20180129]
* - 优化AuthenticationHandler接口
*
* @version 1.6.11.22 [duanyy 20180314]
* - 增加isLocalLoginMode(是否本地登录模式)的判断
* - 增加common(扩展指令接口)
*
* @version 1.6.11.23 [duanyy 20180320]
* - logout时增加Session中数据的删除
*
* @version 1.6.11.59 [20180911 duanyy]
* - 优化权限接口
*/
public class DefaultAuthenticationHandler extends AuthenticationHandler.Abstract{
/**
* 会话管理器
*/
protected SessionManager sessionManager = null;
/**
* 用户模型装载器
*/
protected Loader loader = null;
/**
* 用于前端传递过来的密码解密
*/
protected Coder encrypter = null;
/**
* 用于数据库密码验证
*/
protected Coder md5 = null;
protected Session getSession(SessionManager sm,HttpServletRequest request,HttpServletResponse response,boolean create){
return sm.getSession(request,response,create);
}
@Override
public boolean isLocalLoginMode(){
return true;
}
@Override
public void configure(Element e, Properties p) {
Properties props = new XmlElementProperties(e,p);
Element elem = XmlTools.getFirstElementByPath(e, "user-model");
if (elem != null){
Factory> f = new Factory>();
try {
loader = f.newInstance(elem, props, "loader",SimpleUser.LoadFromInner.class.getName());
}catch (Exception ex){
LOG.error("Can not create loader :" + XmlTools.node2String(elem));
LOG.error(ExceptionUtils.getStackTrace(ex));
}
}
configure(props);
}
@Override
public void configure(Properties p){
super.configure(p);
encrypter = CoderFactory.newCoder("DES3");
md5 = CoderFactory.newCoder("MD5");
}
@Override
public Principal getCurrent(HttpServletRequest request,HttpServletResponse response) {
Session sess = getSession(sessionManager,request,response, false);
return getCurrent(request,response,sess);
}
@Override
public Principal getCurrent(HttpServletRequest request,HttpServletResponse response,Session session) {
return (session != null && session.isLoggedIn()) ? new SessionPrincipal(session.getId(),session):null;
}
@Override
public Principal getPrincipal(String app,String token,String callback) {
throw new BaseException("core.e1000","In default mode,it's not supported to get principal by token.");
}
@Override
public Principal login(HttpServletRequest request,HttpServletResponse response) {
Session sess = getSession(sessionManager,request,response, true);
if (sess.isLoggedIn()){
//已经登录了,删除前一个登录者的用户信息和权限信息
sess.hDel(Session.USER_GROUP);
sess.sDel(Session.PRIVILEGE_GROUP);
sess.setLoggedIn(false);
}
//登录id
String userId = getParameter(request,"loginId");
//登录密码
String password = getParameter(request,"pwd");
//验证码
String authCode = getParameter(request,"loginCode");
try {
String innerAuthCode = sess.hGet(Session.DEFAULT_GROUP,Constants.AUTH_CODE, "");
if (StringUtils.isEmpty(innerAuthCode)){
throw new BaseException("clnt.e2003","The auth code does not exist.");
}
if (!authCode.equals(innerAuthCode)){
throw new BaseException("clnt.e2002",String.format("The auth code %s is not correct", authCode));
}
UserModel user = loadUserModel(userId);
if (user == null){
throw new BaseException("clnt.e2001",
String.format("User %s does not exist or the password is not correct.", userId));
}
String pwd = encrypter.decode(password, authCode);
pwd = md5.encode(pwd, userId);
if (!pwd.equals(user.getPassword())){
throw new BaseException("clnt.e2001",
String.format("User %s does not exist or the password is not correct.", userId));
}
Principal newPrincipal = new SessionPrincipal(sess.getId(),sess);
user.copyTo(newPrincipal);
//设置登录时间
newPrincipal.setProperty(Constants.LOGIN_TIME, String.valueOf(System.currentTimeMillis()), true);
//设置客户端ip
newPrincipal.setProperty(Constants.FROM_IP, getClientIp(request), true);
/**
* 设置已登录标记
*/
sess.setLoggedIn(true);
LOG.info(String.format("User %s has logged in.",user.getId()));
return newPrincipal;
}catch (Exception ex){
LOG.error(String.format("User %s tried to login ,but %s",userId,ex.getMessage()));
throw ex;
}finally{
//登录完成,验证码过期
sess.hDel(Session.DEFAULT_GROUP,Constants.AUTH_CODE);
}
}
@Override
public void setSessionManager(SessionManager sm){
this.sessionManager = sm;
}
/**
* 装入指定id的User Model
* @param loginId 登录id
* @return UserModel实例,如果无法找到,返回为null
*/
protected UserModel loadUserModel(String loginId){
return loader == null ? null : loader.load(loginId, true);
}
/**
* 从Request中获取指定的参数
* @param request HttpServletRequest
* @param id 参数id
* @return 参数值,如果参数不存在,抛出clnt.e2000异常
*/
protected String getParameter(HttpServletRequest request,String id){
String value = request.getParameter(id);
if (StringUtils.isEmpty(value)){
throw new BaseException("clnt.e2000",String.format("Can not find parameter %s",id));
}
return value;
}
/**
* 从Request中获取指定的参数
* @param request HttpServletRequest
* @param id 参数id
* @param dftValue 缺省值,当参数不存在时,返回
* @return 参数值,如果参数不存在,返回缺省值
*/
protected String getParameter(HttpServletRequest request,String id,String dftValue){
String value = request.getParameter(id);
return StringUtils.isEmpty(value)?dftValue:value;
}
@Override
public void logout(HttpServletRequest request,HttpServletResponse response) {
Session session = getSession(sessionManager,request,response, false);
if (session != null && session.isLoggedIn()){
session.hDel(Session.USER_GROUP);
session.sDel(Session.PRIVILEGE_GROUP);
session.setLoggedIn(false);
Principal principal = new SessionPrincipal(session.getId(),session);
LOG.info(String.format("User %s has logged out.",principal.getLoginId()));
principal.expire();
}
}
@Override
public void command(Context ctx){
JsonMessage msg = (JsonMessage)ctx.asMessage(JsonMessage.class);
String cmdId = PropertiesConstants.getString(ctx, "cmd", "help");
if (cmdId.equals("GetUser")){
String userId = PropertiesConstants.getString(ctx, "userId", "");
if (StringUtils.isNotEmpty(userId)){
UserModel user = loadUserModel(userId);
Map map = new HashMap();
user.report(map);
msg.getRoot().put("data", map);
}
return ;
}
}
}