diff --git a/JSD-7565需求确认书.docx b/JSD-7565需求确认书.docx
new file mode 100644
index 0000000..1b2e293
Binary files /dev/null and b/JSD-7565需求确认书.docx differ
diff --git a/README.md b/README.md
index 344f3a2..df53d49 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-7565
-JSD-7565 第三方token交换fine_auth_token
\ No newline at end of file
+JSD-7565 第三方token交换fine_auth_token\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..4890a75
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,18 @@
+
+
+ com.fr.plugin.nfsq.sso
+
+ yes
+ 1.19
+ 10.0
+ 2018-07-31
+ fr.open
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/DesECBUtil.java b/src/main/java/com/fr/plugin/nfsq/sso/DesECBUtil.java
new file mode 100644
index 0000000..34afd35
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/DesECBUtil.java
@@ -0,0 +1,64 @@
+package com.fr.plugin.nfsq.sso;
+
+import com.fr.third.org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.Key;
+
+/**
+ * @author fr.open
+ * @date 2019/1/18
+ */
+public class DesECBUtil {
+ /**
+ * 加密数据
+ *
+ * @param encryptString
+ * @param encryptKey
+ * @return
+ * @throws Exception
+ */
+ public static String encryptDES(String encryptString, String encryptKey) throws Exception {
+ Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(getKey(encryptKey), "DES"));
+ byte[] encryptedData = cipher.doFinal(encryptString.getBytes("UTF-8"));
+ return Base64.encodeBase64String(encryptedData);
+ }
+
+ /**
+ * key 不足8位补位
+ *
+ * @param
+ */
+ public static byte[] getKey(String keyRule) {
+ Key key = null;
+ byte[] keyByte = keyRule.getBytes();
+ // 创建一个空的八位数组,默认情况下为0
+ byte[] byteTemp = new byte[8];
+ // 将用户指定的规则转换成八位数组
+ for (int i = 0; i < byteTemp.length && i < keyByte.length; i++) {
+ byteTemp[i] = keyByte[i];
+ }
+ key = new SecretKeySpec(byteTemp, "DES");
+ return key.getEncoded();
+ }
+
+ /***
+ * 解密数据
+ * @param decryptString
+ * @param decryptKey
+ * @return
+ * @throws Exception
+ */
+
+ public static String decryptDES(String decryptString, String decryptKey) throws Exception {
+ byte[] sourceBytes = Base64.decodeBase64(decryptString);
+ Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(getKey(decryptKey), "DES"));
+ byte[] decoded = cipher.doFinal(sourceBytes);
+ return new String(decoded, "UTF-8");
+
+ }
+}
+
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/HttpUtil.java b/src/main/java/com/fr/plugin/nfsq/sso/HttpUtil.java
new file mode 100644
index 0000000..0b3f04f
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/HttpUtil.java
@@ -0,0 +1,479 @@
+package com.fr.plugin.nfsq.sso;
+
+import com.fr.json.JSONObject;
+import com.fr.log.FineLoggerFactory;
+import com.fr.stable.StringUtils;
+import com.fr.third.org.apache.http.HttpResponse;
+import com.fr.third.org.apache.http.HttpStatus;
+import com.fr.third.org.apache.http.NameValuePair;
+import com.fr.third.org.apache.http.client.HttpClient;
+import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
+import com.fr.third.org.apache.http.client.methods.HttpPost;
+import com.fr.third.org.apache.http.client.methods.HttpPut;
+import com.fr.third.org.apache.http.config.Registry;
+import com.fr.third.org.apache.http.config.RegistryBuilder;
+import com.fr.third.org.apache.http.conn.socket.ConnectionSocketFactory;
+import com.fr.third.org.apache.http.conn.socket.LayeredConnectionSocketFactory;
+import com.fr.third.org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import com.fr.third.org.apache.http.conn.ssl.SSLContexts;
+import com.fr.third.org.apache.http.conn.ssl.TrustStrategy;
+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.HttpClientBuilder;
+import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import com.fr.third.org.apache.http.message.BasicNameValuePair;
+import com.fr.third.org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author fr.open
+ * @date 2019/4/2
+ */
+public class HttpUtil {
+
+ private static HostnameVerifier hv = new HostnameVerifier() {
+ @Override
+ public boolean verify(String urlHostName, SSLSession session) {
+ System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ + session.getPeerHost());
+ return true;
+ }
+ };
+
+ /**
+ * 发送get请求
+ *
+ * @param url
+ * @param param
+ * @param header
+ * @return
+ * @throws IOException
+ */
+ public static String sendGet(String url, Map param, Map header, String charset) {
+ String result = "";
+ BufferedReader in = null;
+ String urlNameString = url;
+ try {
+ if (param != null && !param.isEmpty()) {
+ urlNameString += "?";
+ urlNameString += param.entrySet()
+ .stream()
+ .map(entry -> entry.getKey() + "=" + entry.getValue().toString())
+ .collect(Collectors.joining("&"));
+ }
+
+ URL realUrl = new URL(urlNameString);
+ // 打开和URL之间的连接
+ HttpURLConnection connection;
+ if (url.startsWith("https")) {
+ trustAllHttpsCertificates();
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ connection = (HttpURLConnection) realUrl.openConnection();
+ } else {
+ connection = (HttpURLConnection) realUrl.openConnection();
+ }
+ //设置超时时间
+ connection.setDoInput(true);
+ connection.setRequestMethod("GET");
+ connection.setConnectTimeout(5000);
+ connection.setReadTimeout(15000);
+ // 设置通用的请求属性
+ if (header != null) {
+ Iterator> it = header.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = it.next();
+ System.out.println(entry.getKey() + ":::" + entry.getValue());
+ connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
+ }
+ }
+ 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.connect();
+ if(connection.getResponseCode() == 200){
+ // 定义 BufferedReader输入流来读取URL的响应,设置utf8防止中文乱码
+ in = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset == null ? "utf-8" : charset));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result += line;
+ }
+ if (in != null) {
+ in.close();
+ }
+ }else {
+ in = new BufferedReader(new InputStreamReader(connection.getErrorStream(), charset == null ? "utf-8" : charset));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result += line;
+ }
+ if (in != null) {
+ in.close();
+ }
+ FineLoggerFactory.getLogger().error("Http post form code is {},message is {}",connection.getResponseCode(),result);
+ return StringUtils.EMPTY;
+ }
+
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e, "get url error ,url is:{},error is {}", urlNameString, e.getMessage());
+ }
+ return result;
+ }
+
+ public static String sendPost(String url, Map header, JSONObject body) {
+ PrintWriter out = null;
+ BufferedReader in = null;
+ String result = null;
+ String res = null;
+ try {
+ String urlNameString = url;
+
+ URL realUrl = new URL(urlNameString);
+ // 打开和URL之间的连接
+ HttpURLConnection conn;
+ if (url.startsWith("https")) {
+ trustAllHttpsCertificates();
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ conn = (HttpURLConnection) realUrl.openConnection();
+ } else {
+ conn = (HttpURLConnection) realUrl.openConnection();
+ }
+ // 设置通用的请求属性
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestProperty("connection", "Keep-Alive");
+// conn.setRequestProperty("user-agent",
+// "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
+ if (header != null) {
+ header.forEach((k, v) -> {
+ conn.setRequestProperty(k, String.valueOf(v));
+ });
+ }
+ // 发送POST请求必须设置如下两行
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ //获取请求头
+
+ // 获取URLConnection对象对应的输出流
+ out = new PrintWriter(conn.getOutputStream());
+ // 发送请求参数
+ if (body != null) {
+ FineLoggerFactory.getLogger().error("content data: {}", body.toString());
+ FineLoggerFactory.getLogger().error("content cover data: {}", new String(body.toString().getBytes("UTF-8"), "UTF-8"));
+ out.print(new String(body.toString().getBytes("UTF-8"), "UTF-8"));
+ }
+ // flush输出流的缓冲
+ out.flush();
+ // 定义BufferedReader输入流来读取URL的响应
+ in = new BufferedReader(
+ new InputStreamReader(conn.getInputStream()));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result += line;
+ }
+ res = result;
+ if (res.startsWith("null")) {
+ res = res.replace("null", "");
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ //使用finally块来关闭输出流、输入流
+ finally {
+ try {
+ if (out != null) {
+ out.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+ return res;
+ }
+
+
+ public static String doJSONPost(String url, Map header, JSONObject json, Map param, String chartset) {
+ HttpClient client = getHttpsClient();
+ /*if (url.startsWith("https")) {
+ SSLContext sslcontext = createIgnoreVerifySSL();
+ Registry socketFactoryRegistry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.INSTANCE)
+ .register("https", new SSLConnectionSocketFactory(sslcontext))
+ .build();
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+ HttpClients.custom().setConnectionManager(connManager);
+ client = HttpClients.custom().setConnectionManager(connManager).build();
+ }*/
+ if (param != null && !param.isEmpty()) {
+ url += "?";
+ url += param.entrySet()
+ .stream()
+ .map(entry -> entry.getKey() + "=" + entry.getValue())
+ .collect(Collectors.joining("&"));
+ }
+ HttpPost post = new HttpPost(url);
+ post.setHeader("accept", "*/*");
+ post.setHeader("connection", "Keep-Alive");
+ post.setHeader("Content-Type", "application/json");
+ if (header != null) {
+ header.forEach((k, v) -> {
+ post.setHeader(k, v.toString());
+ });
+ }
+ try {
+ StringEntity s = new StringEntity(json.toString(), chartset == null ? "UTF-8" : chartset);
+ s.setContentEncoding("UTF-8");
+ s.setContentType("application/json; charset=UTF-8");//发送json数据需要设置contentType
+ post.setEntity(s);
+ HttpResponse res = client.execute(post);
+ if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ String result = EntityUtils.toString(res.getEntity());// 返回json格式:
+ return result;
+ } else {
+ FineLoggerFactory.getLogger().error("Http post form code is {},message is {}", res.getStatusLine().getStatusCode(), EntityUtils.toString(res.getEntity()));
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ public static String doJSONPut(String url, Map header, JSONObject json, Map param, String chartset) {
+ HttpClient client = getHttpsClient();
+ /*if (url.startsWith("https")) {
+ SSLContext sslcontext = createIgnoreVerifySSL();
+ Registry socketFactoryRegistry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.INSTANCE)
+ .register("https", new SSLConnectionSocketFactory(sslcontext))
+ .build();
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+ HttpClients.custom().setConnectionManager(connManager);
+ client = HttpClients.custom().setConnectionManager(connManager).build();
+ }*/
+ if (param != null && !param.isEmpty()) {
+ url += "?";
+ url += param.entrySet()
+ .stream()
+ .map(entry -> entry.getKey() + "=" + entry.getValue())
+ .collect(Collectors.joining("&"));
+ }
+ HttpPut post = new HttpPut(url);
+ post.setHeader("accept", "*/*");
+ post.setHeader("connection", "Keep-Alive");
+ post.setHeader("Content-Type", "application/json");
+ if (header != null) {
+ header.forEach((k, v) -> {
+ post.setHeader(k, v.toString());
+ });
+ }
+ try {
+ StringEntity s = new StringEntity(json.toString(), chartset == null ? "UTF-8" : chartset);
+ s.setContentEncoding("UTF-8");
+ s.setContentType("application/json; charset=UTF-8");//发送json数据需要设置contentType
+ post.setEntity(s);
+ HttpResponse res = client.execute(post);
+ if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ String result = EntityUtils.toString(res.getEntity());// 返回json格式:
+ return result;
+ } else {
+ FineLoggerFactory.getLogger().error("Http post form code is {},message is {}", res.getStatusLine().getStatusCode(), EntityUtils.toString(res.getEntity()));
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+
+ public static String doFormPost(String url,Map header, Map map, String chartset) {
+ //声明返回结果
+ String result = "";
+ UrlEncodedFormEntity entity = null;
+ HttpResponse httpResponse = null;
+ HttpClient httpClient = null;
+ try {
+ // 创建连接
+ httpClient = getHttpsClient();
+ ;
+ /*if (url.startsWith("https")) {
+ SSLContext sslcontext = createIgnoreVerifySSL();
+ Registry socketFactoryRegistry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.INSTANCE)
+ .register("https", new SSLConnectionSocketFactory(sslcontext))
+ .build();
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+ HttpClients.custom().setConnectionManager(connManager);
+ httpClient = HttpClients.custom().setConnectionManager(connManager).build();
+ }*/
+ // 设置请求头和报文
+ HttpPost httpPost = new HttpPost(url);
+ if (header != null) {
+ header.forEach((k, v) -> {
+ httpPost.setHeader(k, v.toString());
+ });
+ }
+ //设置参数
+ List list = new ArrayList();
+ Iterator iterator = map.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry elem = (Map.Entry) iterator.next();
+ list.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
+ }
+ entity = new UrlEncodedFormEntity(list, chartset == null ? "UTF-8" : chartset);
+ httpPost.setEntity(entity);
+ //执行发送,获取相应结果
+ httpResponse = httpClient.execute(httpPost);
+ if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ result = EntityUtils.toString(httpResponse.getEntity());
+ } else {
+ FineLoggerFactory.getLogger().error("Http post form code is {},message is {}", httpResponse.getStatusLine().getStatusCode(), EntityUtils.toString(httpResponse.getEntity()));
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return result;
+
+ }
+
+ private static void trustAllHttpsCertificates() throws Exception {
+ TrustManager[] trustAllCerts = new TrustManager[1];
+ TrustManager tm = new miTM();
+ trustAllCerts[0] = tm;
+ SSLContext sc = SSLContext.getInstance("SSL", "SunJSSE");
+ sc.init(null, trustAllCerts, null);
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ }
+
+
+ /**
+ * encode url by UTF-8
+ *
+ * @param url url before encoding
+ * @return url after encoding
+ */
+ public static String encodeUrl(String url) {
+ String eurl = url;
+ try {
+ eurl = URLEncoder.encode(url, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ }
+ return eurl;
+ }
+
+ private static class miTM implements TrustManager,
+ X509TrustManager {
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public boolean isServerTrusted(
+ java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ public boolean isClientTrusted(
+ java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ @Override
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType)
+ throws CertificateException {
+ return;
+ }
+
+ @Override
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType)
+ throws CertificateException {
+ return;
+ }
+ }
+
+ public static SSLContext createIgnoreVerifySSL() {
+ try {
+ SSLContext sc = SSLContext.getInstance("TLSv1.2");
+
+ // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
+ X509TrustManager trustManager = new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
+ String paramString) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
+ String paramString) throws CertificateException {
+ }
+
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ };
+
+ sc.init(null, new TrustManager[]{trustManager}, null);
+ return sc;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ private static CloseableHttpClient getHttpsClient() {
+ RegistryBuilder registryBuilder = RegistryBuilder.create();
+ ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
+ registryBuilder.register("http", plainSF);
+ // 指定信任密钥存储对象和连接套接字工厂
+ try {
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ // 信任任何链接
+ TrustStrategy anyTrustStrategy = new TrustStrategy() {
+
+ @Override
+ public boolean isTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException {
+ // TODO Auto-generated method stub
+ return true;
+ }
+ };
+ SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, anyTrustStrategy).build();
+ LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ registryBuilder.register("https", sslSF);
+ } catch (KeyStoreException e) {
+ throw new RuntimeException(e);
+ } catch (KeyManagementException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ Registry registry = registryBuilder.build();
+ // 设置连接管理器
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
+ // 构建客户端
+ return HttpClientBuilder.create().setConnectionManager(connManager).build();
+
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/Params.java b/src/main/java/com/fr/plugin/nfsq/sso/Params.java
new file mode 100644
index 0000000..d38cf13
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/Params.java
@@ -0,0 +1,40 @@
+package com.fr.plugin.nfsq.sso;
+
+/**
+ * @Author fr.open
+ * @Date 2021/5/10
+ * @Description
+ **/
+public class Params {
+
+ private String username;
+
+ private String accessToken;
+
+ private String refreshToken;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ public String getRefreshToken() {
+ return refreshToken;
+ }
+
+ public void setRefreshToken(String refreshToken) {
+ this.refreshToken = refreshToken;
+ }
+
+}
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/SsoFilter.java b/src/main/java/com/fr/plugin/nfsq/sso/SsoFilter.java
new file mode 100644
index 0000000..554d33e
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/SsoFilter.java
@@ -0,0 +1,537 @@
+package com.fr.plugin.nfsq.sso;
+
+import com.fr.base.TemplateUtils;
+import com.fr.data.NetworkHelper;
+import com.fr.decision.authority.data.User;
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.decision.mobile.terminal.TerminalHandler;
+import com.fr.decision.webservice.bean.authentication.LoginRequestInfoBean;
+import com.fr.decision.webservice.exception.user.UserNotExistException;
+import com.fr.decision.webservice.utils.DecisionServiceConstants;
+import com.fr.decision.webservice.utils.DecisionStatusService;
+import com.fr.decision.webservice.v10.login.LoginService;
+import com.fr.decision.webservice.v10.login.TokenResource;
+import com.fr.decision.webservice.v10.user.UserService;
+import com.fr.general.http.HttpRequest;
+import com.fr.general.http.HttpToolbox;
+import com.fr.io.utils.ResourceIOUtils;
+import com.fr.json.JSONObject;
+import com.fr.log.FineLoggerFactory;
+import com.fr.plugin.transform.FunctionRecorder;
+import com.fr.stable.StringUtils;
+import com.fr.stable.web.Device;
+import com.fr.web.utils.WebUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.time.Instant;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @Author fr.open
+ * @Date 2020/9/10
+ * @Description
+ **/
+@FunctionRecorder
+public class SsoFilter extends AbstractGlobalRequestFilterProvider {
+
+ private final String CODE_KEY = "90bb6046";
+
+ @Override
+ public String filterName() {
+ return "nongfu";
+ }
+
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{"/*"};
+ }
+
+ private static final String[] NOT_FILTER = {
+ "/decision/file",
+ "/decision/resources",
+ "/system",
+ "/materials.min.js.map",
+ "/remote",
+ "/login",
+ "/login/config",
+ "/getFineToken"
+ };
+
+ private String apiAuthorize;
+
+ private String apiAuthorizeResponseType;
+
+ private String apiClientId;
+
+ private String apiGetUser;
+
+ private String apiRefreshToken;
+
+ private String state;
+
+ public SsoFilter() {
+ InputStream in = ResourceIOUtils.read("/resources/xplatform.properties");
+ Properties properties = new Properties();
+ try {
+ properties.load(in);
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ this.apiAuthorize = properties.getProperty("api.authorize");
+ this.apiClientId = properties.getProperty("api.authorize.client_id");
+ this.apiAuthorizeResponseType = properties.getProperty("api.authorize.response_type");
+ this.apiGetUser = properties.getProperty("api.get-user");
+ this.apiRefreshToken = properties.getProperty("api.refresh-token");
+ this.state = properties.getProperty("api.authorize.state");
+ }
+
+
+ @Override
+ public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
+ String thisUrl = req.getRequestURL().toString();
+ FineLoggerFactory.getLogger().info("This request [{}] login status is [{}]", thisUrl, isLogin(req));
+ if (req.getRequestURI().endsWith("auth")) {
+ executeGetAuth(req, res);
+ return;
+ }
+ String code = req.getParameter("sign");
+ if (StringUtils.isNotBlank(code)) {
+ loginFromCode(code, req, res);
+ filter(req, res, filterChain);
+ return;
+ }
+ if (Stream.of(NOT_FILTER).anyMatch(thisUrl::contains) || isLogin(req) || isMobileDevice(req)) {
+ filter(req, res, filterChain);
+ return;
+ }
+ String prefix = null;
+ try {
+ prefix = TemplateUtils.render("${fineServletURL}");
+ if (req.getRequestURI().endsWith(prefix + "/login")) {
+ if (handlerWeChat(req, res)) {
+ return;
+ }
+ filter(req, res, filterChain);
+ return;
+ }
+
+ }catch (IllegalAccessException e){
+ redirectAuth(req, res);
+ return;
+ }catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ Params params = null;
+ try {
+ params = getUsername(req);
+ } catch (IllegalAccessException e) {
+ redirectAuth(req, res);
+ return;
+ }
+ FineLoggerFactory.getLogger().info("Getted username is [{}]", params.getUsername());
+ if (StringUtils.isNotBlank(params.getUsername())) {
+ Cookie at = new Cookie("access_token", params.getAccessToken());
+ at.setDomain("xxxx");
+ at.setMaxAge(7200);
+ Cookie rt = new Cookie("refresh_token", params.getRefreshToken());
+ rt.setDomain("xxxx");
+ rt.setMaxAge(7200);
+ res.addCookie(at);
+ res.addCookie(rt);
+ loginFromToken(req, res, params.getUsername());
+ try {
+ res.sendRedirect(getRedirectUriWithCachedParams(req));
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return;
+ }
+ redirectAuth(req, res);
+ }
+
+ private void redirectAuth(HttpServletRequest req, HttpServletResponse res) {
+ try {
+ res.sendRedirect(getAuthorizeUrl(req,res));
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ }
+
+ private boolean handlerWeChat(HttpServletRequest request, HttpServletResponse res) throws IOException, IllegalAccessException {
+ // 有帆软的登录信息
+ if (isLogin(request)) {
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> 已登录");
+ String token = getAccessToken(request);
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> token value is [{}]", token);
+ // 没有获取到access_token
+ if (StringUtils.isBlank(token)) {
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> token value is empty, 不做处理");
+ return false;
+ }
+ // 获取到了access_token, 比对帆软已登录的用户名和access_token对应的用户名
+ String username = getUsername(request, token).getUsername();
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> token 对应的用户名[{}]", username);
+ String username1 = LoginService.getInstance().getUserNameFromRequestCookie(request);
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> 已登录的用户名[{}]", username1);
+ if (Objects.equals(username1, username)) {
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> 两个用户名相同, 不做处理");
+ return false;
+ }
+ // 不一样的话使用access_token对应的用户名重新登录
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> 两个用户名不相同, 使用[{}]重新登录", username);
+ loginFromToken(request, res, username);
+ return false;
+ }
+
+ // 没有登录信息
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> 未登录");
+ String token = getAccessToken(request);
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> token value is [{}]", token);
+ if (StringUtils.isNotBlank(token)) {
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> token value is not empty, 处理自动登录逻辑");
+ Params params = getUsername(request, token);
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> 获取到的用户名[{}]", params.getUsername());
+ if (StringUtils.isNotBlank(params.getUsername()) && exist(params.getUsername())) {
+ Cookie at = new Cookie("access_token", params.getAccessToken());
+ at.setDomain("yst.com.cn");
+ Cookie rt = new Cookie("refresh_token", params.getRefreshToken());
+ rt.setDomain("yst.com.cn");
+ loginFromToken(request, res, params.getUsername());
+ res.sendRedirect(getRedirectUriWithCachedParams(request));
+ return true;
+ }
+ }
+ FineLoggerFactory.getLogger().info("/decision请求特殊处理 >>> token value is empty, 跳转到sso登录页");
+ res.sendRedirect(getAuthorizeUrl(request, res));
+ return true;
+ }
+
+ private String getAuthorizeUrl(HttpServletRequest request, HttpServletResponse res) throws UnsupportedEncodingException {
+ String urlPattern = "%s?response_type=%s&client_id=%s&redirect_uri=%s&_=%s&state=%s";
+ String state = cacheParams(request);
+ res.addCookie(new Cookie("FINE_REDIRECT_PARAM",state));
+ if (StringUtils.isNotBlank(state)) {
+ urlPattern += "&target=" + state;
+ }
+ String url = String.format(urlPattern,
+ apiAuthorize,
+ apiAuthorizeResponseType,
+ apiClientId,
+ URLEncoder.encode(request.getRequestURL().toString(), "utf-8"),
+ Instant.now().toEpochMilli(),
+ this.state
+ );
+ FineLoggerFactory.getLogger().info("授权登录页面[{}]", url);
+ return url;
+ }
+
+ private String cacheParams(HttpServletRequest request) {
+ Enumeration names = request.getParameterNames();
+ Map value = new HashMap<>();
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ value.put(name, request.getParameter(name));
+ }
+ if (value.isEmpty()) {
+ return StringUtils.EMPTY;
+ }
+ String key = UUID.randomUUID().toString();
+ try {
+ DecisionStatusService.originUrlStatusService().put(key, value);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return key;
+ }
+
+ /**
+ * 登录成功后将缓存中存储的url参数拼接入对应地址
+ *
+ * @param request
+ * @return
+ */
+
+
+ private String getRedirectUriWithCachedParams(HttpServletRequest request) {
+ String redirectUri = request.getRequestURL().toString();
+ String key = request.getParameter("target");
+ if(StringUtils.isBlank(key)){
+ key = getCookieValue(request, "FINE_REDIRECT_PARAM");
+ }
+ if(StringUtils.isBlank(key)){
+ return redirectUri;
+ }
+ Map value = new HashMap<>();
+ try {
+ value = DecisionStatusService.originUrlStatusService().get(key);
+ if (com.fr.stable.StringUtils.isNotBlank(key) && !value.isEmpty()) {
+ DecisionStatusService.originUrlStatusService().delete(key);
+ Map finalValue = value;
+ redirectUri += "?" + value.keySet().stream().map(k -> String.format("%s=%s", k, finalValue.get(k))).collect(Collectors.joining("&"));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return redirectUri;
+ }
+
+
+ private boolean exist(String username) {
+ User user = null;
+ try {
+ user = UserService.getInstance().getUserByUserName(username);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return user != null;
+ }
+
+ private Params getUsername(HttpServletRequest request) throws IllegalAccessException {
+ String token = getAccessToken(request);
+ if(StringUtils.isBlank(token)){
+ FineLoggerFactory.getLogger().info("token is null");
+ return new Params();
+ }
+ return getUsername(request, token);
+ }
+
+ private Params getUsername(HttpServletRequest request, String accessToken) throws IllegalAccessException {
+ String url = apiGetUser + "?access_token=" + accessToken;
+ FineLoggerFactory.getLogger().info("Get user api address is [{}]", url);
+ try {
+ String res = HttpToolbox.executeAndParse(HttpRequest.custom().url(url)
+ .get()
+ .build());
+ FineLoggerFactory.getLogger().info("获取用户信息接口返回内容 ==> {}", res);
+ JSONObject body = new JSONObject(res);
+ if (body.getBoolean("success") && body.has("data")) {
+ body = body.getJSONObject("data");
+ if (body.has("account")) {
+ Params params = new Params();
+ params.setRefreshToken(getRefreshToken(request));
+ params.setUsername(body.getString("account"));
+ params.setAccessToken(accessToken);
+ return params;
+ }
+ }
+ if (body.has("message") && "token不合法".equals(body.getString("message"))) {
+ FineLoggerFactory.getLogger().info("Access Token [{}] 不合法, 使用Refresh Token[{}]重新获取", accessToken, getRefreshToken(request));
+ accessToken = getAccessTokenWithRefreshToken(request);
+ return getUsername(request, accessToken);
+ }
+ throw new IllegalAccessException();
+ }catch (IllegalAccessException e){
+ throw new IllegalAccessException();
+ }catch (Exception e) {
+ FineLoggerFactory.getLogger().error("获取用户名失败", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String getAccessTokenWithRefreshToken(HttpServletRequest request) throws Exception {
+ String url = apiRefreshToken + String.format("?refresh_token=%s&client_id=%s&grant_type=refresh_token", getRefreshToken(request), apiClientId);
+ FineLoggerFactory.getLogger().info("Refresh Token api address is [{}]", url);
+ String res = HttpToolbox.executeAndParse(HttpRequest.custom().url(url)
+ .get()
+ .build());
+ FineLoggerFactory.getLogger().info("刷新token接口返回内容 ==> {}", res);
+ JSONObject body = new JSONObject(res);
+ if (body.getBoolean("success") && body.has("data")) {
+ body = body.getJSONObject("data");
+ if (body.has("access_token")) {
+ return body.getString("access_token");
+ }
+ }
+ throw new IllegalAccessException();
+ }
+
+ private String getRefreshToken(HttpServletRequest request) {
+ return getValueFromRequest(request, "refresh_token");
+ }
+
+ private String getAccessToken(HttpServletRequest request) {
+ return getValueFromRequest(request, "access_token");
+ }
+
+ private String getValueFromRequest(HttpServletRequest request, String key) {
+ try {
+ String value = request.getParameter(key);
+ if (StringUtils.isEmpty(value)) {
+ value = getCookieValue(request, key);
+ }
+ if (StringUtils.isEmpty(value)) {
+ String params = request.getParameter("app");
+ params = params.substring(params.indexOf("#") + 1);
+ Map values = Pattern.compile("&").splitAsStream(params).map(e -> e.split("=")).collect(Collectors.toMap(e -> e[0], e -> e[1]));
+ value = values.get(key);
+ }
+ return value;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error("Failed to get \"{}\" value from this request, cause by: ", key, e.getMessage());
+ FineLoggerFactory.getLogger().error("", e);
+ }
+ return "";
+ }
+
+ private String getCookieValue(HttpServletRequest request, String key) {
+ Cookie[] cookies = request.getCookies();
+ for (Cookie c : cookies) {
+ if (StringUtils.equals(c.getName(), key)) {
+ return c.getValue();
+ }
+ }
+ return StringUtils.EMPTY;
+ }
+
+ private void loginFromCode(String code, HttpServletRequest req, HttpServletResponse res) {
+ FineLoggerFactory.getLogger().info("ssoFilter >>> inside login code param is {}", code);
+ try {
+ code = DesECBUtil.decryptDES(code, CODE_KEY);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ FineLoggerFactory.getLogger().info("ssoFilter >>> inside login code decode is {}", code);
+ String[] arr = code.split("_");
+ loginFromToken(req, res, arr[0]);
+ }
+
+ private void executeGetAuth(HttpServletRequest req, HttpServletResponse res) {
+ String uri = WebUtils.getHTTPRequestParameter(req, "redirect_uri");
+ String currentUsername = null;
+ try {
+ User user= null;
+ try {
+ user = UserService.getInstance().getUserByRequest(req);
+ }catch (Exception e){
+
+ }
+ if(user == null){
+ user = UserService.getInstance().getUserByRequestCookie(req);
+ }
+ currentUsername = user.getUserName();
+ String encryptDES = DesECBUtil.encryptDES(String.format("%s_%d", currentUsername, Instant.now().toEpochMilli()), CODE_KEY);
+ encryptDES = URLEncoder.encode(encryptDES, "UTF-8");
+ uri = uri.indexOf("?") == -1 ? uri + "?sign=" + encryptDES : uri + "&sign=" + encryptDES;
+ res.sendRedirect(uri);
+ FineLoggerFactory.getLogger().info("ssoFilter >>> inside redirect url is {}", uri);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+
+ private boolean notExistUser(String username) {
+ User user = null;
+ try {
+ user = UserService.getInstance().getUserByUserName(username);
+ if (user == null) {
+ return true;
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return false;
+ }
+
+ private boolean hasCookie(HttpServletRequest req) {
+ if (req.getCookies() == null) {
+ return false;
+ }
+ return Stream.of(req.getCookies()).anyMatch(e -> "IAM_SESSION".equalsIgnoreCase(e.getName()));
+ }
+
+ public LoginRequestInfoBean getLoginInfo(HttpServletRequest req) {
+ try {
+ BufferedReader br = req.getReader();
+ String str = "";
+ String listString = "";
+ while ((str = br.readLine()) != null) {
+ listString += str;
+ }
+ JSONObject jsonObject = new JSONObject(listString);
+ LoginRequestInfoBean info = jsonObject.mapTo(LoginRequestInfoBean.class);
+ //info.setPassword(TransmissionTool.decrypt(info.isEncrypted(),info.getPassword()));
+ return info;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return null;
+
+ }
+
+ private boolean loginFromToken(HttpServletRequest req, HttpServletResponse res, String username) {
+ try {
+ if (StringUtils.isNotEmpty(username)) {
+ FineLoggerFactory.getLogger().info("current username:" + username);
+ User user = UserService.getInstance().getUserByUserName(username);
+ FineLoggerFactory.getLogger().info("get user:" + user);
+ if (user == null) {
+ throw new UserNotExistException();
+ }
+ String token = LoginService.getInstance().login(req, res, username);
+ FineLoggerFactory.getLogger().info("get login token:" + token);
+ req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
+ FineLoggerFactory.getLogger().info("username:" + username + "login success");
+ return true;
+ } else {
+ FineLoggerFactory.getLogger().warn("username is null!");
+ return false;
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return false;
+ }
+
+ private void filter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
+ try {
+ filterChain.doFilter(req, res);
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ } catch (ServletException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+
+ private boolean isLogin(HttpServletRequest request) {
+ String oldToken = TokenResource.COOKIE.getToken(request);
+ return oldToken != null && checkTokenValid(request, (String) oldToken);
+ }
+
+ private boolean checkTokenValid(HttpServletRequest req, String token) {
+ try {
+ Device device = NetworkHelper.getDevice(req);
+ LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
+ return true;
+ } catch (Exception ignore) {
+ }
+ return false;
+ }
+
+ public boolean isMobileDevice(HttpServletRequest request) {
+ String requestHeader = request.getHeader("user-agent");
+ String[] deviceArray = new String[]{"android", "iphone", "ios", "windows phone"};
+ if (requestHeader == null) {
+ return false;
+ }
+ requestHeader = requestHeader.toLowerCase();
+ for (int i = 0; i < deviceArray.length; i++) {
+ if (requestHeader.contains(deviceArray[i]) && request.getRequestURI().endsWith("/login")) {
+ FineLoggerFactory.getLogger().info("current request:{} is mobile request!", request.getRequestURI());
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/SsoHttpHandler.java b/src/main/java/com/fr/plugin/nfsq/sso/SsoHttpHandler.java
new file mode 100644
index 0000000..4ee2691
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/SsoHttpHandler.java
@@ -0,0 +1,103 @@
+package com.fr.plugin.nfsq.sso;
+
+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.general.PropertiesUtils;
+import com.fr.json.JSONObject;
+import com.fr.log.FineLoggerFactory;
+import com.fr.record.analyzer.EnableMetrics;
+import com.fr.stable.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;
+
+/**
+ * @author fr.open
+ * @since 2020/08/28
+ */
+@EnableMetrics
+public class SsoHttpHandler extends BaseHttpHandler {
+
+ private String apiUser = "";
+
+ public SsoHttpHandler() {
+ apiUser = PropertiesUtils.getProperties("xplatform").getProperty("api.get-user");
+ }
+
+ @Override
+ public RequestMethod getMethod() {
+ return RequestMethod.GET;
+ }
+
+ @Override
+ public String getPath() {
+ return "/getFineToken";
+ }
+
+ @Override
+ public boolean isPublic() {
+ return true;
+ }
+
+ @Override
+ public void handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ if (StringUtils.isBlank(apiUser)) {
+ sendError(response, "apiUser config is null");
+ return;
+ }
+ String token = request.getParameter("access_token");
+ if (StringUtils.isBlank(token)) {
+ sendError(response, "token is null");
+ return;
+ }
+ String userName = getUsername(token);
+ if (StringUtils.isBlank(userName)) {
+ sendError(response, "get user is null");
+ return;
+ }
+ User user = UserService.getInstance().getUserByUserName(userName);
+ FineLoggerFactory.getLogger().info("get user:" + user);
+ if (user == null) {
+ sendError(response, "user not exist");
+ }
+ String fineToken = LoginService.getInstance().login(request, response, userName);
+ JSONObject jsonObject = new JSONObject("{\"codeDesc\":\"success\",\"success\":true,\"codeNum\":0}");
+ jsonObject.put("value", JSONObject.create().put("fine_oath_token", fineToken));
+ response.setContentType("application/json;charset=UTF-8");
+ WebUtils.printAsJSON(response, jsonObject);
+ }
+
+ private String getUsername(String accessToken) {
+ String url = apiUser + "?access_token=" + accessToken;
+ FineLoggerFactory.getLogger().info("Get user api address is [{}]", url);
+ try {
+ String res = HttpUtil.sendGet(url, null, null, null);
+ FineLoggerFactory.getLogger().info("获取用户信息接口返回内容 ==> {}", res);
+ JSONObject body = new JSONObject(res);
+ if (body.getBoolean("success") && body.has("data")) {
+ body = body.getJSONObject("data");
+ if (body.has("account")) {
+ return body.getString("account");
+ }
+ }
+ throw new IllegalAccessException();
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error("获取用户名失败", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected void sendError(HttpServletResponse response, String errorCode) {
+ JSONObject jsonObject = new JSONObject("{\"codeDesc\":\"" + errorCode + "\",\"success\":false,\"codeNum\":70}");
+ try {
+ response.setContentType("application/json;charset=UTF-8");
+ WebUtils.printAsJSON(response, jsonObject);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error("输出响应错误失败", e);
+ }
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/SsoRequestHandlerBridge.java b/src/main/java/com/fr/plugin/nfsq/sso/SsoRequestHandlerBridge.java
new file mode 100644
index 0000000..2173b60
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/SsoRequestHandlerBridge.java
@@ -0,0 +1,19 @@
+package com.fr.plugin.nfsq.sso;
+
+import com.fr.decision.fun.HttpHandler;
+import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
+import com.fr.plugin.transform.FunctionRecorder;
+
+/**
+ * @author fr.open
+ * @since 2020/08/28
+ */
+@FunctionRecorder
+public class SsoRequestHandlerBridge extends AbstractHttpHandlerProvider {
+ @Override
+ public HttpHandler[] registerHandlers() {
+ return new HttpHandler[]{
+ new SsoHttpHandler(),
+ };
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nfsq/sso/SsoRequestURLAliasBridge.java b/src/main/java/com/fr/plugin/nfsq/sso/SsoRequestURLAliasBridge.java
new file mode 100644
index 0000000..78b9b71
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nfsq/sso/SsoRequestURLAliasBridge.java
@@ -0,0 +1,18 @@
+package com.fr.plugin.nfsq.sso;
+
+import com.fr.decision.fun.impl.AbstractURLAliasProvider;
+import com.fr.decision.webservice.url.alias.URLAlias;
+import com.fr.decision.webservice.url.alias.URLAliasFactory;
+
+/**
+ * @author fr.open
+ * @since 2020/08/28
+ */
+public class SsoRequestURLAliasBridge extends AbstractURLAliasProvider {
+ @Override
+ public URLAlias[] registerAlias() {
+ return new URLAlias[]{
+ URLAliasFactory.createPluginAlias("/getFineToken", "/getFineToken", true),
+ };
+ }
+}