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.
233 lines
9.3 KiB
233 lines
9.3 KiB
2 years ago
|
package com.fr.plugin.xxx.gzjc.sso.filter;
|
||
|
|
||
|
import com.fr.base.TemplateUtils;
|
||
|
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
|
||
|
import com.fr.decision.webservice.bean.authentication.OriginUrlResponseBean;
|
||
|
import com.fr.decision.webservice.utils.DecisionStatusService;
|
||
|
import com.fr.decision.webservice.utils.WebServiceUtils;
|
||
|
import com.fr.general.PropertiesUtils;
|
||
|
import com.fr.intelli.record.Focus;
|
||
|
import com.fr.intelli.record.Original;
|
||
|
import com.fr.json.JSONArray;
|
||
|
import com.fr.json.JSONObject;
|
||
|
import com.fr.locale.InterProviderFactory;
|
||
|
import com.fr.log.FineLoggerFactory;
|
||
|
import com.fr.plugin.context.PluginContexts;
|
||
|
import com.fr.plugin.xxx.gzjc.sso.PluginConstants;
|
||
|
import com.fr.plugin.xxx.gzjc.sso.utils.HttpUtil;
|
||
|
import com.fr.plugin.xxx.gzjc.sso.utils.LogUtils;
|
||
|
import com.fr.plugin.transform.FunctionRecorder;
|
||
|
import com.fr.stable.StringUtils;
|
||
|
import com.fr.stable.fun.Authorize;
|
||
|
import com.fr.web.utils.WebUtils;
|
||
|
|
||
|
import javax.servlet.FilterChain;
|
||
|
import javax.servlet.FilterConfig;
|
||
|
import javax.servlet.http.HttpServletRequest;
|
||
|
import javax.servlet.http.HttpServletResponse;
|
||
|
import java.io.IOException;
|
||
|
import java.io.PrintWriter;
|
||
|
import java.net.URLEncoder;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Map;
|
||
|
import java.util.Properties;
|
||
|
import java.util.UUID;
|
||
|
|
||
|
import static com.fr.plugin.xxx.gzjc.sso.utils.CommonUtils.*;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @author xxx
|
||
|
* @since 2021/12/04
|
||
|
*/
|
||
|
@FunctionRecorder
|
||
|
@Authorize(callSignKey = PluginConstants.PLUGIN_ID)
|
||
|
public class SsoFilter extends AbstractGlobalRequestFilterProvider {
|
||
|
|
||
|
|
||
|
private String apiClientId;
|
||
|
|
||
|
private String apiClientSecret;
|
||
|
|
||
|
private String apiAuthorize;
|
||
|
|
||
|
private String apiGetToken;
|
||
|
|
||
|
private String apiGetUser;
|
||
|
|
||
|
private String errorUrl;
|
||
|
|
||
|
private String appName;
|
||
|
|
||
|
private void initParams() {
|
||
|
Properties props = PropertiesUtils.getProperties("sso");
|
||
|
this.apiClientId = props.getProperty("api.client_id");
|
||
|
this.apiClientSecret = props.getProperty("api.client_secret");
|
||
|
this.apiAuthorize = props.getProperty("api.authorize");
|
||
|
this.apiGetToken = props.getProperty("api.get-token");
|
||
|
this.apiGetUser = props.getProperty("api.get-user");
|
||
|
this.appName = props.getProperty("api.app-name");
|
||
|
this.errorUrl = props.getProperty("api.error-url");
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void init(FilterConfig filterConfig) {
|
||
|
super.init(filterConfig);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
|
||
|
if (isAccept(request) || isLogin(request)) {
|
||
|
next(request, response, chain);
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
initParams();
|
||
|
//登录页面跳转地址拦截
|
||
|
String origin = WebUtils.getHTTPRequestParameter(request, "origin");
|
||
|
if (request.getRequestURI().endsWith("decision/login")) {
|
||
|
try {
|
||
|
if ("get".equalsIgnoreCase(request.getMethod()) && StringUtils.isNotBlank(origin)) {
|
||
|
OriginUrlResponseBean path = DecisionStatusService.originUrlStatusService().get(origin);
|
||
|
if (path != null) {
|
||
|
String currentPath = String.format("%s://%s:%s%s",request.getScheme(),request.getServerName(),request.getServerPort(),path.getOriginUrl());
|
||
|
jumpAuthorize(request, response, currentPath);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
LogUtils.error(e.getMessage(), e);
|
||
|
}
|
||
|
next(request, response, chain);
|
||
|
return;
|
||
|
}
|
||
|
String code = request.getParameter("code");
|
||
|
if (StringUtils.isBlank(code)) {
|
||
|
jumpAuthorize(request, response, "");
|
||
|
return;
|
||
|
}
|
||
|
String username = getUsername(getToken(code));
|
||
|
if(!existUser(username)){
|
||
|
String address = String.format("%s?systemName=%s&reason=%s", errorUrl, URLEncoder.encode(appName,"UTF-8"), URLEncoder.encode("用户不存在","UTF-8"));
|
||
|
response.sendRedirect(address);
|
||
|
return;
|
||
|
}
|
||
|
login(username, request, response);
|
||
|
String state = request.getParameter("state");
|
||
|
if (StringUtils.isNotBlank(state)) {
|
||
|
String accessURL = getCachedParam(state, "accessURL");
|
||
|
if (StringUtils.isNotBlank(accessURL)) {
|
||
|
response.sendRedirect(accessURL);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
next(request, response, chain);
|
||
|
} catch (Exception e) {
|
||
|
LogUtils.error("oauth2单点登陆处理失败, Cause by: ", e);
|
||
|
setError(response, e.getMessage());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private String getUsername(String token) throws IOException {
|
||
|
String address = String.format("%s?access_token=%s&client_id=%s", apiGetUser, token, apiClientId);
|
||
|
HashMap<String, Object> params = new HashMap<>();
|
||
|
params.put("access_token", token);
|
||
|
String res = HttpUtil.sendGet(address, null, null);
|
||
|
LogUtils.debug4plugin("请求用户信息返回的内容 >>> [{}]", res);
|
||
|
JSONObject body = new JSONObject(res);
|
||
|
if(body.has("spRoleList")){
|
||
|
JSONArray array = body.getJSONArray("spRoleList");
|
||
|
if(array.length() != 0){
|
||
|
return array.getString(0);
|
||
|
}
|
||
|
}
|
||
|
if (body.has("loginName")) {
|
||
|
return body.getString("loginName");
|
||
|
}
|
||
|
throw new RuntimeException("获取用户信息失败,Cause by: " + res);
|
||
|
}
|
||
|
|
||
|
private String getToken(String code) throws IOException {
|
||
|
String address = String.format("%s?client_id=%s&grant_type=authorization_code&code=%s&client_secret=%s", apiGetToken, apiClientId, code, apiClientSecret);
|
||
|
HashMap<String, Object> params = new HashMap<>();
|
||
|
params.put("client_id", apiClientId);
|
||
|
params.put("client_secret", apiClientSecret);
|
||
|
params.put("code", code);
|
||
|
params.put("grant_type", "authorization_code");
|
||
|
String res = HttpUtil.sendPost(address, null, JSONObject.create());
|
||
|
LogUtils.debug4plugin("请求 Token 接口返回的内容 >>> [{}]", res);
|
||
|
JSONObject body = new JSONObject(res);
|
||
|
if (body.has("access_token")) {
|
||
|
return body.getString("access_token");
|
||
|
}
|
||
|
throw new RuntimeException("获取access_token失败,Cause by: " + res);
|
||
|
}
|
||
|
|
||
|
private void jumpAuthorize(HttpServletRequest request, HttpServletResponse response, String originUrl) throws Exception {
|
||
|
String state = UUID.randomUUID().toString();
|
||
|
String accessURL = request.getRequestURL().toString();
|
||
|
Map<String, String> params = new HashMap<>();
|
||
|
if (StringUtils.isNotBlank(originUrl)) {
|
||
|
accessURL = String.format("%s://%s:%s%s",request.getScheme(),request.getServerName(),request.getServerPort(), TemplateUtils.render("${fineServletURL}"));;
|
||
|
params.put("accessURL", originUrl);
|
||
|
} else {
|
||
|
if (StringUtils.isNotBlank(request.getQueryString())) {
|
||
|
accessURL += "?" + request.getQueryString();
|
||
|
}
|
||
|
params.put("accessURL", accessURL);
|
||
|
}
|
||
|
cacheParams(state, params);
|
||
|
String address = String.format("%s?redirect_uri=%s&state=%s&client_id=%s&response_type=code", apiAuthorize, URLEncoder.encode(accessURL, "UTF-8"), state, apiClientId);
|
||
|
LogUtils.debug4plugin("请求中不包含code值,跳转到登陆页面 >>> \"{}\"", address);
|
||
|
response.sendRedirect(address);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String filterName() {
|
||
|
return "sso";
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
@Focus(id = PluginConstants.PLUGIN_ID, text = "机场oauth2单点登陆", source = Original.PLUGIN)
|
||
|
public String[] urlPatterns() {
|
||
|
if (!PluginContexts.currentContext().isAvailable()) {
|
||
|
return new String[]{"/neverbeused"};
|
||
|
}
|
||
|
return new String[]{
|
||
|
"/decision/",
|
||
|
"/decision/login",
|
||
|
"/decision",
|
||
|
"/decision/view/report",
|
||
|
"/decision/view/form",
|
||
|
};
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private void setError(HttpServletResponse res, String reason) {
|
||
|
try {
|
||
|
PrintWriter printWriter = WebUtils.createPrintWriter(res);
|
||
|
Map<String, Object> map = new HashMap<>();
|
||
|
map.put("result", InterProviderFactory.getProvider().getLocText("Fine-Engine_Error_Page_Result"));
|
||
|
map.put("reason", reason);
|
||
|
map.put("solution", InterProviderFactory.getProvider().getLocText("Fine-Engine_Please_Contact_Platform_Admin"));
|
||
|
String page = WebServiceUtils.parseWebPageResourceSafe("com/fr/web/controller/decision/entrance/resources/unavailable.html", map);
|
||
|
printWriter.write(page);
|
||
|
printWriter.flush();
|
||
|
printWriter.close();
|
||
|
} catch (Exception e) {
|
||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|