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.
214 lines
8.6 KiB
214 lines
8.6 KiB
package com.fr.plugin.xxxx.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.JSONObject; |
|
import com.fr.locale.InterProviderFactory; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.plugin.context.PluginContexts; |
|
import com.fr.plugin.xxxx.sso.PluginConstants; |
|
import com.fr.plugin.xxxx.sso.utils.HttpUtil; |
|
import com.fr.plugin.xxxx.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.xxxx.sso.utils.CommonUtils.*; |
|
|
|
|
|
/** |
|
* @author fr.open |
|
* @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 void initParams() { |
|
Properties props = PropertiesUtils.getProperties("sso"); |
|
this.apiClientId = getProperty(props, "api.client_id", false); |
|
this.apiClientSecret = getProperty(props, "api.client_secret", false); |
|
this.apiAuthorize = getProperty(props, "api.authorize", false); |
|
this.apiGetToken = getProperty(props, "api.get-token", false); |
|
this.apiGetUser = getProperty(props, "api.get-user", false); |
|
} |
|
|
|
@Override |
|
public void init(FilterConfig filterConfig) { |
|
super.init(filterConfig); |
|
initParams(); |
|
} |
|
|
|
@Override |
|
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { |
|
if (isAccept(request) || isLogin(request)) { |
|
next(request, response, chain); |
|
return; |
|
} |
|
try { |
|
//登录页面跳转地址拦截 |
|
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)); |
|
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("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[0]; |
|
} |
|
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); |
|
} |
|
} |
|
|
|
|
|
}
|
|
|