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.

231 lines
9.4 KiB

package com.fr.plugin.xx.zyjn.sso;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xx.zyjn.PluginConstants;
import com.fr.plugin.xx.zyjn.conf.GxkgSsoConfig;
import com.fr.plugin.xx.zyjn.schedule.SyncUserSchedule;
import com.fr.plugin.xx.zyjn.utils.CommonUtils;
import com.fr.plugin.xx.zyjn.utils.HttpUtil;
import com.fr.plugin.xx.zyjn.utils.LogUtils;
import com.fr.plugin.transform.FunctionRecorder;
import com.fr.scheduler.QuartzContext;
import com.fr.scheduler.ScheduleJobManager;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.Authorize;
import com.fr.third.v2.org.quartz.CronScheduleBuilder;
import com.fr.third.v2.org.quartz.JobKey;
import com.fr.third.v2.org.quartz.SchedulerException;
import com.fr.third.v2.org.quartz.TriggerBuilder;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* @author xx
* @date 2021/11/04
*/
@FunctionRecorder
@Authorize(callSignKey = PluginConstants.PLUGIN_ID)
public class OAuth extends AbstractGlobalRequestFilterProvider {
@Override
public void init(FilterConfig filterConfig) {
}
public static void initSchedule() {
JobKey jobKey = new JobKey("syncUser", "syncGroup");
try {
if (QuartzContext.getInstance().getScheduler().checkExists(jobKey)) {
ScheduleJobManager.getInstance().removeJob(jobKey.getName(), jobKey.getGroup());
}
} catch (SchedulerException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
addSchedule(jobKey);
}
private static void addSchedule(JobKey jobKey) {
Map<String, Object> param = new HashMap();
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.forJob(jobKey.getName(), jobKey.getGroup()).withIdentity(jobKey.getName(), jobKey.getGroup()).startNow();
String cron = GxkgSsoConfig.getInstance().getCron();
if (StringUtils.isBlank(cron)) {
FineLoggerFactory.getLogger().error("cron is null schedule start failed");
return;
}
CronScheduleBuilder schedule = CronScheduleBuilder.cronSchedule(cron);
triggerBuilder.withSchedule(schedule);
try {
ScheduleJobManager.getInstance().addJob(jobKey.getName(), jobKey.getGroup(), "sync job", SyncUserSchedule.class, triggerBuilder.build(), param);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
@Override
public String filterName() {
return "oauthFilter";
}
@Override
public String[] urlPatterns() {
if (!PluginContexts.currentContext().isAvailable()) {
LogUtils.error("未注册或禁用");
return new String[]{"/neverbeused"};
}
//initSchedule();
return new String[]{
"/decision",
"/decision/view/report",
"/decision/view/form",
};
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
GxkgSsoConfig config = GxkgSsoConfig.getInstance();
if (CommonUtils.isLogin(request)) {
Cookie sessionId = com.fr.third.springframework.web.util.WebUtils.getCookie(request, "SSO_SESSION_ID");
if (config.getRefreshToken() && StringUtils.equals("XMLHttpRequest", request.getHeader("X-Requested-With"))) {
refreshSession(sessionId, config);
}
CommonUtils.next(request, response, chain);
return;
}
if (isAccept(request)) {
CommonUtils.next(request, response, chain);
return;
}
try {
String code = request.getParameter("code");
if (StringUtils.isBlank(code)) {
jumpAuthorize(request, response, config);
return;
}
String token = getToken(code, config);
if (StringUtils.isBlank(token)) {
CommonUtils.setError(response, "token 获取失败");
return;
}
String username = getUsername(token, config);
if (StringUtils.isBlank(username)) {
CommonUtils.setError(response, "username 获取失败");
return;
}
if (!CommonUtils.existUser(username)) {
CommonUtils.setError(response, String.format("[%s]用户不存在", username));
return;
}
CommonUtils.login(username, request, response);
String state = request.getParameter("state");
String sessionId = request.getParameter("sessionId");
response.addCookie(new Cookie("SSO_SESSION_ID", sessionId));
if (StringUtils.isNotBlank(state)) {
String accessURL = CommonUtils.getCachedParam(state);
if (StringUtils.isNotBlank(accessURL)) {
response.sendRedirect(accessURL);
return;
}
}
String url = request.getRequestURL().toString();
String query = String.format("%s=%s", "code", code);
String queryString = URLDecoder.decode(request.getQueryString(),"UTF-8");
LogUtils.debug4plugin("query string is {}", queryString);
queryString = queryString.replace("&" + query, "").replace(query, "");
if (StringUtils.isNotBlank(queryString)) {
LogUtils.debug4plugin("replace string is {}", url + "?" + queryString);
response.sendRedirect(url + "?" + queryString);
} else {
LogUtils.debug4plugin("replace string is {}", url);
response.sendRedirect(url);
}
} catch (Exception e) {
LogUtils.error("oauth2单点登陆处理失败, Cause by: ", e);
CommonUtils.setError(response, e.getMessage());
}
}
private void refreshSession(Cookie cookie, GxkgSsoConfig config) {
if (cookie == null) {
return;
}
String temp = "%s/sso/refreshLoginTime?sessionId=%s";
String url = String.format(temp, config.getHost(), cookie.getValue());
LogUtils.debug4plugin("get refreshSession url is {}", url);
Map<String, Object> param = new HashMap<>();
param.put("sessionId", cookie.getValue());
String res = HttpUtil.doFormPost(url, null, param, null);
LogUtils.debug4plugin("refreshSession token res is {}", res);
}
private String getUsername(String token, GxkgSsoConfig config) {
String temp = "%s/sso/oauth2/userInfo?access_token=%s&client_id=%s";
String url = String.format(temp, config.getHost(), token, config.getClientId());
LogUtils.debug4plugin("get username url is {}", url);
String res = HttpUtil.sendGet(url, null, null);
LogUtils.debug4plugin("get token res is {}", res);
JSONObject result = new JSONObject(res);
if (result.has("uid")) {
return result.getString("uid");
}
return StringUtils.EMPTY;
}
private String getToken(String code, GxkgSsoConfig config) {
String temp = "%s/sso/oauth2/token?client_id=%s&grant_type=authorization_code&code=%s&client_secret=%s";
String url = String.format(temp, config.getHost(), config.getClientId(), code, config.getClientSecret());
LogUtils.debug4plugin("get token url is {}", url);
String res = HttpUtil.sendPost(url, null, JSONObject.create());
LogUtils.debug4plugin("get token res is {}", res);
JSONObject result = new JSONObject(res);
if (result.has("access_token")) {
return result.getString("access_token");
}
return StringUtils.EMPTY;
}
private void jumpAuthorize(HttpServletRequest request, HttpServletResponse response, GxkgSsoConfig config) {
try {
String redirectUrl = CommonUtils.getUrl(request);
String key = CommonUtils.cacheParams(redirectUrl);
String temp = "%s/sso/oauth2/authorize?response_type=code&redirect_uri=%s&client_id=%s&state=%s";
String url = String.format(temp, config.getHost(), URLEncoder.encode(config.getRedirect(), "UTF-8"), config.getClientId(), key);
if (StringUtils.isNotBlank(request.getParameter("ssoToken"))) {
url += "&ssoToken=" + request.getParameter("ssoToken");
}
LogUtils.debug4plugin("redirect url is {}", url);
response.sendRedirect(url);
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
}
}
private boolean isAccept(HttpServletRequest request) {
if (request.getRequestURI().endsWith("/view/form") || request.getRequestURI().endsWith("/view/report")) {
if (StringUtils.isNotBlank(WebUtils.getHTTPRequestParameter(request, "code"))) {
return false;
}
if (StringUtils.isNotBlank(WebUtils.getReportTitleFromRequest(request))) {
return false;
}
return true;
}
return false;
}
}