You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
12 KiB

3 years ago
package com.fr.plugin.http.handler;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.net.http.HttpKit;
import com.fr.base.ServerConfig;
import com.fr.base.TemplateUtils;
import com.fr.config.EmailServerConfig;
import com.fr.data.NetworkHelper;
import com.fr.decision.authority.data.User;
import com.fr.decision.config.FSConfig;
import com.fr.decision.config.LoginVerificationConfig;
import com.fr.decision.config.mobile.MobileConfig;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.decision.mobile.terminal.TerminalHandler;
import com.fr.decision.privilege.TransmissionTool;
import com.fr.decision.webservice.bean.authentication.LoginClientBean;
import com.fr.decision.webservice.bean.authentication.LoginRequestInfoBean;
import com.fr.decision.webservice.bean.authentication.LoginResponseInfoBean;
import com.fr.decision.webservice.bean.authentication.OriginUrlResponseBean;
import com.fr.decision.webservice.exception.captcha.UnverifiedCaptchaException;
import com.fr.decision.webservice.exception.general.SpecialCharProhibitException;
import com.fr.decision.webservice.exception.login.LoginInfoSignErrorException;
import com.fr.decision.webservice.exception.login.UserLoginException;
import com.fr.decision.webservice.utils.ControllerFactory;
import com.fr.decision.webservice.utils.DecisionStatusService;
import com.fr.decision.webservice.utils.WebServiceUtils;
import com.fr.decision.webservice.utils.controller.AuthenticController;
import com.fr.decision.webservice.v10.login.slider.SliderVerificationService;
import com.fr.decision.webservice.v10.password.strategy.PasswordStrategyService;
import com.fr.decision.webservice.v10.register.RegisterService;
import com.fr.decision.webservice.v10.sms.SMSService;
import com.fr.decision.webservice.v10.user.UserService;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.MBEConfig;
import com.fr.security.JwtUtils;
import com.fr.stable.CodeUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.store.Converter;
import com.fr.third.fasterxml.jackson.core.JsonGenerationException;
import com.fr.third.fasterxml.jackson.core.JsonParseException;
import com.fr.third.fasterxml.jackson.databind.JsonMappingException;
import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
import com.fr.third.fasterxml.jackson.databind.type.TypeFactory;
import com.fr.third.springframework.web.bind.annotation.RequestMethod;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
public class ALLMbeLogin1Handler extends BaseHttpHandler {
@Override
public RequestMethod getMethod() {
return null;
}
@Override
public String getPath() {
return "/mbeLogin";
}
@Override
public boolean isPublic() {
return true;
}
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
String requestBody = getRequestBody(req);
try {
LoginRequestInfoBean infoBean = deserialize(requestBody, LoginRequestInfoBean.class);
//账号密码验证
if (!checkPasswordAndUserName(infoBean)) {
throw new UserLoginException();
}
LoginResponseInfoBean responseInfoBean = doLogin(req, res, infoBean);
RespJsonObj respJsonObj = new RespJsonObj();
respJsonObj.setData(responseInfoBean);
res.setContentType("application/json;charset=UTF-8");
WebUtils.printAsString(res, serialize(respJsonObj));
}catch (Exception e){
LogKit.error("login error",e);
WebUtils.printAsString(res, serialize(e));
}
}
class RespJsonObj{
LoginResponseInfoBean data;
public LoginResponseInfoBean getData() {
return data;
}
public void setData(LoginResponseInfoBean data) {
this.data = data;
}
}
private long getTokenTimeOutByValidity(int req) {
return req == -2 ? 1209600000L : FSConfig.getInstance().getLoginConfig().getLoginTimeout();
}
private String generateToken(User req, long var2) {
return this.generateToken(req.getUserName(), req.getDisplayName(), req.getTenantId(), var2);
}
private boolean needLoginVerification(Device req) {
if (req.isMobile()) {
return LoginVerificationConfig.getInstance().isSmsVerification() && SMSService.getInstance().isSMSAvailable();
} else {
return LoginVerificationConfig.getInstance().isSmsVerification() && SMSService.getInstance().isSMSAvailable() || LoginVerificationConfig.getInstance().isEmailVerification() && EmailServerConfig.getInstance().isEmailConfigValid();
}
}
private void loginInfoSignVerify(Device req, LoginRequestInfoBean var2) throws Exception {
if (!req.isPC() && MobileConfig.getInstance().getLoginIntegrityCheckConfig().isCheckEnabled()) {
StringBuilder var3 = new StringBuilder();
var3.append("username=").append(var2.getUsername()).append("&password=").append(var2.getPassword()).append("&macAddress=").append(StringUtils.isEmpty(var2.getMacAddress()) ? "" : var2.getMacAddress()).append("&deviceName=").append(StringUtils.isEmpty(var2.getDeviceName()) ? "" : var2.getDeviceName());
if (!StringUtils.equals(var3.toString(), TransmissionTool.decrypt(var2.getSign()))) {
throw new LoginInfoSignErrorException();
}
}
}
private LoginResponseInfoBean doLogin(HttpServletRequest req, HttpServletResponse res, LoginRequestInfoBean var3) throws Exception {
Device device = NetworkHelper.getDevice(req);
this.loginInfoSignVerify(device, var3);
String var5 = TransmissionTool.decrypt(var3.isEncrypted(), var3.isSupportCustomEncrypt(), var3.getPassword());
String var6 = var3.getUsername();
if (WebServiceUtils.containSQLChars(var6)) {
throw new SpecialCharProhibitException();
} else {
String var7 = WebServiceUtils.getIpInfoFromRequest(req);
SliderVerificationService.getInstance().dealWithSliderVerification(device, var7, var3.getSliderToken());
User var8 = UserService.getInstance().getUserByUserName(var6);
if (var8 == null) {
SliderVerificationService.getInstance().addErrorCount(var7);
throw new UserLoginException();
} else {
TerminalHandler var9 = TerminalHandler.getTerminal(req, device);
AuthenticController var10 = ControllerFactory.getInstance().getAuthenticController(var8.getId());
long var11 = this.getTokenTimeOutByValidity(var3.getValidity());
String var13 = this.generateToken(var8, var11);
var10.verifySingleLoginStatus(var8.getUserName(), var9, var13);
if (var10.passwordChangeable(var8)) {
PasswordStrategyService.getInstance().checkPasswordNeedUpdate(var8, var13);
PasswordStrategyService.getInstance().checkPasswordStrength(var5, var6, var13);
}
if (this.needLoginVerification(device)) {
throw new UnverifiedCaptchaException(var13);
} else {
RegisterService.getInstance().checkLicExpireSoon(var8);
OriginUrlResponseBean var14 = this.getOriginUrlResponse(var3.getOrigin());
LoginClientBean var15 = new LoginClientBean(req, device, var9);
var15.setUsername(var8.getUserName());
var15.setToken(var13);
var15.setValidity(var3.getValidity());
var15.setUserId(var8.getId());
var15.setMacAddress(var3.getMacAddress());
var10.logoutSingleLoginInvalidUser(var8.getUserName(), var9);
this.addLoginStatus(var13, var15, var11);
if (ServerConfig.getInstance().isTokenFromCookie()) {
this.writeToken2Cookie(res, var13, var3.getValidity());
}
return new LoginResponseInfoBean(var13, var14, var8.getUserName(), var3.getValidity());
}
}
}
}
public static String serialize(Object object) {
Writer write = new StringWriter();
try {
objectMapper.writeValue(write, object);
} catch (JsonGenerationException e) {
} catch (JsonMappingException e) {
} catch (IOException e) {
}
return write.toString();
}
public static <T> T deserialize(String json, Class<T> clazz) {
Object object = null;
try {
object = objectMapper.readValue(json, TypeFactory.rawClass(clazz));
} catch (JsonParseException e) {
} catch (JsonMappingException e) {
} catch (IOException e) {
}
return (T) object;
}
/**
* 获取请求体
*
* @param req
* @return
*/
public static String getRequestBody(HttpServletRequest req) {
StringBuffer sb = new StringBuffer();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null)
sb.append(line);
} catch (Exception e) {
}
return sb.toString();
}
private void writeToken2Cookie(HttpServletResponse response, String token, int validity) {
try {
if (StringUtils.isNotEmpty(token)) {
Cookie cookie = new Cookie("fine_auth_token", token);
long cookieLife = validity == -2 ? 1209600000L : (long) validity;
cookie.setMaxAge((int) cookieLife);
cookie.setPath(ServerConfig.getInstance().getCookiePath());
response.addCookie(cookie);
Cookie rememberLogin = new Cookie("fine_remember_login", String.valueOf(validity == -2 ? -2 : -1));
rememberLogin.setMaxAge((int) cookieLife);
rememberLogin.setPath(ServerConfig.getInstance().getCookiePath());
response.addCookie(rememberLogin);
} else {
FineLoggerFactory.getLogger().error("empty token cannot save.");
}
} catch (Exception var8) {
FineLoggerFactory.getLogger().error(var8.getMessage(), var8);
}
}
private String generateToken(String username, String displayName, String tenantId, long timeOut) {
Map<String, Object> claims = new HashMap();
claims.put("description", displayName);
claims.put("tenantId", tenantId);
return JwtUtils.createDefaultJWT(username, claims, timeOut);
}
private void addLoginStatus(String token, LoginClientBean clientBean, long tokenTimeout) throws Exception {
DecisionStatusService.loginStatusService().put(token, clientBean, new Converter<LoginClientBean>() {
public String[] createAlias(LoginClientBean loginClientBean) {
return new String[]{loginClientBean.getUsername()};
}
}, tokenTimeout);
}
private OriginUrlResponseBean getOriginUrlResponse(String req) throws Exception {
if (StringUtils.isNotEmpty(req)) {
OriginUrlResponseBean var2 = (OriginUrlResponseBean) DecisionStatusService.originUrlStatusService().get(req);
DecisionStatusService.originUrlStatusService().delete(req);
if (var2 != null) {
return var2;
}
}
return new OriginUrlResponseBean(TemplateUtils.render("${fineServletURL}"));
}
private boolean checkPasswordAndUserName(LoginRequestInfoBean infoBean ) throws IOException {
String url = MBEConfig.getInstance().getApiUrl();
String ukey = MBEConfig.getInstance().getUkey();
Map<String, String> params = new HashMap<String, String>();
params.put("ukey", ukey);
params.put("wcode", infoBean.getUsername());
String passwordDecode = TransmissionTool.decrypt(infoBean.isEncrypted(), infoBean.isSupportCustomEncrypt(), infoBean.getPassword());;
params.put("password", passwordDecode);
String res = HttpKit.post(url, params);
LogKit.info("url:{} res:{}", url, res);
JSONObject entries = new JSONObject(res);
return entries.getInt("flag") == 0;
}
}