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
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); |
|
} |
|
}
|
|
|