LAPTOP-SB56SG4Q\86185
3 years ago
11 changed files with 338 additions and 1 deletions
@ -1,3 +1,6 @@
|
||||
# open-JSD-9162 |
||||
|
||||
JSD-9162 OAuth2单点 |
||||
JSD-9162 OAuth2单点\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.eco.plugin.xxxx.oauth2</id> |
||||
<name><![CDATA[单点插件]]></name> |
||||
<active>yes</active> |
||||
<version>1.0.1</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2020-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[oauth2]]></description> |
||||
<change-notes><![CDATA[ |
||||
]]></change-notes> |
||||
<lifecycle-monitor class="com.fr.plugin.MSLifeCycleMonitor"/> |
||||
<extra-decision> |
||||
<!-- 长连接 --> |
||||
<HttpHandlerProvider class="com.fr.plugin.MSauth2HandlerProvider"/> |
||||
<!-- 短连接 --> |
||||
<URLAliasProvider class="com.fr.plugin.MSauth2URLAliasBridge"/> |
||||
</extra-decision> |
||||
<function-recorder class="com.fr.plugin.MSauth2HandlerProvider"/> |
||||
</plugin> |
@ -0,0 +1,52 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.base.FRContext; |
||||
import com.fr.base.ServerConfig; |
||||
import com.fr.base.TemplateUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.org.apache.commons.io.IOUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.io.*; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.net.URLEncoder; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Base64; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* http请求工具类 |
||||
* |
||||
* @author 0246 |
||||
*/ |
||||
public class HttpUtils { |
||||
|
||||
|
||||
|
||||
/** |
||||
* 返回当前系统的根路径 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static String getDefaultUrl(HttpServletRequest req) { |
||||
StringBuilder url = new StringBuilder(); |
||||
try { |
||||
url.append(req.getScheme()); |
||||
url.append("://"); |
||||
url.append(req.getServerName()); |
||||
if (req.getServerPort() != 80) { |
||||
url.append(":"); |
||||
url.append(req.getServerPort()); |
||||
} |
||||
url.append(TemplateUtils.render("${fineServletURL}")); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
return url.toString(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,118 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fanruan.api.net.http.HttpKit; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.decision.webservice.v10.login.LoginService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.third.org.apache.commons.lang3.StringUtils; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class MSAuthCallbackApi extends BaseHttpHandler { |
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return "/authCallBack"; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { |
||||
String code = WebUtils.getHTTPRequestParameter(httpServletRequest, "code"); |
||||
if (StringUtils.isBlank(code)) { |
||||
WebUtils.printAsString(httpServletResponse, "授权码不存在"); |
||||
return; |
||||
} |
||||
//第一步获取token
|
||||
MSConfig config = MSConfig.getInstance(); |
||||
String valAddr = config.getValAddr(); |
||||
String tokenUrl = String.format("%s/oauth/token?grant_type=authorization_code&code=%s&client_id=%s&client_secret=%s&redirect_uri=%s", |
||||
valAddr, |
||||
code, |
||||
config.getAppId(), |
||||
config.getClientSecret(), |
||||
config.getFrUrl()+"/url/ms/authCallBack" |
||||
); |
||||
if (!PluginContexts.currentContext().isAvailable()) { |
||||
WebUtils.printAsString(httpServletResponse, "单点插件授权过期请联系帆软"); |
||||
return; |
||||
} |
||||
String json = HttpKit.post(tokenUrl,new HashMap<>()); |
||||
if (StringUtils.isBlank(json)) { |
||||
WebUtils.printAsString(httpServletResponse, "访问授权服务器失败请检查服务器网络配置"); |
||||
return; |
||||
} |
||||
FineLoggerFactory.getLogger().info("请求token返回:{}", json); |
||||
JSONObject jsonObject = new JSONObject(json); |
||||
if (jsonObject.has("access_token")) { |
||||
String access_token = jsonObject.getString("access_token"); |
||||
String uid = getUserInfo(access_token); |
||||
User user = UserService.getInstance().getUserByUserName(uid); |
||||
if (user == null) { |
||||
WebUtils.printAsString(httpServletResponse, "登录失败:" + uid + " 在帆软用户体系不存在,请联系管理员添加"); |
||||
return; |
||||
} |
||||
login(httpServletRequest, httpServletResponse, uid); |
||||
Object callback = httpServletRequest.getSession().getAttribute("callback"); |
||||
if (callback != null) { |
||||
sendRedirect(httpServletResponse, callback.toString()); |
||||
return; |
||||
} |
||||
sendRedirect(httpServletResponse, HttpUtils.getDefaultUrl(httpServletRequest)); |
||||
return; |
||||
} |
||||
WebUtils.printAsString(httpServletResponse, "登录失败:" + jsonObject.getString("message")); |
||||
} |
||||
|
||||
public String getUserInfo(String access_token) { |
||||
Map<String, String> params = new HashMap<>(); |
||||
MSConfig oauth2Config = MSConfig.getInstance(); |
||||
String valAddr = oauth2Config.getValAddr(); |
||||
String url = String.format("%s/api/bff/v1.2/oauth2/userinfo?access_token=%s", valAddr, access_token); |
||||
try { |
||||
FineLoggerFactory.getLogger().info("进入token获取用户名=========参数 {} url:{}", params, url); |
||||
String post = HttpKit.get(url); |
||||
FineLoggerFactory.getLogger().info("进入token获取用户名=========参数 {} url:{} 响应:{}", params, url, post); |
||||
JSONObject entries = new JSONObject(post); |
||||
boolean success = entries.getBoolean("success"); |
||||
if (success) { |
||||
return entries.getJSONObject("data").getString("username"); |
||||
} |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
private String login(HttpServletRequest req, HttpServletResponse res, String username) throws Exception { |
||||
String token = LoginService.getInstance().login(req, res, username); |
||||
req.setAttribute("fine_auth_token", token); |
||||
FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username); |
||||
return token; |
||||
} |
||||
|
||||
private void sendRedirect(HttpServletResponse res, String url) throws IOException { |
||||
Map<String, String> params = new HashMap<>(); |
||||
params.put("callBack", url); |
||||
WebUtils.writeOutTemplate("com/fr/plugin/redirect.html", res, params); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,70 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.config.*; |
||||
import com.fr.config.holder.Conf; |
||||
import com.fr.config.holder.factory.Holders; |
||||
|
||||
@Visualization(category = "OAUTH2插件配置") |
||||
public class MSConfig extends DefaultConfiguration { |
||||
|
||||
private static volatile MSConfig config = null; |
||||
|
||||
public static MSConfig getInstance() { |
||||
if (config == null) { |
||||
config = ConfigContext.getConfigInstance(MSConfig.class); |
||||
} |
||||
return config; |
||||
} |
||||
|
||||
@Identifier(value = "valAddr", name = "接口地址", description = "接口地址", status = Status.SHOW) |
||||
private Conf<String> valAddr = Holders.simple(""); |
||||
@Identifier(value = "frUrl", name = "报表地址", description = "报表地址", status = Status.SHOW) |
||||
private Conf<String> frUrl = Holders.simple("http://localhost:8075/webroot/decision"); |
||||
@Identifier(value = "appId", name = "clientId", description = "clientId", status = Status.SHOW) |
||||
private Conf<String> appId = Holders.simple(""); |
||||
@Identifier(value = "clientSecret", name = "clientSecret", description = "clientSecret", status = Status.SHOW) |
||||
private Conf<String> clientSecret = Holders.simple(""); |
||||
|
||||
public String getFrUrl() { |
||||
return frUrl.get(); |
||||
} |
||||
|
||||
public void setFrUrl(String frUrl) { |
||||
this.frUrl.set(frUrl); |
||||
} |
||||
|
||||
public String getAppId() { |
||||
return appId.get(); |
||||
} |
||||
|
||||
public void setAppId(String appId) { |
||||
this.appId.set(appId); |
||||
} |
||||
|
||||
public String getClientSecret() { |
||||
return clientSecret.get(); |
||||
} |
||||
|
||||
public void setClientSecret(String clientSecret) { |
||||
this.clientSecret.set(clientSecret); |
||||
} |
||||
|
||||
public String getValAddr() { |
||||
return valAddr.get(); |
||||
} |
||||
|
||||
public void setValAddr(String valAddr) { |
||||
this.valAddr.set(valAddr); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
MSConfig cloned = (MSConfig) super.clone(); |
||||
cloned.valAddr = (Conf<String>) valAddr.clone(); |
||||
cloned.appId = (Conf<String>) appId.clone(); |
||||
cloned.clientSecret = (Conf<String>) clientSecret.clone(); |
||||
cloned.frUrl = (Conf<String>) frUrl.clone(); |
||||
return cloned; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,16 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.plugin.context.PluginContext; |
||||
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||
|
||||
public class MSLifeCycleMonitor extends AbstractPluginLifecycleMonitor { |
||||
@Override |
||||
public void afterRun(PluginContext pluginContext) { |
||||
MSConfig.getInstance(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void beforeStop(PluginContext pluginContext) { |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.HttpHandler; |
||||
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; |
||||
import com.fr.plugin.transform.ExecuteFunctionRecord; |
||||
import com.fr.plugin.transform.FunctionRecorder; |
||||
|
||||
@FunctionRecorder |
||||
/** |
||||
* url处理器需要在这里注册 |
||||
*/ |
||||
public class MSauth2HandlerProvider extends AbstractHttpHandlerProvider { |
||||
@Override |
||||
@ExecuteFunctionRecord |
||||
public HttpHandler[] registerHandlers() { |
||||
return new HttpHandler[]{ |
||||
new MSAuthCallbackApi() |
||||
}; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,26 @@
|
||||
package com.fr.plugin; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractURLAliasProvider; |
||||
import com.fr.decision.webservice.url.alias.URLAlias; |
||||
import com.fr.decision.webservice.url.alias.URLAliasFactory; |
||||
|
||||
/** |
||||
* 将长连接转换为短连接 |
||||
* 参考文档: |
||||
* https://wiki.fanruan.com/display/PD/com.fr.decision.fun.URLAliasProvider
|
||||
*/ |
||||
@Authorize(callSignKey = "com.eco.plugin.zzl.oauth2" ) |
||||
public class MSauth2URLAliasBridge extends AbstractURLAliasProvider |
||||
{ |
||||
public MSauth2URLAliasBridge() { |
||||
MSConfig.getInstance(); |
||||
} |
||||
|
||||
@Override |
||||
public URLAlias[] registerAlias() { |
||||
//像这样配置之后再访问/api就可以通过http(s)://ip:port/webroot/decision/url/api。 进行访问
|
||||
return new URLAlias[]{ |
||||
URLAliasFactory.createPluginAlias("/ms/authCallBack", "/authCallBack", true), |
||||
}; |
||||
} |
||||
} |
Loading…
Reference in new issue