commit
14dadd4e64
8 changed files with 444 additions and 0 deletions
@ -0,0 +1,6 @@
|
||||
# open-JSD-10408 |
||||
|
||||
JSD-10408 挂载bi仪表板url单点登录\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 |
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.eco.plugin.xxx.dapsso</id> |
||||
<name><![CDATA[xx单点登录_EK]]></name> |
||||
<active>yes</active> |
||||
<version>1.0.0</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2018-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[xx单点登录]]></description> |
||||
<change-notes><![CDATA[ |
||||
[2022-06-27]JSD-10408插件初始化 |
||||
]]></change-notes> |
||||
<main-package>com.eco.plugin.xxx.dapsso</main-package> |
||||
|
||||
<extra-core> |
||||
|
||||
<LocaleFinder class="LocaleFinderBridge"/> |
||||
</extra-core> |
||||
|
||||
<extra-decision> |
||||
<GlobalRequestFilterProvider class="DAPLoginFilter"/> |
||||
</extra-decision> |
||||
<lifecycle-monitor class="PluginInitializeMonitor"/> |
||||
|
||||
<function-recorder class="AccessKeyConfig"/> |
||||
</plugin> |
@ -0,0 +1,65 @@
|
||||
package com.eco.plugin.xxx.dapsso; |
||||
|
||||
import com.fr.config.*; |
||||
import com.fr.config.holder.Conf; |
||||
import com.fr.config.holder.factory.Holders; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
@Visualization(category = "Plugin-Config_Login") |
||||
@EnableMetrics |
||||
public class AccessKeyConfig extends DefaultConfiguration { |
||||
|
||||
public static volatile AccessKeyConfig config = null; |
||||
|
||||
@Focus(id = "com.eco.plugin.xxx.dapsso", text = "DAP_SSO") |
||||
public static AccessKeyConfig getInstance() { |
||||
if (config == null) { |
||||
config = ConfigContext.getConfigInstance(AccessKeyConfig.class); |
||||
} |
||||
return config; |
||||
} |
||||
|
||||
@Identifier(value = "accessKey", name = "Plugin-Config_Property_AccessKey", description = "Plugin-Config_Property_AccessKey_Description", status = Status.SHOW) |
||||
private Conf<String> accessKey = Holders.simple(StringUtils.EMPTY); |
||||
|
||||
@Identifier(value = "authURL", name = "Plugin-Config_Property_AuthURL", description = "Plugin-Config_Property_AuthURL_Description", status = Status.SHOW) |
||||
private Conf<String> authURL = Holders.simple(StringUtils.EMPTY); |
||||
|
||||
@Identifier(value = "redirectURL", name = "Plugin-Config_Property_RedirectURL", description = "Plugin-Config_Property_RedirectURL_Description", status = Status.HIDE) |
||||
private Conf<String> redirectURL = Holders.simple(StringUtils.EMPTY); |
||||
|
||||
public String getAccessKey() { |
||||
return accessKey.get(); |
||||
} |
||||
|
||||
public void setAccessKey(String accessKey) { |
||||
this.accessKey.set(accessKey); |
||||
} |
||||
|
||||
public String getRedirectURL() { |
||||
return redirectURL.get(); |
||||
} |
||||
|
||||
public void setRedirectURL(String redirectURL){ |
||||
this.redirectURL.set(redirectURL); |
||||
} |
||||
|
||||
public String getAuthURL() { |
||||
return authURL.get(); |
||||
} |
||||
|
||||
public void setAuthURL(String authURL){ |
||||
this.authURL.set(authURL); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
AccessKeyConfig cloned = (AccessKeyConfig) super.clone(); |
||||
// cloned.appCode = (Conf<String>) appCode.clone();
|
||||
// cloned.redirectURL = (Conf<String>) redirectURL.clone();
|
||||
return cloned; |
||||
} |
||||
} |
@ -0,0 +1,304 @@
|
||||
package com.eco.plugin.xxx.dapsso; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; |
||||
import com.fr.decision.webservice.login.LogInOutResultInfo; |
||||
import com.fr.decision.webservice.utils.DecisionServiceConstants; |
||||
import com.fr.decision.webservice.utils.WebServiceUtils; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.decision.webservice.v10.login.event.LogInOutEvent; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.event.EventDispatcher; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.org.apache.http.HttpEntity; |
||||
import com.fr.third.org.apache.http.ParseException; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.client.methods.HttpPost; |
||||
import com.fr.third.org.apache.http.entity.StringEntity; |
||||
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||
import com.fr.third.org.apache.http.impl.client.HttpClients; |
||||
import com.fr.third.org.apache.http.message.BasicHeader; |
||||
import com.fr.third.org.apache.http.protocol.HTTP; |
||||
import com.fr.third.org.apache.http.util.EntityUtils; |
||||
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 javax.servlet.http.HttpSession; |
||||
import java.io.IOException; |
||||
|
||||
public class DAPLoginFilter extends AbstractGlobalRequestFilterProvider { |
||||
@Override |
||||
public String filterName() { |
||||
return "DAP_SSO"; |
||||
} |
||||
|
||||
@Override |
||||
public String[] urlPatterns() { |
||||
// if (!PluginContexts.currentContext().isAvailable()) {
|
||||
// FineLoggerFactory.getLogger().info("com.fr.plugin.dap.sso: no lic!");
|
||||
// return new String[0];
|
||||
// }
|
||||
FineLoggerFactory.getLogger().info("com.eco.plugin.xxx.dapsso: have lic!"); |
||||
return new String[]{"/*"}; |
||||
} |
||||
|
||||
@Override |
||||
public void init(FilterConfig filterConfig) { |
||||
AccessKeyConfig.getInstance(); |
||||
super.init(filterConfig); |
||||
} |
||||
|
||||
public static void main(String[] args) { |
||||
String url = "https://xxxx/webroot/decision/v5/design/report/d2db1040ffd641d4aee4b58368c48bcc/view?entryType=5"; |
||||
|
||||
System.out.println(url.contains("/design/report")); |
||||
|
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { |
||||
String token = req.getParameter("userToken"); |
||||
String requestUrl = WebUtils.getOriginalURL(req); |
||||
FineLoggerFactory.getLogger().info("FRLOG:url:"+requestUrl); |
||||
if (LoginService.getInstance().isLogged(req)){ |
||||
FineLoggerFactory.getLogger().info("FRLOG:已经登录"); |
||||
release(req, res, filterChain); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if (isLocal(req)){ |
||||
FineLoggerFactory.getLogger().info("FRLOG:Local"); |
||||
release(req, res, filterChain); |
||||
return; |
||||
} else if (isRelease(req)){ |
||||
FineLoggerFactory.getLogger().info("FRLOG:Release"); |
||||
release(req, res, filterChain); |
||||
return; |
||||
} else if(StringUtils.isEmpty(token)){ |
||||
FineLoggerFactory.getLogger().info("FRLOG:EmptyToken"); |
||||
returnString(res, "Open failed!", "Token is Empty!"); |
||||
return; |
||||
} |
||||
|
||||
int length = requestUrl.length(); |
||||
if (requestUrl.contains("?userToken")){ |
||||
length = requestUrl.indexOf("?userToken"); |
||||
} else if (requestUrl.contains("&userToken")){ |
||||
length = requestUrl.indexOf("&userToken"); |
||||
} |
||||
|
||||
// FineLoggerFactory.getLogger().info("requestURL -> " + requestUrl);
|
||||
requestUrl = requestUrl.substring(0, length); |
||||
|
||||
String username = getUsername(token); |
||||
username = username.toLowerCase(); |
||||
FineLoggerFactory.getLogger().info("username -> " + username); |
||||
|
||||
//登录
|
||||
login(req, res, username, requestUrl); |
||||
|
||||
release(req, res, filterChain); |
||||
} |
||||
|
||||
public boolean isRelease(HttpServletRequest request) { |
||||
return StringUtils.isEmpty(request.getParameter("userToken")); |
||||
// if (StringUtils.isEmpty(request.getParameter("userToken"))){
|
||||
// String url = WebUtils.getOriginalURL(request);
|
||||
// return StringUtils.isEmpty(request.getParameter("viewlet")) && !url.contains("v5/design/report");
|
||||
// }
|
||||
// return false;
|
||||
} |
||||
private void release(HttpServletRequest req, HttpServletResponse res, FilterChain chain) { |
||||
try{ |
||||
chain.doFilter(req,res); |
||||
}catch (Exception e){ |
||||
FineLoggerFactory.getLogger().info("FRLOG:filter fail"); |
||||
} |
||||
} |
||||
|
||||
private String getUsername(String token) { |
||||
AccessKeyConfig config = AccessKeyConfig.getInstance(); |
||||
String accessKey = config.getAccessKey(); |
||||
String authURL = config.getAuthURL(); |
||||
JSONObject param = new JSONObject(); |
||||
param.put("accessKey", accessKey); |
||||
param.put("userToken", token); |
||||
String result = ""; |
||||
try { |
||||
result = send(authURL + "/api/user/auth", param, "UTF-8"); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error("FRLOG -> get user failed"); |
||||
return ""; |
||||
} |
||||
FineLoggerFactory.getLogger().info("FRLOG result -> " + result); |
||||
JSONObject jo = new JSONObject(result); |
||||
if (jo.containsKey("data")){ |
||||
return jo.getJSONObject("data").getString("yumADAccount"); |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
/** |
||||
* 发送post请求 |
||||
* @param url 路径 |
||||
* @param jsonObject 参数(json类型) |
||||
* @param encoding 编码格式 UTF-8 |
||||
* @return |
||||
* @throws ParseException |
||||
* @throws IOException |
||||
*/ |
||||
public static String send(String url, JSONObject jsonObject, String encoding) throws ParseException, IOException { |
||||
String body = ""; |
||||
|
||||
FineLoggerFactory.getLogger().info("authURL -> " + url); |
||||
// FineLoggerFactory.getLogger().info("param -> " + jsonObject.toString());
|
||||
//创建httpclient对象
|
||||
CloseableHttpClient client = HttpClients.createDefault(); |
||||
//创建post方式请求对象
|
||||
HttpPost httpPost = new HttpPost(url); |
||||
|
||||
//装填参数
|
||||
StringEntity s = new StringEntity(jsonObject.toString(), "utf-8"); |
||||
s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, |
||||
"application/json")); |
||||
//设置参数到请求对象中
|
||||
httpPost.setEntity(s); |
||||
// System.out.println("请求地址:"+url);
|
||||
// System.out.println("请求参数:"+nvps.toString());
|
||||
|
||||
//设置header信息
|
||||
//指定报文头【Content-type】、【User-Agent】
|
||||
// httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
httpPost.setHeader("Content-type", "application/json"); |
||||
httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); |
||||
|
||||
//执行请求操作,并拿到结果(同步阻塞)
|
||||
CloseableHttpResponse response = client.execute(httpPost); |
||||
//获取结果实体
|
||||
HttpEntity entity = response.getEntity(); |
||||
if (entity != null) { |
||||
//按指定编码转换结果实体为String类型
|
||||
body = EntityUtils.toString(entity, encoding); |
||||
} |
||||
EntityUtils.consume(entity); |
||||
//释放链接
|
||||
response.close(); |
||||
FineLoggerFactory.getLogger().info(body); |
||||
return body; |
||||
} |
||||
|
||||
public void login(HttpServletRequest request, HttpServletResponse response, String userName, String url){ |
||||
FineLoggerFactory.getLogger().info("FRLOG:username -> " + userName); |
||||
// FineLoggerFactory.getLogger().info("FRLOG:跳转链接:"+url);
|
||||
|
||||
|
||||
//判断用户名是否为空
|
||||
if(!StringUtils.isEmpty(userName)){ |
||||
if(isUserExist(userName)){ |
||||
String FRToken = ""; |
||||
|
||||
try { |
||||
HttpSession session = request.getSession(true); |
||||
|
||||
FRToken = LoginService.getInstance().login(request, response, userName); |
||||
|
||||
request.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME,FRToken); |
||||
|
||||
session.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, FRToken); |
||||
EventDispatcher.fire(LogInOutEvent.LOGIN,new LogInOutResultInfo(request,response,userName,true)); |
||||
FineLoggerFactory.getLogger().info("FRLOG:Login success!"); |
||||
|
||||
// if(!StringUtils.isEmpty(url)){
|
||||
// response.sendRedirect(url);
|
||||
// }
|
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().info("FRLOG -> Login failed!"); |
||||
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage()); |
||||
|
||||
returnString(response, "Open failed!", "Login failed!"); |
||||
// returnJSON(response, "Login failed!");
|
||||
return; |
||||
} |
||||
}else{ |
||||
FineLoggerFactory.getLogger().info("FRLOG -> user is not exist!"); |
||||
returnString(response, "Open failed!", "User is not exist!"); |
||||
// returnJSON(response, "User is not exist!");
|
||||
return; |
||||
} |
||||
}else{ |
||||
FineLoggerFactory.getLogger().info("FRLOG -> username is empty!"); |
||||
returnString(response, "Open failed!", "Token expired!"); |
||||
// returnJSON(response, "Token expired!");
|
||||
return; |
||||
} |
||||
} |
||||
|
||||
public static void returnString(HttpServletResponse res, String notice, String msg) { |
||||
try { |
||||
String errorHtml = WebServiceUtils.generateErrorWebPage(notice, msg, ""); |
||||
WebUtils.printAsString(res,errorHtml); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().info("return error -> " + e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public void returnJSON(HttpServletResponse res, String msg){ |
||||
JSONObject data = new JSONObject(); |
||||
data.put("msg", msg); |
||||
try { |
||||
WebUtils.printAsJSON(res,data); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().info("return error -> " + e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
public boolean isUserExist(String userName){ |
||||
try { |
||||
if (UserService.getInstance().getUserByUserName(userName) == null){ |
||||
return false; |
||||
} |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().info(e.getMessage(), e); |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public static Boolean isLocal(HttpServletRequest request) { |
||||
|
||||
String ip = request.getHeader("x-forwarded-for"); |
||||
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { |
||||
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
|
||||
if( ip.indexOf(",")!=-1 ){ |
||||
ip = ip.split(",")[0]; |
||||
} |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("Proxy-Client-IP"); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("WL-Proxy-Client-IP"); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("HTTP_CLIENT_IP"); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR"); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("X-Real-IP"); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getRemoteAddr(); |
||||
} |
||||
FineLoggerFactory.getLogger().info("RealIp -> [{}] ",ip); |
||||
return StringUtils.equals(ip, "0:0:0:0:0:0:0:1") || StringUtils.equals(ip, "127.0.0.1"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,10 @@
|
||||
package com.eco.plugin.xxx.dapsso; |
||||
|
||||
import com.fr.stable.fun.impl.AbstractLocaleFinder; |
||||
|
||||
public class LocaleFinderBridge extends AbstractLocaleFinder { |
||||
@Override |
||||
public String find() { |
||||
return "dap_locale/conf"; |
||||
} |
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.eco.plugin.xxx.dapsso; |
||||
|
||||
import com.fr.plugin.context.PluginContext; |
||||
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||
|
||||
|
||||
public class PluginInitializeMonitor extends AbstractPluginLifecycleMonitor { |
||||
@Override |
||||
public void afterRun(PluginContext pluginContext) { |
||||
AccessKeyConfig.getInstance(); |
||||
} |
||||
|
||||
@Override |
||||
public void beforeStop(PluginContext pluginContext) { |
||||
|
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
Plugin-Config_Login=Login configuration |
||||
Plugin-Config_Property_AccessKey=AccessKey |
||||
Plugin-Config_Property_AccessKey_Description=Set AccessKey. |
||||
Plugin-Config_Property_RedirectURL=RedirectURL |
||||
Plugin-Config_Property_RedirectURL_Description=Set RedirectURL. |
||||
Plugin-Config_Property_AuthURL=Authorization address |
||||
Plugin-Config_Property_AuthURL_Description=Set Authorization address\u3002 |
||||
Plugin-Error_Token=No token, access deny. |
@ -0,0 +1,8 @@
|
||||
Plugin-Config_Login=\u5355\u70B9\u767B\u5F55\u914D\u7F6E |
||||
Plugin-Config_Property_AccessKey=AccessKey |
||||
Plugin-Config_Property_AccessKey_Description=\u8BBE\u7F6EAccessKey\u3002 |
||||
Plugin-Config_Property_RedirectURL=\u65E0\u7528\u6237\u8DF3\u8F6C\u5730\u5740 |
||||
Plugin-Config_Property_RedirectURL_Description=\u51B3\u7B56\u5E73\u53F0\u4E2D\u4E0D\u5B58\u5728\u8BE5\u7528\u6237\u65F6\u7684\u8DF3\u8F6C\u5730\u5740\u3002 |
||||
Plugin-Config_Property_AuthURL=\u8BA4\u8BC1\u5730\u5740 |
||||
Plugin-Config_Property_AuthURL_Description=\u8BBE\u7F6E\u8BA4\u8BC1\u5730\u5740\u3002 |
||||
Plugin-Error_Token=\u65E0\u6548\u7684Token\uFF0C\u7981\u6B62\u8BBF\u95EE |
Loading…
Reference in new issue