diff --git a/JSD-8146-需求确认书V1.docx b/JSD-8146-需求确认书V1.docx
new file mode 100644
index 0000000..fc657ba
Binary files /dev/null and b/JSD-8146-需求确认书V1.docx differ
diff --git a/JSD-8146配置使用文档.docx b/JSD-8146配置使用文档.docx
new file mode 100644
index 0000000..a8cdaee
Binary files /dev/null and b/JSD-8146配置使用文档.docx differ
diff --git a/README.md b/README.md
index 34e8f89..4055d3d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-8146
-JSD-8146 开源任务材料
\ No newline at end of file
+JSD-8146 开源任务材料\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar
new file mode 100644
index 0000000..f4482fc
Binary files /dev/null and b/lib/finekit-10.0.jar differ
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..d8b9402
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,24 @@
+
+
+ com.fr.plugin.sso.auth
+
+ yes
+ 1.0.8
+ 10.0
+ 2018-07-31
+ fr.open
+
+
+ com.fr.plugin.sso
+
+ com.fanruan.api
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sso/LifeCycleMonitorImpl.java b/src/main/java/com/fr/plugin/sso/LifeCycleMonitorImpl.java
new file mode 100644
index 0000000..3654079
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sso/LifeCycleMonitorImpl.java
@@ -0,0 +1,34 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: LifeCycleMonitorImpl
+ * Author: Louis
+ * Date: 2021/3/30 15:10
+ */
+ package com.fr.plugin.sso;
+
+ import com.fr.plugin.context.PluginContext;
+ import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
+ import com.fr.plugin.sso.config.SsoConfig;
+
+ /**
+ *
+ *
+ *
+ * @author fr.open
+ * @since 1.0.0
+ */
+ public class LifeCycleMonitorImpl extends AbstractPluginLifecycleMonitor {
+ public LifeCycleMonitorImpl() {
+ }
+
+ @Override
+ public void afterRun(PluginContext pluginContext) {
+ SsoConfig.getInstance();
+ }
+
+ @Override
+ public void beforeStop(PluginContext pluginContext) {
+
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sso/LocaleFinder.java b/src/main/java/com/fr/plugin/sso/LocaleFinder.java
new file mode 100644
index 0000000..0cb36bb
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sso/LocaleFinder.java
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (C), 2018-2020
+ * Project: starter
+ * FileName: LocaleFinder
+ * Author: Louis
+ * Date: 2020/8/31 22:19
+ */
+ package com.fr.plugin.sso;
+
+ import com.fr.intelli.record.Focus;
+import com.fr.intelli.record.Original;
+import com.fr.record.analyzer.EnableMetrics;
+import com.fr.stable.fun.impl.AbstractLocaleFinder;
+
+import static com.fr.plugin.sso.config.SsoConfig.PLUGIN_ID;
+
+ /**
+ *
+ *
+ *
+ * @author fr.open
+ * @since 1.0.0
+ */
+ @EnableMetrics
+ public class LocaleFinder extends AbstractLocaleFinder {
+
+ @Override
+ @Focus(id = PLUGIN_ID, text = "Plugin-Sso", source = Original.PLUGIN)
+ public String find() {
+ return "com/fr/plugin/sso/locale/lang";
+ }
+
+ @Override
+ public int currentAPILevel() {
+ return CURRENT_LEVEL;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sso/config/SsoConfig.java b/src/main/java/com/fr/plugin/sso/config/SsoConfig.java
new file mode 100644
index 0000000..1ad33fa
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sso/config/SsoConfig.java
@@ -0,0 +1,88 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: OneAccessConfig
+ * Author: Louis
+ * Date: 2021/3/30 9:38
+ */
+ package com.fr.plugin.sso.config;
+
+ import com.fanruan.api.util.StringKit;
+ 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;
+
+ /**
+ *
+ *
+ *
+ * @author fr.open
+ * @since 1.0.0
+ */
+ @Visualization(category = "Plugin-Sso_Group")
+ public class SsoConfig extends DefaultConfiguration {
+ public static final String PLUGIN_ID = "com.fr.plugin.sso.auth";
+
+ private static volatile SsoConfig config = null;
+
+ @Focus(id = PLUGIN_ID, text = "Plugin-Sso", source = Original.PLUGIN)
+ public static SsoConfig getInstance() {
+ if (config == null) {
+ config = ConfigContext.getConfigInstance(SsoConfig.class);
+ }
+ return config;
+ }
+
+ @Identifier(value = "appId", name = "Plugin-Sso_Config_AppId", description = "Plugin-Sso_Config_AppId_Description", status = Status.SHOW)
+ private Conf appId = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "appKey", name = "Plugin-Sso_Config_AppKey", description = "Plugin-Sso_Config_AppKey_Description", status = Status.SHOW)
+ private Conf appKey = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "tokenUrl", name = "Plugin-Sso_Config_TokenUrl", description = "Plugin-Sso_Config_TokenUrl_Description", status = Status.SHOW)
+ private Conf tokenUrl = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "userInfoUrl", name = "Plugin-Sso_Config_UserInfoUrl", description = "Plugin-Sso_Config_UserInfoUrl_Description", status = Status.SHOW)
+ private Conf userInfoUrl = Holders.simple(StringKit.EMPTY);
+// @Identifier(value = "signOutUrl", name = "Plugin-Sso_Config_SignOutUrl", description = "Plugin-Sso_Config_SignOutUrl_Description", status = Status.SHOW)
+// private Conf signOutUrl = Holders.simple(StringKit.EMPTY);
+
+ public String getAppId() {
+ return appId.get();
+ }
+
+ public void setAppId(String appId) {
+ this.appId.set(appId);
+ }
+
+ public String getAppKey() {
+ return appKey.get();
+ }
+
+ public void setAppKey(String appKey) {
+ this.appKey.set(appKey);
+ }
+
+ public String getTokenUrl() {
+ return tokenUrl.get();
+ }
+
+ public void setTokenUrl(String tokenUrl) {
+ this.tokenUrl.set(tokenUrl);
+ }
+
+ public String getUserInfoUrl() {
+ return userInfoUrl.get();
+ }
+
+ public void setUserInfoUrl(String userInfoUrl) {
+ this.userInfoUrl.set(userInfoUrl);
+ }
+
+// public String getSignOutUrl() {
+// return signOutUrl.get();
+// }
+//
+// public void setSignOutUrl(String signOutUrl) {
+// this.signOutUrl.set(signOutUrl);
+// }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sso/request/TokenLogin.java b/src/main/java/com/fr/plugin/sso/request/TokenLogin.java
new file mode 100644
index 0000000..be2637d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sso/request/TokenLogin.java
@@ -0,0 +1,216 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: TokenLogin
+ * Author: Louis
+ * Date: 2021/3/30 22:09
+ */
+ package com.fr.plugin.sso.request;
+
+ import com.fanruan.api.decision.login.LoginKit;
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.net.NetworkKit;
+import com.fanruan.api.util.CodeKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.base.TemplateUtils;
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.decision.webservice.utils.DecisionServiceConstants;
+import com.fr.decision.webservice.v10.login.LoginService;
+import com.fr.json.JSONObject;
+import com.fr.plugin.sso.config.SsoConfig;
+import com.fr.plugin.sso.service.SsoService;
+import com.fr.stable.CodeUtils;
+import com.fr.stable.StringUtils;
+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.util.HashMap;
+import java.util.Map;
+
+ /**
+ *
+ *
+ *
+ * @author fr.open
+ * @since 1.0.0
+ */
+ public class TokenLogin extends AbstractGlobalRequestFilterProvider {
+ public static final String TPL_PATH = "/com/fr/plugin/sso/web/codePage.html";
+ public static final String REMOTE_DESIGN = "/remote/design";
+ public static final String RESOURCES_PATH = "/resources";
+ public static final String FILE_PATH = "/file";
+ public static final String SYSTEM_INFO = "/system/info";
+ public static final String SYSTEM_HEALTH = "/system/health";
+ public static final String MATERIALS_MIN_JS_MAP = "/materials.min.js.map";
+ public static final String LOGIN_PATH = "/login";
+ public static final String LOGIN_OTHER = "/login/";
+ public static final String LOGOUT_PATH = "/logout";
+ public static final String USER_LANGUAGE = "/v10/user/language";
+
+ public static final String SSO_CALLBACK = "/sso_callback";
+ public static final String CALLBACK = "callback";
+ public static final String SOURCE_URL = "sourceUrl";
+
+ private SsoService ssoService;
+
+ /**
+ * 过滤器名称
+ *
+ * @return
+ */
+ @Override
+ public String filterName() {
+ return "SsoFilter";
+ }
+
+ /**
+ * 过滤规则
+ *
+ * @return
+ */
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{"/*"};
+ }
+
+ /**
+ * 过滤器初始化
+ *
+ * @param filterConfig
+ */
+ @Override
+ public void init(FilterConfig filterConfig) {
+ ssoService = new SsoService();
+ super.init(filterConfig);
+ }
+
+ /**
+ * 过滤器处理
+ *
+ * @param request
+ * @param response
+ * @param filterChain
+ */
+ @Override
+ public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
+ try {
+ if (operation(request, response)) {
+ filterChain.doFilter(request, response);
+ }
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 用户验证登陆操作
+ *
+ * @param req
+ * @param res
+ * @throws Exception
+ */
+ private boolean operation(HttpServletRequest req, HttpServletResponse res) throws Exception {
+ String pathInfo = (req.getPathInfo() != null) ? req.getPathInfo() : StringKit.EMPTY;
+ LogKit.info("sso-TokenLogin-operation-pathInfo:{}", pathInfo);
+ if (pathInfo.startsWith(REMOTE_DESIGN) || pathInfo.startsWith(LOGIN_OTHER)
+ || StringKit.equals(LOGIN_PATH, pathInfo) || pathInfo.startsWith(SYSTEM_HEALTH)
+ || pathInfo.startsWith(RESOURCES_PATH) || pathInfo.startsWith(LOGOUT_PATH)
+ || pathInfo.startsWith(SYSTEM_INFO) || pathInfo.startsWith(MATERIALS_MIN_JS_MAP)
+ || pathInfo.startsWith(USER_LANGUAGE) || pathInfo.startsWith(FILE_PATH)) {
+ return true;
+ }
+ // 已登录
+ if (LoginService.getInstance().isLogged(req)) {
+ return true;
+ }
+ String callback = NetworkKit.getHTTPRequestParameter(req, CALLBACK);
+ if (StringKit.isBlank(callback)) {
+ loginPage(req, res);
+ return false;
+ }
+ if (!pathInfo.startsWith(SSO_CALLBACK)) {
+ return true;
+ }
+ String ip = ssoService.getIpAddr(req);
+ JSONObject ssoToken = ssoService.getSsoToken(callback, ip);
+ LogKit.error("sso-TokenLogin-operation-ssoToken:{}", ssoToken);
+ if (ssoToken == null || !StringKit.equals(ssoToken.getString("Success"), "true")) {
+ return true;
+ }
+ //获取单点登陆用户的相关信息
+ JSONObject ssoUserInfo = ssoService.getSsoUserInfo(ssoToken.getString("Message"), ip);
+ if (ssoUserInfo == null || !StringKit.equals(ssoUserInfo.getString("Success"), "true")) {
+ return true;
+ }
+ //往session设置ssoTokenMessage参数值
+ req.getSession().setAttribute("ssoTokenMessage", ssoToken.get("Message").toString());
+ //往session设置ssoUserInfo参数值
+ req.getSession().setAttribute("ssoUserInfo", ssoUserInfo);
+ String username = ssoUserInfo.get("AppAccount").toString();
+ if (StringKit.isBlank(username)) {
+ return true;
+ }
+ LogKit.error("sso-TokenLogin-operation-username:{}", username);
+ String tokenFR = LoginKit.login(req, res, username);
+ req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, tokenFR);
+ String sourceUrl = encodeViewlet(NetworkKit.getHTTPRequestParameter(req, SOURCE_URL));
+ LogKit.error("sso-TokenLogin-operation-sourceUrl:{}", sourceUrl);
+ res.sendRedirect(sourceUrl);
+ return false;
+ }
+
+ /**
+ * 登陆页面
+ *
+ * @param req
+ * @param res
+ * @return
+ * @throws Exception
+ */
+ private void loginPage(HttpServletRequest req, HttpServletResponse res) throws Exception {
+ Map parameterMap = new HashMap<>();
+ parameterMap.put("appId", SsoConfig.getInstance().getAppId());
+ parameterMap.put("sourceUrl", CodeKit.encodeURIComponent(getOriginalURL(req)));
+ String codePage = TemplateUtils.renderTemplate(TPL_PATH, parameterMap);
+ LogKit.info("sso-TokenLogin-loginPage-codePage:{}", codePage);
+ WebUtils.printAsString(res, codePage);
+ }
+
+ /**
+ * 得到请求url和参数
+ *
+ * @param request
+ * @return
+ */
+ private String getOriginalURL(HttpServletRequest request) {
+ StringBuffer url = request.getRequestURL();
+ if (StringKit.isNotBlank(request.getQueryString())) {
+ url.append("?").append(request.getQueryString());
+ }
+ return url.toString();
+ }
+
+ /**
+ * viewlet中文处理编码
+ *
+ * @param url
+ * @return
+ */
+ private String encodeViewlet(String url) {
+ if (StringKit.isBlank(url)) {
+ return url;
+ }
+ String paramViewlet = StringUtils.EMPTY;
+ if (url.contains("viewlet=")) {
+ paramViewlet = url.split("viewlet=")[1];
+ paramViewlet = paramViewlet.split("&")[0];
+ }
+ if (StringUtils.isNotEmpty(paramViewlet)) {
+ url = url.replaceFirst(paramViewlet, CodeUtils.encodeURIComponent(paramViewlet));
+ }
+ return url;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sso/service/SsoService.java b/src/main/java/com/fr/plugin/sso/service/SsoService.java
new file mode 100644
index 0000000..612cd8d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sso/service/SsoService.java
@@ -0,0 +1,171 @@
+package com.fr.plugin.sso.service;
+
+import com.fanruan.api.log.LogKit;
+import com.fr.json.JSONObject;
+import com.fr.plugin.sso.config.SsoConfig;
+import com.fr.plugin.sso.utils.HttpRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * 单点登录服务类
+ *
+ * @author
+ */
+public class SsoService {
+
+ /**
+ * 单点登陆系统appid
+ **/
+ private String appid;
+ /**
+ * 单点登陆系统appkey
+ **/
+ private String appkey;
+ /**
+ * 单点登陆系统tokenurl
+ **/
+ private String tokenurl;
+ /**
+ * 单点登陆系统userinfourl
+ **/
+ private String userinfourl;
+ /**
+ * 单点登陆系统signouturl
+ **/
+ private String signouturl;
+
+ public SsoService() {
+ //初始化加载配置文件中的相关信息
+ SsoConfig config = SsoConfig.getInstance();
+ appid = config.getAppId();
+ appkey = config.getAppKey();
+ tokenurl = config.getTokenUrl();
+ userinfourl = config.getUserInfoUrl();
+// signouturl = config.getSignOutUrl();
+ }
+
+ /**
+ * 获取单点登陆用户的相关信息
+ * 由于返回SsoUserInfo首字母大写,javabean处理不方便,直接使用map获取。
+ * 其中map中包括的数值有:
+ * boolean Success;
+ * String Message;
+ * String OpenID;
+ * String AppAccount;
+ * String EmpID;
+ * String Job;
+ * String Token;
+ * String UserName;
+ * String DepartmentID;
+ * String DepartmentName;
+ * String CompanyID;
+ * String CompanyName;
+ * String Title;
+ * String Office;
+ * boolean InService;
+ * 为支持jdk1.4版本,不使用泛型
+ *
+ * @param token 单点登陆系统token
+ * @param ip 用户IP
+ * @return
+ */
+ public JSONObject getSsoUserInfo(String token, String ip) {
+ String urlString = userinfourl + "?token=" + token + "&appid=" + appid
+ + "&appkey=" + appkey + "&ip=" + ip;
+ LogKit.error("sso-SsoService-getSsoUserInfo-urlString:{}", urlString);
+ try {
+ //获取返还信息
+ String json = HttpRequest.sendGet(urlString);
+ LogKit.error("sso-SsoService-getSsoUserInfo-json:{}", json);
+ // 对返回的JSON进行转换
+ if (json != null && !"".equals(json.trim())) {
+ return new JSONObject(json);
+ }
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+
+ /**
+ * 获取ssoToken ,callback是单点登录系统中返回的参数
+ * 由于返回token首字母大写,使用map获取。map包含的参数有:
+ * String Success;
+ * String Message;
+ * 为支持jdk1.4版本,不使用泛型
+ *
+ * @param callback
+ * @return
+ */
+ public JSONObject getSsoToken(String callback, String ip) {
+ String urlString = tokenurl + "?callback=" + callback + "&appid="
+ + appid + "&appkey=" + appkey + "&ip=" + ip;
+ LogKit.error("sso-SsoService-getSsoToken-urlString:{}", urlString);
+ try {
+ //获取返还信息
+ String json = HttpRequest.sendGet(urlString);
+ LogKit.error("sso-SsoService-getSsoToken-json:{}", json);
+ // 对返回的JSON进行转换
+ if (json != null && !"".equals(json.trim())) {
+ return new JSONObject(json);
+ }
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ } // 使用finally块来关闭输出流、输入流
+ return null;
+ }
+
+ /**
+ * 注销单点登陆
+ *
+ * @param token 单点登陆系统token
+ * @param ip 用户IP
+ * @return
+ */
+ public boolean signOut(String token, String ip) {
+ Map userInfo = null;
+ boolean returnFlag = false;
+ String urlString = signouturl + "?token=" + token + "&appid=" + appid
+ + "&appkey=" + appkey + "&ip=" + ip;
+ try {
+ //获取返还信息
+ String json = HttpRequest.sendGet(urlString);
+ //判断json是否是true
+ if (json != null && "true".equals(json.trim())) {
+ returnFlag = Boolean.valueOf(json).booleanValue();
+ }
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ return returnFlag;
+ }
+
+ /**
+ * 获取登录用户的IP地址
+ *
+ * @param request
+ * @return
+ */
+ public static String getIpAddr(HttpServletRequest request) {
+ String ip = request.getHeader("x-forwarded-for");
+ 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.getRemoteAddr();
+ }
+ if (ip.equals("0:0:0:0:0:0:0:1")) {
+ ip = "本地";
+ }
+ if (ip.split(",").length > 1) {
+ ip = ip.split(",")[0];
+ }
+ return ip;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sso/utils/HttpRequest.java b/src/main/java/com/fr/plugin/sso/utils/HttpRequest.java
new file mode 100644
index 0000000..2588df7
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sso/utils/HttpRequest.java
@@ -0,0 +1,164 @@
+package com.fr.plugin.sso.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * http请求工具类,为支持jdk1.4,不使用泛型
+ *
+ * @author
+ */
+public class HttpRequest {
+
+ /**
+ * 向指定 URL 发送POST方法的请求
+ *
+ * @param fullurl 完整的URL,可能包括一些参数如 ?a=B&c=D
+ * @return 所代表远程资源的响应结果
+ */
+ public static String sendGet(String fullurl) {
+ StringBuffer result = new StringBuffer();
+ BufferedReader in = null;
+ try {
+ String urlNameString = fullurl;
+ URL realUrl = new URL(urlNameString);
+ // 打开和URL之间的连接
+ URLConnection connection = realUrl.openConnection();
+ // 设置通用的请求属性
+ //connection.setRequestProperty("accept", "*/*");
+ //connection.setRequestProperty("connection", "Keep-Alive");
+ //connection.setRequestProperty("user-agent",
+ // "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+
+ // connection.setRequestProperty("Authorization", "Basic "+base64(user, password));
+
+ // 建立实际的连接
+ connection.connect();
+ // 获取所有响应头字段
+ Map map = connection.getHeaderFields();
+ // 遍历所有的响应头字段
+ //for (String key : map.keySet()) {
+ // System.out.println(key + "--->" + map.get(key));
+ //}
+ // 定义 BufferedReader输入流来读取URL的响应
+
+ in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result.append(line);
+ }
+ } catch (Exception e) {
+ System.err.println("发送GET请求出现异常!" + e);
+ e.printStackTrace();
+ }
+ // 使用finally块来关闭输入流
+ finally {
+ try {
+ if (in != null) {
+ in.close();
+ }
+ } catch (Exception e2) {
+ e2.printStackTrace();
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * 向指定 URL 发送POST方法的请求
+ *
+ * @param url 发送请求的 URL
+ * @param params 请求参数
+ * @return 所代表远程资源的响应结果
+ */
+ public static String sendPost(String url, HashMap params) {
+ PrintWriter out = null;
+ BufferedReader in = null;
+ StringBuffer result = new StringBuffer();
+
+ try {
+ URL realUrl = new URL(url);
+ // 打开和URL之间的连接
+ URLConnection connection = realUrl.openConnection();
+ // 设置通用的请求属性
+// connection.setRequestProperty("accept", "*/*");
+// connection.setRequestProperty("connection", "Keep-Alive");
+// connection.setRequestProperty("user-agent",
+// "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+
+ // connection.setRequestProperty("Authorization", "Basic "+base64(user, password));
+ connection.setRequestProperty("Accept-Charset", "utf-8");
+ connection.setRequestProperty("contentType", "utf-8");
+
+ // 发送POST请求必须设置如下两行
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ // 获取URLConnection对象对应的输出流
+
+ out = new PrintWriter(connection.getOutputStream());
+ // 发送请求参数
+ StringBuffer param = new StringBuffer();
+ for (Iterator iterator = params.keySet().iterator(); iterator.hasNext(); ) {
+ String key = (String) iterator.next();
+
+ Object obj = params.get(key);
+
+ if (obj == null) continue;
+
+ if (obj.getClass().isArray()) {
+ //数组的处理方式
+ Object[] objs = (Object[]) obj;
+
+ for (int i = 0; i < objs.length; i++) {
+ param.append(key).append("=").append(objs[i]);
+
+ param.append("&");
+ }
+ } else {
+ param.append(key).append("=").append(obj);
+ param.append("&");
+ }
+
+ }
+ out.print(param.toString());
+ // flush输出流的缓冲
+ out.flush();
+ // 定义BufferedReader输入流来读取URL的响应
+ in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+
+ String line;
+ while ((line = in.readLine()) != null) {
+ //result += line;
+ result.append(line);
+ }
+ } catch (Exception e) {
+ System.err.println("发送 POST 请求出现异常!" + e);
+ e.printStackTrace();
+
+ return "{\"success\": false, \"message\": \"" + e.getMessage() + "\" }";
+ }
+ // 使用finally块来关闭输出流、输入流
+ finally {
+ try {
+ if (out != null) {
+ out.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ return result.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/com/fr/plugin/sso/locale/lang.properties b/src/main/resources/com/fr/plugin/sso/locale/lang.properties
new file mode 100644
index 0000000..e79dd33
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/sso/locale/lang.properties
@@ -0,0 +1,12 @@
+Plugin-Sso=Sso Plugin
+Plugin-Sso_Group=Sso Plugin
+Plugin-Sso_Config_AppId=AppId
+Plugin-Sso_Config_AppId_Description=AppId
+Plugin-Sso_Config_AppKey=AppKey
+Plugin-Sso_Config_AppKey_Description=AppKey
+Plugin-Sso_Config_TokenUrl=TokenUrl
+Plugin-Sso_Config_TokenUrl_Description=TokenUrl
+Plugin-Sso_Config_UserInfoUrl=UserInfoUrl
+Plugin-Sso_Config_UserInfoUrl_Description=UserInfoUrl
+Plugin-Sso_Config_SignOutUrl=SignOutUrl
+Plugin-Sso_Config_SignOutUrl_Description=SignOutUrl
\ No newline at end of file
diff --git a/src/main/resources/com/fr/plugin/sso/locale/lang_zh_CN.properties b/src/main/resources/com/fr/plugin/sso/locale/lang_zh_CN.properties
new file mode 100644
index 0000000..3686cce
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/sso/locale/lang_zh_CN.properties
@@ -0,0 +1,12 @@
+Plugin-Sso=\u5355\u70B9\u767B\u9646\u63D2\u4EF6
+Plugin-Sso_Group=\u5355\u70B9\u767B\u9646\u63D2\u4EF6
+Plugin-Sso_Config_AppId=\u5E06\u8F6F\u7CFB\u7EDF\u4EE3\u7801APPID
+Plugin-Sso_Config_AppId_Description=\u5E06\u8F6F\u7CFB\u7EDF\u4EE3\u7801APPID
+Plugin-Sso_Config_AppKey=\u5E06\u8F6F\u7CFB\u7EDFAPPKEY
+Plugin-Sso_Config_AppKey_Description=\u5E06\u8F6F\u7CFB\u7EDFAPPKEY
+Plugin-Sso_Config_TokenUrl=Token\u63A5\u53E3\u5730\u5740
+Plugin-Sso_Config_TokenUrl_Description=Token\u63A5\u53E3\u5730\u5740
+Plugin-Sso_Config_UserInfoUrl=UserInfo\u63A5\u53E3\u5730\u5740
+Plugin-Sso_Config_UserInfoUrl_Description=UserInfo\u63A5\u53E3\u5730\u5740
+Plugin-Sso_Config_SignOutUrl=\u767B\u51FA\u5730\u5740
+Plugin-Sso_Config_SignOutUrl_Description=\u767B\u51FA\u5730\u5740
\ No newline at end of file
diff --git a/src/main/resources/com/fr/plugin/sso/web/codePage.html b/src/main/resources/com/fr/plugin/sso/web/codePage.html
new file mode 100644
index 0000000..5e783a4
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/sso/web/codePage.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ 登陆中
+
+
+
+
+
+
+登陆
+
+
+
\ No newline at end of file