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
287 lines
12 KiB
3 years ago
|
package com.fr.plugin.handler;
|
||
|
|
||
|
import com.auth0.jwt.JWT;
|
||
|
import com.auth0.jwt.JWTVerifier;
|
||
|
import com.auth0.jwt.algorithms.Algorithm;
|
||
|
import com.auth0.jwt.impl.PublicClaims;
|
||
|
import com.auth0.jwt.interfaces.Claim;
|
||
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||
|
import com.fanruan.api.net.http.HttpKit;
|
||
|
import com.finebi.utils.CollectionUtils;
|
||
|
import com.fr.data.NetworkHelper;
|
||
|
import com.fr.decision.authority.data.User;
|
||
|
import com.fr.decision.fun.impl.BaseHttpHandler;
|
||
|
import com.fr.decision.mobile.terminal.TerminalHandler;
|
||
|
import com.fr.decision.webservice.v10.login.LoginService;
|
||
|
import com.fr.decision.webservice.v10.login.TokenResource;
|
||
|
import com.fr.decision.webservice.v10.user.UserService;
|
||
|
import com.fr.general.ComparatorUtils;
|
||
|
import com.fr.json.JSONObject;
|
||
|
import com.fr.log.FineLoggerFactory;
|
||
|
import com.fr.plugin.DBUtils;
|
||
|
import com.fr.plugin.FLConfig;
|
||
|
import com.fr.plugin.ThreeDESUtil;
|
||
|
import com.fr.plugin.exception.ValidException;
|
||
|
import com.fr.security.JwtUtils;
|
||
|
import com.fr.stable.StringUtils;
|
||
|
import com.fr.stable.web.Device;
|
||
|
import com.fr.third.springframework.web.bind.annotation.RequestMethod;
|
||
|
import com.fr.web.utils.WebUtils;
|
||
|
|
||
|
import javax.servlet.http.HttpServletRequest;
|
||
|
import javax.servlet.http.HttpServletResponse;
|
||
|
import javax.servlet.http.HttpSession;
|
||
|
import java.io.IOException;
|
||
|
import java.util.Date;
|
||
|
import java.util.List;
|
||
|
import java.util.Map;
|
||
|
import java.util.Objects;
|
||
|
|
||
|
public class FLPostLoginCallBackHander extends BaseHttpHandler {
|
||
|
DBUtils dbUtils = new DBUtils("secret-key");
|
||
|
|
||
|
public static Map<String, Claim> verifyToken(String token, String unifySecred) throws Exception {
|
||
|
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(unifySecred)).build();
|
||
|
Map<String, Claim> mapValue = null;
|
||
|
if (verifier != null) {
|
||
|
DecodedJWT jwt = verifier.verify(token);
|
||
|
if (jwt != null) {
|
||
|
mapValue = jwt.getClaims();
|
||
|
}
|
||
|
}
|
||
|
return mapValue;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public RequestMethod getMethod() {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String getPath() {
|
||
|
return "/login/post";
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean isPublic() {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private String findSecretKey() {
|
||
|
String sql = "select APP_SECRET from sm2_uuid_secret ORDER BY UPDATE_TIME DESC";
|
||
|
try {
|
||
|
List<Map<String, String>> result = dbUtils.exQuery(sql);
|
||
|
if (CollectionUtils.isEmpty(result)) {
|
||
|
return null;
|
||
|
}
|
||
|
String secret = result.get(0).get("APP_SECRET");
|
||
|
FineLoggerFactory.getLogger().info("oauth login secret :{}", secret);
|
||
|
return secret;
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().error("oauth login exception :{}", e.getMessage(), e);
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void getMethodHandle(HttpServletRequest req, HttpServletResponse res) throws Exception {
|
||
|
String token = req.getParameter("token");
|
||
|
String loginName = req.getParameter("loginName");
|
||
|
String serviceId = req.getParameter("serviceId");
|
||
|
FineLoggerFactory.getLogger().info("oauth login[get] token:{},loginName:{},serviceId:{}", token, loginName, serviceId);
|
||
|
if (StringUtils.isNotBlank(token)) {
|
||
|
String applySexret = findSecretKey();
|
||
|
//1. token有效期验证
|
||
|
/* if (StringUtils.isNotEmpty(applySexret)) {
|
||
|
Map<String, Claim> map;
|
||
|
try {
|
||
|
map = verifyToken(token, applySexret);
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().error("token校验失败--------------" + e.toString());
|
||
|
WebUtils.printAsString(res, "token校验失败");
|
||
|
return;
|
||
|
}
|
||
|
Date date = map.get(PublicClaims.EXPIRES_AT).asDate();
|
||
|
int exp = date.compareTo(new Date());
|
||
|
if (exp < 0) {
|
||
|
WebUtils.printAsString(res, "token过期,请重新跳转登录");
|
||
|
return;
|
||
|
}
|
||
|
}*/
|
||
|
//2. 调用接口获取用户信息
|
||
|
String username = validGetTokenGetUsername(serviceId, token, loginName);
|
||
|
UserService userService = UserService.getInstance();
|
||
|
User user = userService.getUserByUserName(username);
|
||
|
if (user != null) {
|
||
|
login(req, res, username);
|
||
|
FLConfig xtlConfig = FLConfig.getInstance();
|
||
|
String frUrl = xtlConfig.getFrUrl();
|
||
|
sendRedirect(res, frUrl);
|
||
|
return;
|
||
|
} else {
|
||
|
WebUtils.printAsString(res, "用户" + username + "在帆软系统中不存在");
|
||
|
return;
|
||
|
}
|
||
|
} else {
|
||
|
WebUtils.printAsString(res, "token校验失败");
|
||
|
// sendRedirect(res, goAuth());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void postMethodHandle(HttpServletRequest req, HttpServletResponse res) throws Exception {
|
||
|
String token = req.getParameter("pwdaToken");
|
||
|
String loginName = req.getParameter("acctId");
|
||
|
String syscode = req.getParameter("syscode");
|
||
|
FineLoggerFactory.getLogger().info("oauth login[get] pwdaToken:{},acctId:{},syscode:{}", token, loginName, syscode);
|
||
|
|
||
|
if (StringUtils.isNotBlank(token)) {
|
||
|
String applySexret = findSecretKey();
|
||
|
//1. token有效期验证
|
||
|
if (StringUtils.isNotEmpty(applySexret)) {
|
||
|
Map<String, Claim> map;
|
||
|
try {
|
||
|
map = verifyToken(token, applySexret);
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().error("token校验失败--------------" + e.toString());
|
||
|
WebUtils.printAsString(res, "token校验失败");
|
||
|
return;
|
||
|
}
|
||
|
Date date = map.get(PublicClaims.EXPIRES_AT).asDate();
|
||
|
int exp = date.compareTo(new Date());
|
||
|
if (exp < 0) {
|
||
|
WebUtils.printAsString(res, "token过期,请重新跳转登录");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
//2. 调用接口获取用户信息
|
||
|
String username = validPostTokenGetUsername(syscode, token, loginName);
|
||
|
UserService userService = UserService.getInstance();
|
||
|
User user = userService.getUserByUserName(username);
|
||
|
if (user != null) {
|
||
|
login(req, res, username);
|
||
|
FLConfig xtlConfig = FLConfig.getInstance();
|
||
|
String frUrl = xtlConfig.getFrUrl();
|
||
|
sendRedirect(res, frUrl);
|
||
|
return;
|
||
|
} else {
|
||
|
WebUtils.printAsString(res, "用户" + username + "在帆软系统中不存在");
|
||
|
return;
|
||
|
}
|
||
|
} else {
|
||
|
WebUtils.printAsString(res, "token校验失败");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
|
||
|
try {
|
||
|
postMethodHandle(req, res);
|
||
|
} catch (ValidException e) {
|
||
|
WebUtils.printAsString(res, e.getMessage());
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
||
|
WebUtils.printAsString(res, "处理异常");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private String validGetTokenGetUsername(String service, String token, String userName) throws IOException {
|
||
|
FLConfig xtlConfig = FLConfig.getInstance();
|
||
|
String valAddr = xtlConfig.getValAddr();
|
||
|
String url = String.format("%s/checkBwdaToken", valAddr);
|
||
|
JSONObject req = new JSONObject();
|
||
|
req.put("SERVICEID", service);
|
||
|
req.put("LOGINNAME", userName);
|
||
|
req.put("TOKEN", token);
|
||
|
String reqJson = req.toString();
|
||
|
url += "?args=" + ThreeDESUtil.encode(reqJson, xtlConfig.getThreeDdKey());
|
||
|
;
|
||
|
FineLoggerFactory.getLogger().info("验证token请求地址:{}", url);
|
||
|
String resp = HttpKit.get(url, null);
|
||
|
|
||
|
/**
|
||
|
* SERVICEID 应用标识,由4A统一分配
|
||
|
* RSP 成功标识0成功 非0失败
|
||
|
* LOGINACCOUNT 当前登录主帐号。应用侧获取当前主帐号
|
||
|
* ERRDESC 错误描述,仅当rsp非0时有效
|
||
|
*/
|
||
|
FineLoggerFactory.getLogger().info("验证token结果响应:{}", resp);
|
||
|
JSONObject entries = new JSONObject(resp);
|
||
|
String data = entries.getString("data");
|
||
|
entries = new JSONObject(data);
|
||
|
if (Objects.equals(0, entries.getNumberOfInteger("RSP"))) {
|
||
|
FineLoggerFactory.getLogger().info("验证token登录成功,获取用户名:{}", entries.getString("LOGINACCOUNT"));
|
||
|
return entries.getString("LOGINACCOUNT");
|
||
|
} else {
|
||
|
throw new ValidException("4a校验异常");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private String validPostTokenGetUsername(String syscode, String token, String userName) throws IOException {
|
||
|
FLConfig xtlConfig = FLConfig.getInstance();
|
||
|
String valAddr = xtlConfig.getValAddr();
|
||
|
String url = String.format("%s/checkProwadaToken", valAddr);
|
||
|
JSONObject req = new JSONObject();
|
||
|
req.put("SYSCODE", syscode);
|
||
|
req.put("ACCTID", userName);
|
||
|
req.put("TOKEN", token);
|
||
|
String reqJson = req.toString();
|
||
|
url += "?args=" + ThreeDESUtil.encode(reqJson, xtlConfig.getThreeDdKey());
|
||
|
String resp = HttpKit.get(url, null);
|
||
|
/**
|
||
|
* SYSCODE 应用标识,由4A统一分配
|
||
|
* RSP 成功标识0成功 非0失败
|
||
|
* ACCTNAME 当前登录主帐号登录名
|
||
|
* ORGCODE 当前登录账号身份的组织编码
|
||
|
* ERRDESC 错误描述,仅当rsp非0时有效
|
||
|
*/
|
||
|
FineLoggerFactory.getLogger().info("验证token结果响应:{}", resp);
|
||
|
JSONObject entries = new JSONObject(resp);
|
||
|
if (Objects.equals(0, entries.getNumberOfInteger("RSP"))) {
|
||
|
return entries.getString("USERCODE");
|
||
|
} else {
|
||
|
throw new ValidException("4a校验异常");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
private void sendRedirect(HttpServletResponse res, String url) {
|
||
|
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
|
||
|
res.setHeader("Location", url);
|
||
|
}
|
||
|
|
||
|
private boolean login(HttpServletRequest req, HttpServletResponse res, String username) {
|
||
|
try {
|
||
|
String oldToken = TokenResource.COOKIE.getToken(req);
|
||
|
if ((oldToken == null) || (!checkTokenValid(req, oldToken, username))) {
|
||
|
HttpSession session = req.getSession(true);
|
||
|
String token = LoginService.getInstance().login(req, res, username);
|
||
|
session.setAttribute("fine_auth_token", token);
|
||
|
FineLoggerFactory.getLogger().error("fr CookieFilter is over with username is ###" + username);
|
||
|
return true;
|
||
|
} else {
|
||
|
FineLoggerFactory.getLogger().error("no need login: {}", username);
|
||
|
return true;
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private boolean checkTokenValid(HttpServletRequest req, String token, String currentUserName) {
|
||
|
try {
|
||
|
if (!ComparatorUtils.equals(currentUserName, JwtUtils.parseJWT(token).getSubject())) {
|
||
|
FineLoggerFactory.getLogger().info("username changed:" + currentUserName);
|
||
|
return false;
|
||
|
} else {
|
||
|
Device device = NetworkHelper.getDevice(req);
|
||
|
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
|
||
|
return true;
|
||
|
}
|
||
|
} catch (Exception var5) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|