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.

331 lines
14 KiB

package com.fr.plugin;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.net.http.HttpKit;
import com.fr.base.ServerConfig;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
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.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.stable.StringUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
public class XTLCookieFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "xtlfilter";
}
@Override
public String[] urlPatterns() {
return new String[]{
"/*"
};
}
@Override
public void init(FilterConfig filterConfig) {
XTLConfig.getInstance();
FineLoggerFactory.getLogger().info("登录Oauth2初始化");
super.init(filterConfig);
}
static String AuthCookieName = "tyyh_token";
static String FRCookieName = "fr_ttyh_token";
private boolean isLogOut(HttpServletRequest req) {
String url = WebUtils.getOriginalURL(req);
String servletNamePrefix = "/" + ServerConfig.getInstance().getServletName() + "/logout";
return url.contains(servletNamePrefix) && req.getMethod().equals("POST");
}
private String deleteCookieByName(HttpServletRequest request, HttpServletResponse response, String name) {
Cookie[] cookies = request.getCookies();
if (null == cookies) {
FineLoggerFactory.getLogger().info("没有cookie");
} else {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
String cookieValue = cookie.getValue();
//设置值为null
cookie.setValue(null);
//立即销毁cookie
cookie.setMaxAge(0);
cookie.setPath("/");
FineLoggerFactory.getLogger().info("被删除的cookie名字为:{}", cookie.getName(), cookieValue);
response.addCookie(cookie);
return cookieValue;
}
}
}
return "";
}
private void callLogout(String token){
XTLConfig xtlConfig = XTLConfig.getInstance();
String url = String.format("%s/api/verification/loginOut", xtlConfig.getValAddr());
HttpUtils httpUtils = new HttpUtils();
JSONObject entries = new JSONObject();
entries.put("token", token);
String resp = httpUtils.postJsonData(url, entries.toString());
LogKit.info("登出对方接口提示:{}", resp);
}
private void delLoginOut(HttpServletRequest req, HttpServletResponse res) {
try {
//执行帆软内部的退出
LoginService.getInstance().logout(req, res);
XTLConfig xtlConfig = XTLConfig.getInstance();
String frUrl = URLEncoder.encode(xtlConfig.getFrUrl(),"UTF-8");
String callBack = String.format("%s/user/login?BackAddr=%s",xtlConfig.getValAddr(),frUrl);
JSONObject jsonObject = new JSONObject();
String token = deleteCookieByName(req, res, FRCookieName);
deleteCookieByName(req, res, AuthCookieName);
if (StringUtils.isNotBlank(token)) {
callLogout(token);
}
jsonObject.put("data", callBack);
//调用外部接口注销accessToken
FineLoggerFactory.getLogger().error("登出成功: ----------------");
//指定退出之后到他们登录页面
WebUtils.printAsJSON(res, jsonObject);
} catch (Exception var4) {
}
}
private boolean isLoginRequest(HttpServletRequest req) {
if (req == null) {
return false;
}
if (!"GET".equalsIgnoreCase(req.getMethod())) {
return false;
}
String url = req.getRequestURL().toString();
if (url.endsWith("/decision/login") || url.endsWith("/decision/login/")) {
return true;
}
return false;
}
@Override
@ExecuteFunctionRecord
public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) {
try {
if(isLogOut(request)){
delLoginOut(request, httpServletResponse);
return;
}
if(isLoginRequest(request)){
String isAdmin = request.getParameter("isAdmin");
if (StringUtils.equals(isAdmin,"1")) {
request.getSession(true).setAttribute("adminLogin",true);
}
}
if (needFilter(request)) {
Map<String, String> cookies = getCookies(request);
//校验是否本地有cookies
String value;
if (cookies.containsKey(AuthCookieName) && (value = cookies.get(AuthCookieName)) != null) {
if (cookies.containsKey(FRCookieName) && StringUtils.equals(cookies.get(FRCookieName), value) && isLogin(request)) {
//如果登陆了就继续后续流程,如果没有登录还要去校验token走流程
filterChain.doFilter(request, httpServletResponse);
return;
}
//本地不存在FRCookieName或者两个不一致,就去验证AuthCookieName
Boolean success = checkCookies(value);
if (success) {
//通过token获取code,code换用户信息
boolean loginSuccess = loginByToken(value, request, httpServletResponse);
if(loginSuccess){
setCookie(httpServletResponse, FRCookieName, value);
}
}
}else{
if(isLogin(request)){
//登出系统
LoginService.getInstance().crossDomainLogout(request, httpServletResponse, "xx");
deleteCookieByName(request, httpServletResponse, FRCookieName);
}
}
if(!isLogin(request)){
//校验token失败跳转去登陆页面
String originalURL = WebUtils.getOriginalURL(request);
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String encode = URLEncoder.encode(originalURL, "UTF-8");
String format = String.format("%s/user/login?BackAddr=%s", valAddr, encode);
sendRedirect(httpServletResponse, format);
return;
}
}
filterChain.doFilter(request, httpServletResponse);
} catch (IOException | ServletException e) {
printException2FrLog(e);
} catch (Exception e) {
printException2FrLog(e);
}
}
private boolean loginByToken(String token, HttpServletRequest req, HttpServletResponse res) throws Exception {
String code = getCode(token);
String accessToken = getAccessToken(code);
String userId = getUserId(accessToken);
UserService userService = UserService.getInstance();
User user = userService.getUserByUserName(userId);
if (user != null) {
login(req, res, userId);
return true;
} else {
WebUtils.printAsString(res, "用户" + userId + "在帆软系统中不存在");
return false;
}
}
private Boolean checkCookies(String value) {
XTLConfig xtlConfig = XTLConfig.getInstance();
String url = String.format("%s/api/verification/verificationLogin", xtlConfig.getValAddr());
JSONObject entries = new JSONObject();
entries.put("joinsysCode", xtlConfig.getLoginAppid());
entries.put("cookie", value);
HttpUtils httpUtils = new HttpUtils();
String resp = httpUtils.postJsonData(url, entries.toString());
JSONObject respJson = new JSONObject(resp);
String code = respJson.getString("code");
return StringUtils.equals(code, "200");
}
private String getUserId(String accessToken) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String url = String.format("%s/api/getUserInfo", valAddr);
Map<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer " + accessToken);
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getUserInfo返回:{}", resp);
JSONObject entries = new JSONObject(resp);
return entries.getString("userId");
}
private String getAccessToken(String code) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String frUrl = xtlConfig.getFrUrl() + "/url/oauth2/login";
String appid = xtlConfig.getAppid();
String loginClientSecret = xtlConfig.getLoginClientSecret();
String url = String.format("%s/api/oauth/getAccessToken?redirect_uri=%s&" +
"client_id=%s&" +
"client_secret=%s&code=%s&grant_type=authorization_code", valAddr, frUrl, appid, loginClientSecret, code);
Map<String, String> header = new HashMap<>();
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getAccessToken返回:{}", resp);
JSONObject entries = new JSONObject(resp);
int code1 = entries.getInt("code");
if (code1 == 200) {
return entries.getJSONObject("data").getString("access_token");
}
return "";
}
private String getCode(String token) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String loginAppid = xtlConfig.getLoginAppid();
String url = String.format("%s/api/oauth/getCode?joinsysCode=%s", valAddr, loginAppid);
Map<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer " + token);
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getCode返回:{}", resp);
JSONObject entries = new JSONObject(resp);
int code = entries.getInt("code");
if (code == 200) {
return entries.getString("msg");
}
return "";
}
private static void setCookie(HttpServletResponse response, String name, String value) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
response.addCookie(cookie);
}
private Map<String, String> getCookies(HttpServletRequest request) {
Map<String, String> cookieMap = new HashMap<String, String>();
Cookie[] cookies = request.getCookies();
if (null != cookies) {
for (Cookie cookie : cookies) {
cookieMap.put(cookie.getName(), cookie.getValue());
}
}
return cookieMap;
}
private void sendRedirect(HttpServletResponse res, String url) {
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
res.setHeader("Location", url);
}
private boolean needFilter(HttpServletRequest request) {
String requestURI = request.getRequestURI();
Object adminLogin = request.getSession().getAttribute("adminLogin");
if (adminLogin != null) {
return false;
}
if (StringUtils.isNotBlank(requestURI)) {
if (requestURI.endsWith("decision")) {
return true;
}
if (requestURI.endsWith("/view/form") || requestURI.endsWith("/view/report")) {
if (StringUtils.isNotBlank(request.getParameter("viewlet"))) {
return true;
}
}
if (requestURI.contains("/v5/design/report") && (requestURI.endsWith("/edit")|| requestURI.endsWith("/view"))) {
return true;
}
}
return false;
}
public static void printException2FrLog(Throwable e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String s = writer.toString();
FineLoggerFactory.getLogger().error("错误:{}", s);
}
private void login(HttpServletRequest req, HttpServletResponse res, String username) {
String token = null;
try {
UserService userService = UserService.getInstance();
User user = userService.getUserByUserName(username);
if (user != null) {
token = LoginService.getInstance().login(req, res, username);
req.setAttribute("fine_auth_token", token);
}
FineLoggerFactory.getLogger().error("login success");
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineLoggerFactory.getLogger().error("login failed");
}
}
private boolean isLogin(HttpServletRequest req) {
return LoginService.getInstance().isLogged(req);
}
}