Browse Source

open

master
pioneer 2 years ago
commit
8e3a4ce7e2
  1. 6
      README.md
  2. BIN
      lib/commons-codec-1.3.jar
  3. BIN
      lib/commons-logging.jar
  4. BIN
      lib/jackson-all-1.9.1.jar
  5. BIN
      lib/para-oauth-sdk-1.0.jar
  6. 24
      plugin.xml
  7. 21
      src/main/java/com/eco/plugin/xx/jfsso/config/InitializeMonitor.java
  8. 112
      src/main/java/com/eco/plugin/xx/jfsso/config/PluginSimpleConfig.java
  9. 121
      src/main/java/com/eco/plugin/xx/jfsso/filter/SSOFilter.java
  10. 20
      src/main/java/com/eco/plugin/xx/jfsso/logout/Logout.java
  11. 33
      src/main/java/com/eco/plugin/xx/jfsso/logout/WebResourceProvider.java
  12. 130
      src/main/java/com/eco/plugin/xx/jfsso/utils/FRUtils.java
  13. 39
      src/main/java/com/eco/plugin/xx/jfsso/utils/ResponseUtils.java
  14. 55
      src/main/java/com/eco/plugin/xx/jfsso/utils/Utils.java
  15. 66
      src/main/resources/com/eco/plugin/xx/jfsso/js/logout.js

6
README.md

@ -0,0 +1,6 @@
# open-JSD-9911
JSD-9911 区分请求跳转到移动端或者pc端不同的url上\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
lib/commons-codec-1.3.jar

Binary file not shown.

BIN
lib/commons-logging.jar

Binary file not shown.

BIN
lib/jackson-all-1.9.1.jar

Binary file not shown.

BIN
lib/para-oauth-sdk-1.0.jar

Binary file not shown.

24
plugin.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin>
<id>com.eco.plugin.xx.jfsso</id>
<name><![CDATA[嘉福单点登录]]></name>
<active>yes</active>
<version>1.0.3</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[嘉福单点登录]]></description>
<change-notes><![CDATA[
]]></change-notes>
<main-package>com.eco.plugin.xx.jfsso</main-package>
<lifecycle-monitor class="com.eco.plugin.xx.jfsso.config.InitializeMonitor"/>
<extra-decision>
<GlobalRequestFilterProvider class="com.eco.plugin.xx.jfsso.filter.SSOFilter"/>
<LogInOutEventProvider class="com.eco.plugin.xx.jfsso.logout.Logout"/>
<WebResourceProvider class="com.eco.plugin.xx.jfsso.logout.WebResourceProvider" />
</extra-decision>
<function-recorder class="com.eco.plugin.xx.jfsso.config.PluginSimpleConfig"/>
</plugin>

21
src/main/java/com/eco/plugin/xx/jfsso/config/InitializeMonitor.java

@ -0,0 +1,21 @@
package com.eco.plugin.xx.jfsso.config;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
/**
* @author xx
* @version 10.0
* Created by xx on 2021-12-03
*/
public class InitializeMonitor extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
PluginSimpleConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
}

112
src/main/java/com/eco/plugin/xx/jfsso/config/PluginSimpleConfig.java

@ -0,0 +1,112 @@
package com.eco.plugin.xx.jfsso.config;
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.intelli.record.Original;
import com.fr.record.analyzer.EnableMetrics;
@Visualization(category = "单点登录配置")
@EnableMetrics
public class PluginSimpleConfig extends DefaultConfiguration {
private static volatile PluginSimpleConfig config = null;
@Focus(id="com.eco.plugin.xx.jfsso.config", text = "单点登录配置", source = Original.PLUGIN)
public static PluginSimpleConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(PluginSimpleConfig.class);
}
return config;
}
@Identifier(value = "clientId", name = "应用id", description = "应用id", status = Status.SHOW)
private Conf<String> clientId = Holders.simple("");
@Identifier(value = "secret", name = "密钥", description = "密钥", status = Status.SHOW)
private Conf<String> secret = Holders.simple("");
@Identifier(value = "index", name = "帆软首页", description = "帆软首页", status = Status.SHOW)
private Conf<String> index = Holders.simple("http://localhost:8075/webroot/decision");
@Identifier(value = "authUrl", name = "获取授权码接口", description = "获取授权码接口", status = Status.SHOW)
private Conf<String> authUrl = Holders.simple("");
@Identifier(value = "tokenUrl", name = "获取token接口", description = "获取token接口", status = Status.SHOW)
private Conf<String> tokenUrl = Holders.simple("");
@Identifier(value = "userUrl", name = "获取用户信息接口", description = "获取用户信息接口", status = Status.SHOW)
private Conf<String> userUrl = Holders.simple("");
@Identifier(value = "logoutUrl", name = "登出接口", description = "登出接口", status = Status.SHOW)
private Conf<String> logoutUrl = Holders.simple("");
public String getClientId() {
return clientId.get();
}
public void setClientId(String url) {
this.clientId.set(url);
}
public String getSecret() {
return secret.get();
}
public void setSecret(String url) {
this.secret.set(url);
}
public String getAuthUrl() {
return authUrl.get();
}
public void setAuthUrl(String url) {
this.authUrl.set(url);
}
public String getTokenUrl() {
return tokenUrl.get();
}
public void setTokenUrl(String url) {
this.tokenUrl.set(url);
}
public String getUserUrl() {
return userUrl.get();
}
public void setUserUrl(String url) {
this.userUrl.set(url);
}
public String getLogoutUrl() {
return logoutUrl.get();
}
public void setLogoutUrl(String url) {
this.logoutUrl.set(url);
}
public String getIndex() {
return index.get();
}
public void setIndex(String url) {
this.index.set(url);
}
@Override
public Object clone() throws CloneNotSupportedException {
PluginSimpleConfig cloned = (PluginSimpleConfig) super.clone();
// cloned.text = (Conf<String>) text.clone();
// cloned.count = (Conf<Integer>) count.clone();
// cloned.price = (Conf<Double>) price.clone();
// cloned.time = (Conf<Long>) time.clone();
// cloned.student = (Conf<Boolean>) student.clone();
return cloned;
}
}

121
src/main/java/com/eco/plugin/xx/jfsso/filter/SSOFilter.java

@ -0,0 +1,121 @@
package com.eco.plugin.xx.jfsso.filter;
import com.eco.plugin.xx.jfsso.config.PluginSimpleConfig;
import com.eco.plugin.xx.jfsso.utils.FRUtils;
import com.eco.plugin.xx.jfsso.utils.ResponseUtils;
import com.eco.plugin.xx.jfsso.utils.Utils;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.plugin.context.PluginContexts;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.fun.Authorize;
import com.para.esc.sdk.oauth.IOAuth20Service;
import com.para.esc.sdk.oauth.builder.OAuthServiceBuilder;
import com.para.esc.sdk.oauth.client.model.UserInfo;
import com.para.esc.sdk.oauth.exceptions.OAuthApiException;
import com.para.esc.sdk.oauth.model.OAuth20Config;
import com.para.esc.sdk.oauth.model.Token;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@EnableMetrics
@Authorize(callSignKey = "com.eco.plugin.xx.jfsso")
public class SSOFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "jfssoFilter";
}
@Override
public String[] urlPatterns() {
return new String[]{"/*"};
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain ){
if(PluginContexts.currentContext().isAvailable()){
//是否放行
boolean release = isRelease(req);
if(release){
release(req,res,chain);
return;
}
PluginSimpleConfig psc = PluginSimpleConfig.getInstance();
//构建单点请求
OAuth20Config configInfo =
new OAuth20Config(psc.getClientId(),psc.getSecret(),
FRUtils.getAllUrl(req), psc.getAuthUrl(),
psc.getTokenUrl());
IOAuth20Service service = new OAuthServiceBuilder(configInfo).build20Service();
String code = req.getParameter("code");
if(Utils.isNullStr(code)){
redirect(res,service.getAuthorizationUrl());
return ;
}
Token accessToken = service.getAccessToken(code);
UserInfo oauthUser = new UserInfo(accessToken);
UserInfo loginUser = null;
try {
loginUser = oauthUser.requestUserInfo(psc.getUserUrl());
} catch (OAuthApiException e) {
ResponseUtils.failedResponse(res,"获取用户信息异常:"+e.getMessage());
return ;
}
String userName = loginUser.getId();
FRUtils.Login(req,res,userName,"");
}
release(req,res,chain);
}
/**
* 是否放行
* @param req
* @return
*/
private boolean isRelease(HttpServletRequest req) {
String url = FRUtils.getAllUrl(req);
String op = req.getParameter("op");
boolean isLogin = FRUtils.isLogin(req);
boolean isRemote = url.contains("remote");
boolean isLoginPage = url.contains("login")||url.contains("decision/file")||url.contains("decision/resource")||url.contains("decision/system")||url.contains("query/ip");
// boolean isMobile = Utils.isMobile(req) || url.contains("/mobile") || "H5".equals(op);
boolean isDing = url.contains("dingtalk");
//带noSSO参数跳过单点
String noSSO =req.getParameter("noSSO");
boolean isSSO = false;
if(!Utils.isNullStr(noSSO)){
isSSO = Boolean.parseBoolean(noSSO);
}
return isLogin || isRemote || isLoginPage ||isSSO || isDing;
}
//跳转认证中心
private void redirect(HttpServletResponse res, String url) {
try {
res.sendRedirect(url);
} catch (IOException e) {
FRUtils.FRLogInfo("跳转认证中心异常:"+e.getMessage());
}
}
//放行拦截器
private void release(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
try{
chain.doFilter(req,res);
}catch (Exception e){
FRUtils.FRLogInfo("拦截失败");
}
}
}

20
src/main/java/com/eco/plugin/xx/jfsso/logout/Logout.java

@ -0,0 +1,20 @@
package com.eco.plugin.xx.jfsso.logout;
import com.eco.plugin.xx.jfsso.config.PluginSimpleConfig;
import com.fr.decision.fun.impl.AbstractLogInOutEventProvider;
import com.fr.decision.webservice.login.LogInOutResultInfo;
import com.fr.decision.webservice.v10.login.LoginService;
import javax.servlet.http.HttpSession;
public class Logout extends AbstractLogInOutEventProvider {
@Override
public String logoutAction(LogInOutResultInfo result) {
HttpSession session = result.getRequest().getSession(true);
LoginService.getInstance().crossDomainLogout(result.getRequest(),result.getResponse(),"");
session.invalidate();
return PluginSimpleConfig.getInstance().getLogoutUrl();
}
}

33
src/main/java/com/eco/plugin/xx/jfsso/logout/WebResourceProvider.java

@ -0,0 +1,33 @@
package com.eco.plugin.xx.jfsso.logout;
import com.fr.decision.fun.impl.AbstractWebResourceProvider;
import com.fr.decision.web.MainComponent;
import com.fr.web.struct.Atom;
import com.fr.web.struct.Component;
import com.fr.web.struct.browser.RequestClient;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
public class WebResourceProvider extends AbstractWebResourceProvider {
@Override
public Atom attach() {
return MainComponent.KEY;
}
@Override
public Atom client() {
return new Component() {
@Override
public ScriptPath script(RequestClient requestClient) {
return ScriptPath.build("/com/eco/plugin/xx/jfsso/js/logout.js");
}
@Override
public StylePath style(RequestClient requestClient) {
return StylePath.EMPTY;
// return StylePath.build("/com/fr/plugin/jdfSSO/css/icon.css");
}
};
}
}

130
src/main/java/com/eco/plugin/xx/jfsso/utils/FRUtils.java

@ -0,0 +1,130 @@
package com.eco.plugin.xx.jfsso.utils;
import com.fr.decision.authority.AuthorityContext;
import com.fr.decision.webservice.login.LogInOutResultInfo;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.login.LoginService;
import com.fr.decision.webservice.v10.login.event.LogInOutEvent;
import com.fr.event.EventDispatcher;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.query.QueryFactory;
import com.fr.stable.query.restriction.RestrictionFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
public class FRUtils {
/**
* 判断用户是否存在
* @param userName
* @return
*/
public static boolean isUserExist(String userName){
if (StringUtils.isEmpty(userName)) {
return false;
} else {
try {
List var1 = AuthorityContext.getInstance().getUserController().find(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", userName)));
return var1 != null && !var1.isEmpty();
} catch (Exception var2) {
FineLoggerFactory.getLogger().error(var2.getMessage());
return false;
}
}
}
/**
* 判断是否登录FR
* @param req
* @return
*/
public static boolean isLogin(HttpServletRequest req){
return LoginService.getInstance().isLogged(req);
}
/**
* 帆软登录
* @param httpServletRequest
* @param httpServletResponse
* @param userName
* @param url
*/
public static void Login(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,String userName,String url){
FineLoggerFactory.getLogger().info("FRLOG:用户名:"+userName);
FineLoggerFactory.getLogger().info("FRLOG:跳转链接:"+url);
//判断用户名是否为空
if(!Utils.isNullStr(userName)){
if(isUserExist(userName)){
String FRToken = "";
try {
HttpSession session = httpServletRequest.getSession(true);
FRToken = LoginService.getInstance().login(httpServletRequest, httpServletResponse, userName);
httpServletRequest.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME,FRToken);
session.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, FRToken);
EventDispatcher.fire(LogInOutEvent.LOGIN,new LogInOutResultInfo(httpServletRequest,httpServletResponse,userName,true));
FineLoggerFactory.getLogger().info("FRLOG:登陆成功!");
if(!Utils.isNullStr(url)){
httpServletResponse.sendRedirect(url);
}
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登录异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOG:登录异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户在报表系统中不存在!");
FineLoggerFactory.getLogger().info("FRLOG:用户在报表系统中不存在!");
}
}else{
ResponseUtils.failedResponse(httpServletResponse,"用户名不能为空!");
FineLoggerFactory.getLogger().info("FRLOG:用户名不能为空!");
}
}
/**
*
* @param httpServletRequest
* @param httpServletResponse
*/
public static void logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse)
{
if(!isLogin(httpServletRequest)){
return ;
}
try {
LoginService.getInstance().logout(httpServletRequest,httpServletResponse);
} catch (Exception e) {
ResponseUtils.failedResponse(httpServletResponse,"登出异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOG:登出异常,请联系管理员!");
FineLoggerFactory.getLogger().info("FRLOGException:"+e.getMessage());
}
}
/**
* 打印FR日志
* @param message
*/
public static void FRLogInfo(String message){
FineLoggerFactory.getLogger().info("FRLOG:"+message);
}
/**
* 获取带参数的访问链接
* @return
*/
public static String getAllUrl(HttpServletRequest httpServletRequest){
return WebUtils.getOriginalURL(httpServletRequest);
}
}

39
src/main/java/com/eco/plugin/xx/jfsso/utils/ResponseUtils.java

@ -0,0 +1,39 @@
package com.eco.plugin.xx.jfsso.utils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class ResponseUtils {
private static final int SUCCESS = 200;
private static final int FAILED = -1;
public static void successResponse(HttpServletResponse res, String body) {
response(res, body, SUCCESS);
}
public static void failedResponse(HttpServletResponse res, String body) {
response(res, body, FAILED);
}
private static void response(HttpServletResponse res, String body, int code) {
JSONObject object = new JSONObject();
PrintWriter pw;
try {
object.put("code", code);
object.put("data", body);
pw = WebUtils.createPrintWriter(res);
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
return;
}
res.setContentType("application/json;charset=utf-8");
String result = object.toString();
pw.println(result);
pw.flush();
pw.close();
}
}

55
src/main/java/com/eco/plugin/xx/jfsso/utils/Utils.java

@ -0,0 +1,55 @@
package com.eco.plugin.xx.jfsso.utils;
import com.fr.data.NetworkHelper;
import com.fr.third.org.apache.commons.codec.digest.DigestUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
public class Utils {
/**
* 判断字符串是否为空
* @param str
* @return true 空字符串 false 非空字符串
*/
public static boolean isNullStr(String str){
return !(str != null && !str.isEmpty() && !"null".equals(str));
}
/**
* MD5加密
* @param str
* @return
*/
public static String getMd5Str(String str)
{
return DigestUtils.md5Hex(str);
}
/**
* 获取完整的访问路径
*/
public static String getAllUrl(HttpServletRequest req, String queryStr){
return WebUtils.getOriginalURL(req);
}
/**
* 判断是否是手机端的链接
* @param req
* @return
*/
public static boolean isMobile(HttpServletRequest req) {
String[] mobileArray = {"iPhone", "iPad", "android", "windows phone", "xiaomi"};
String userAgent = req.getHeader("user-agent");
if (userAgent != null && userAgent.toUpperCase().contains("MOBILE")) {
for(String mobile : mobileArray) {
if(userAgent.toUpperCase().contains(mobile.toUpperCase())) {
return true;
}
}
}
return NetworkHelper.getDevice(req).isMobile();
}
}

66
src/main/resources/com/eco/plugin/xx/jfsso/js/logout.js

@ -0,0 +1,66 @@
/**
* Created by xx on 2020/1/8
*
* 替换main.service.js里面loginKick方法 实现登录超时自定义跳转
*
*/
!(function () {
console.log("--------------------加载my.global.service.js------------------");
var myService = BI.Services.getService("dec.service.global");
/**
* 踢出登录
* @param errorCode 错误码
* @param errorText 错误信息
*/
myService.loginKick=function (errorCode, errorText) {
var name = "login.timeout", text = errorText || "Dec-Login_Info_Not_Available";
switch (errorCode) {
case DecCst.ErrorCode.USERNAME_UNAVAILABLE:
case DecCst.ErrorCode.USERNAME_NOT_EXITS:
case DecCst.ErrorCode.PLATFORM_USER_REMOVE:
text = "Dec-Login_Account_Not_Available";
break;
case DecCst.ErrorCode.SINGLE_LOGIN_KICK:
text = "Dec-Login_Single_Logged_Tip";
break;
case DecCst.ErrorCode.USERNAME_PASSWORD_ERROR:
text = "Dec-Login_Password_Changed";
break;
default:
break;
}
BI.Popovers.create(name, {
header: BI.i18nText("BI-Basic_Prompt"),
size: "small",
closable: false,
body: {
type: "bi.label",
whiteSpace: "normal",
text: BI.i18nText(text)
},
footer: {
type: "bi.right_vertical_adapt",
items: [{
type: "bi.button",
$testId: "dec-login-kick-btn",
text: BI.i18nText("BI-Basic_OK"),
height: 24,
handler: function () {
BI.Popovers.remove(name);
var url = "http://xx/logout?redirectUrl=http://xx/webroot/decision";
window.location.href=url
// if (myService.isAdmin()){
// window.location.reload(true);
// }else {
// var url = getUrl();
// window.location.href=url;
// }
}
}]
}
}, this).open(name);
}
})();
Loading…
Cancel
Save