Browse Source

open

master
pioneer 2 years ago
commit
0d2bb31029
  1. 6
      README.md
  2. BIN
      doc/.~用户整体对接方案.docx
  3. BIN
      doc/oauth单点使用文档.docx
  4. BIN
      lib/finekit-10.0-20200828.jar
  5. 20
      plugin.xml
  6. 692
      src/main/java/com/fr/plugin/HttpUtils.java
  7. 82
      src/main/java/com/fr/plugin/XTLConfig.java
  8. 331
      src/main/java/com/fr/plugin/XTLCookieFilter.java
  9. 15
      src/main/java/com/fr/plugin/XTLHttpHander.java
  10. 16
      src/main/java/com/fr/plugin/XTLLifeCycleMonitor.java
  11. 26
      src/main/java/com/fr/plugin/XTLURLAliasBridge.java
  12. 170
      src/main/java/com/fr/plugin/handler/LoginCallBackHander.java

6
README.md

@ -0,0 +1,6 @@
# open-JSD-9681
JSD-9681 与客户认证系统做单点\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
doc/.~用户整体对接方案.docx

Binary file not shown.

BIN
doc/oauth单点使用文档.docx

Binary file not shown.

BIN
lib/finekit-10.0-20200828.jar

Binary file not shown.

20
plugin.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.plugin.xtl.login</id>
<name><![CDATA[xxx登录Oauth2]]></name>
<active>yes</active>
<version>1.0.6</version>
<env-version>10.0</env-version>
<jartime>2020-07-31</jartime>
<vendor>fr.open</vendor>
<lifecycle-monitor class="com.fr.plugin.XTLLifeCycleMonitor"/>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.XTLCookieFilter"/>
<!-- 长连接 -->
<HttpHandlerProvider class="com.fr.plugin.XTLHttpHander"/>
<!-- 短连接 -->
<URLAliasProvider class="com.fr.plugin.XTLURLAliasBridge"/>
</extra-decision>
<function-recorder class="com.fr.plugin.XTLURLAliasBridge"/>
</plugin>

692
src/main/java/com/fr/plugin/HttpUtils.java

@ -0,0 +1,692 @@
package com.fr.plugin;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.http.*;
import com.fr.third.org.apache.http.client.*;
import com.fr.third.org.apache.http.client.config.RequestConfig;
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.client.methods.HttpPost;
import com.fr.third.org.apache.http.client.utils.URIBuilder;
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.PlainConnectionSocketFactory;
import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import com.fr.third.org.apache.http.entity.ByteArrayEntity;
import com.fr.third.org.apache.http.impl.client.BasicCookieStore;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import com.fr.third.org.apache.http.message.BasicNameValuePair;
import com.fr.third.org.apache.http.util.CharArrayBuffer;
import com.fr.third.org.apache.http.util.EntityUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HttpUtils {
private static final Log logger = LogFactory.getLog(HttpUtils.class);
public CookieStore cookieStore = new BasicCookieStore();
private CloseableHttpClient getHttpClientSSL() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext sslcontext = null;
try {
sslcontext = createIgnoreVerifySSL();
} catch (Exception ex) {
//logger.error(ex.getMessage());
}
Registry<ConnectionSocketFactory> socketFactoryRegistry;
if (sslcontext != null)
socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslcontext))
.build();
else
socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(30000)
.setConnectTimeout(30000)
.setConnectionRequestTimeout(30000)
.setStaleConnectionCheckEnabled(true)
.build();
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connManager)
.setDefaultCookieStore(cookieStore)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
return client;
}
private CloseableHttpClient getHttpClient() throws Exception {
SSLContext sslcontext = createIgnoreVerifySSL();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setStaleConnectionCheckEnabled(true)
.build();
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connManager)
.setDefaultCookieStore(cookieStore)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
return client;
}
/**
* get请求参数放在map里
*
* @param url 请求地址
* @param param 参数map
* @return 响应
*/
public String getData(String url, Map<String, String> param, Map<String, String> headers) {
String result = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
URIBuilder builder = new URIBuilder(url);
for (Map.Entry<String, String> entry : param.entrySet()) {
builder.addParameter(entry.getKey(), entry.getValue());
}
HttpGet get = new HttpGet(builder.build());
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
get.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(get);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* get请求参数放在map里
*
* @param url
* @param param
* @return
*/
public String getData(String url, Map<String, String> param) {
return getData(url, param, null);
}
public String getDataSSL(String url, Map<String, String> param) throws Exception {
return getDataSSL(url, param, null);
}
/**
* SSL协议 get请求参数放在map里
*
* @param url 请求地址
* @param param 参数map
* @return 响应
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String getDataSSL(String url, Map<String, String> param, Map<String, String> headers) throws KeyManagementException, NoSuchAlgorithmException {
String result = null;
CloseableHttpClient httpClient = getHttpClientSSL();
CloseableHttpResponse response = null;
try {
URIBuilder builder = new URIBuilder(url);
for (Map.Entry<String, String> entry : param.entrySet()) {
builder.addParameter(entry.getKey(), entry.getValue());
}
HttpGet get = new HttpGet(builder.build());
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
get.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(get);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (Exception e) {
logger.error("请求地址:" + url + ",请求参数:" + param + ",响应数据:" + result);
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* SSL协议 get请求参数放在map里 参数直接拼接在url后面
*
* @param url 请求地址
* @param param 参数map
* @return 响应
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String getDataSSLUrl(String url, Map<String, String> param, Map<String, String> headers) throws KeyManagementException, NoSuchAlgorithmException {
String result = null;
CloseableHttpClient httpClient = getHttpClientSSL();
CloseableHttpResponse response = null;
try {
StringBuilder stringBuilder = new StringBuilder();
if (param != null)
for (Map.Entry<String, String> entry : param.entrySet()) {
stringBuilder.append(entry.getKey());
if (entry.getValue() != null)
stringBuilder.append("=").append(entry.getValue());
stringBuilder.append("&");
}
if (stringBuilder.length() > 0)
url = addUrlParam(url, stringBuilder.substring(0, stringBuilder.length() - 1));
URIBuilder builder = new URIBuilder(url);
// for(Map.Entry<String,String> entry : param.entrySet())
// {
// builder.addParameter(entry.getKey(),entry.getValue());
// }
//
//
HttpGet get = new HttpGet(builder.build());
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
get.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(get);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (Exception e) {
logger.error("请求地址:" + url + ",请求参数:" + param + ",响应数据:" + result);
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 发送post请求参数用map接收
*
* @param url 地址
* @param param 参数
* @return 返回值
*/
public String postData(String url, Map<String, String> param, Map<String, String> headers) {
String result = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : param.entrySet()) {
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
CloseableHttpResponse response = null;
try {
post.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
post.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(post);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 发送post请求参数用map接收
*
* @param url 地址
* @param param 参数
* @return 返回值
*/
public String postData(String url, Map<String, String> param) {
return postData(url, param, null);
}
/**
* SSL协议发送post请求参数用map接收
*
* @param url 地址
* @param param 参数
* @return 返回值
*/
public String postDataSSL(String url, Map<String, String> param) throws KeyManagementException, NoSuchAlgorithmException {
return postDataSSL(url, param, null);
}
/**
* SSL协议发送post请求参数用map接收
*
* @param url 地址
* @param param 参数
* @return 返回值
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String postDataSSL(String url, Map<String, String> param, Map<String, String> headers) throws KeyManagementException, NoSuchAlgorithmException {
String result = null;
CloseableHttpClient httpClient = getHttpClientSSL();
HttpPost post = new HttpPost(url);
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : param.entrySet()) {
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
CloseableHttpResponse response = null;
try {
post.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
post.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(post);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* post请求参数为json字符串
*
* @param url 请求地址
* @param jsonString json字符串
* @return 响应
*/
public String postJsonData(String url, String jsonString) {
return postJsonData(url, jsonString, null);
}
/**
* post请求参数为json字符串
*
* @param url 请求地址
* @param jsonString json字符串
* @return 响应
*/
public String postJsonData(String url, String jsonString, Map<String, String> headers) {
String result = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
try {
post.setEntity(new ByteArrayEntity(jsonString.getBytes("UTF-8")));
post.setHeader("Content-type", "application/json");
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
post.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(post);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* post请求参数为json字符串
*
* @param url 请求地址
* @param jsonString json字符串
* @return 响应
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String postJsonDataSSL(String url, String jsonString, Map<String, String> headers) throws KeyManagementException, NoSuchAlgorithmException {
String result = null;
CloseableHttpClient httpClient = getHttpClientSSL();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
try {
post.setEntity(new ByteArrayEntity(jsonString.getBytes("UTF-8")));
post.setHeader("Content-type", "application/json");
if (headers != null)
for (Map.Entry<String, String> entry : headers.entrySet()) {
post.setHeader(entry.getKey(), entry.getValue());
}
response = httpClient.execute(post);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
result = entityToString(entity);
}
return result;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private String entityToString(HttpEntity entity) throws IOException {
String result = null;
if (entity != null) {
long lenth = entity.getContentLength();
if (lenth != -1 && lenth < 2048) {
result = EntityUtils.toString(entity, "UTF-8");
} else {
InputStreamReader reader1 = new InputStreamReader(entity.getContent(), "UTF-8");
CharArrayBuffer buffer = new CharArrayBuffer(2048);
char[] tmp = new char[1024];
int l;
while ((l = reader1.read(tmp)) != -1) {
buffer.append(tmp, 0, l);
}
result = buffer.toString();
}
}
return result;
}
/**
* 绕过验证
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSLv3");
// 实现一个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;
}
private static byte[] getbytes(InputStream is) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
byte[] b = new byte[2048];
int n = 0;
while ((n = is.read(b)) != -1) {
bos.write(b, 0, n);
}
return bos.toByteArray();
} catch (Exception e) {
} finally {
try {
if (is != null) {
is.close();
}
} catch (Exception e) {
}
try {
if (bos != null) {
bos.close();
}
} catch (Exception e) {
}
}
return null;
}
/**
* 根据url下载文件保存到filepath中
*
* @param url
* @param param
* @return
*/
public boolean downloadFile(String url, OutputStream stream, Map<String, String> param, Map<String, String> headers) {
try {
CloseableHttpClient httpClient = getHttpClientSSL();
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpClient.execute(httpget);
//info.setResult(result);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
byte[] buffer = new byte[10 * 1024];
int ch = 0;
while ((ch = is.read(buffer)) != -1) {
stream.write(buffer, 0, ch);
}
is.close();
stream.flush();
stream.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据url下载文件保存到filepath中
*
* @param url
* @param filepath
* @return
*/
public boolean downloadFile(String url, String filepath, Map<String, String> param, Map<String, String> headers) {
try {
CloseableHttpClient httpClient = getHttpClientSSL();
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpClient.execute(httpget);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
//String str=response.getHeaders("Content-disposition");
File file = new File(filepath);
file.getParentFile().mkdirs();
FileOutputStream fileout = new FileOutputStream(file);
byte[] buffer = new byte[10 * 1024];
int ch = 0;
while ((ch = is.read(buffer)) != -1) {
fileout.write(buffer, 0, ch);
}
is.close();
fileout.flush();
fileout.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 链接地址后追加参数
*/
public static String addUrlParam(String url, String... param) {
if (param != null) {
for (String str : param)
if (StringUtils.isNotBlank(str)) {
if (url.indexOf("?") >= 0) {
url += "&" + str;
} else {
url += "?" + str;
}
}
}
return url;
}
}

82
src/main/java/com/fr/plugin/XTLConfig.java

@ -0,0 +1,82 @@
package com.fr.plugin;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
@Visualization(category = "xxx单点配置")
public class XTLConfig extends DefaultConfiguration {
private static volatile XTLConfig config = null;
public static XTLConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(XTLConfig.class);
}
return config;
}
@Identifier(value = "valAddr", name = "统一用户地址", description = "接口地址", status = Status.SHOW)
private Conf<String> valAddr = Holders.simple("http://manage.suntien.com:7926/SSO");
@Identifier(value = "appid", name = "应用被推颁发的ClientId", description = "应用被推颁发的AppID", status = Status.SHOW)
private Conf<String> appid = Holders.simple("xxx");
@Identifier(value = "loginClientSecret", name = "Client_secret", description = "Secret", status = Status.SHOW)
private Conf<String> loginClientSecret = Holders.simple("xxx");
@Identifier(value = "frUrl", name = "当前fr系统地址", description = "", status = Status.SHOW)
private Conf<String> frUrl = Holders.simple("http://xxx/webroot/decision");
@Identifier(value = "loginAppid", name = "业务系统唯一标识码", description = "应用被推颁发的AppID", status = Status.SHOW)
private Conf<String> loginAppid = Holders.simple("xxx");
public String getFrUrl() {
return frUrl.get();
}
public void setFrUrl(String frUrl) {
this.frUrl.set(frUrl);
}
public String getLoginClientSecret() {
return loginClientSecret.get();
}
public void setLoginClientSecret(String loginClientSecret) {
this.loginClientSecret.set(loginClientSecret);
}
public String getAppid() {
return appid.get();
}
public void setAppid(String appid) {
this.appid.set(appid);
}
public String getValAddr() {
return valAddr.get();
}
public void setValAddr(String valAddr) {
this.valAddr.set(valAddr);
}
public String getLoginAppid() {
return loginAppid.get();
}
public void setLoginAppid(String loginAppid) {
this.loginAppid .set(loginAppid); ;
}
@Override
public Object clone() throws CloneNotSupportedException {
XTLConfig cloned = (XTLConfig) super.clone();
cloned.valAddr = (Conf<String>) valAddr.clone();
cloned.loginAppid = (Conf<String>) loginAppid.clone();
cloned.appid = (Conf<String>) appid.clone();
cloned.loginClientSecret = (Conf<String>) loginClientSecret.clone();
cloned.frUrl = (Conf<String>) frUrl.clone();
return cloned;
}
}

331
src/main/java/com/fr/plugin/XTLCookieFilter.java

@ -0,0 +1,331 @@
package com.fr.plugin;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.net.http.HttpKit;
import com.fr.base.ServerConfig;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
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.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.stable.StringUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
public class XTLCookieFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "xtlfilter";
}
@Override
public String[] urlPatterns() {
return new String[]{
"/*"
};
}
@Override
public void init(FilterConfig filterConfig) {
XTLConfig.getInstance();
FineLoggerFactory.getLogger().info("登录Oauth2初始化");
super.init(filterConfig);
}
static String AuthCookieName = "tyyh_token";
static String FRCookieName = "fr_ttyh_token";
private boolean isLogOut(HttpServletRequest req) {
String url = WebUtils.getOriginalURL(req);
String servletNamePrefix = "/" + ServerConfig.getInstance().getServletName() + "/logout";
return url.contains(servletNamePrefix) && req.getMethod().equals("POST");
}
private String deleteCookieByName(HttpServletRequest request, HttpServletResponse response, String name) {
Cookie[] cookies = request.getCookies();
if (null == cookies) {
FineLoggerFactory.getLogger().info("没有cookie");
} else {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
String cookieValue = cookie.getValue();
//设置值为null
cookie.setValue(null);
//立即销毁cookie
cookie.setMaxAge(0);
cookie.setPath("/");
FineLoggerFactory.getLogger().info("被删除的cookie名字为:{}", cookie.getName(), cookieValue);
response.addCookie(cookie);
return cookieValue;
}
}
}
return "";
}
private void callLogout(String token){
XTLConfig xtlConfig = XTLConfig.getInstance();
String url = String.format("%s/api/verification/loginOut", xtlConfig.getValAddr());
HttpUtils httpUtils = new HttpUtils();
JSONObject entries = new JSONObject();
entries.put("token", token);
String resp = httpUtils.postJsonData(url, entries.toString());
LogKit.info("登出对方接口提示:{}", resp);
}
private void delLoginOut(HttpServletRequest req, HttpServletResponse res) {
try {
//执行帆软内部的退出
LoginService.getInstance().logout(req, res);
XTLConfig xtlConfig = XTLConfig.getInstance();
String frUrl = URLEncoder.encode(xtlConfig.getFrUrl(),"UTF-8");
String callBack = String.format("%s/user/login?BackAddr=%s",xtlConfig.getValAddr(),frUrl);
JSONObject jsonObject = new JSONObject();
String token = deleteCookieByName(req, res, FRCookieName);
deleteCookieByName(req, res, AuthCookieName);
if (StringUtils.isNotBlank(token)) {
callLogout(token);
}
jsonObject.put("data", callBack);
//调用外部接口注销accessToken
FineLoggerFactory.getLogger().error("登出成功: ----------------");
//指定退出之后到他们登录页面
WebUtils.printAsJSON(res, jsonObject);
} catch (Exception var4) {
}
}
private boolean isLoginRequest(HttpServletRequest req) {
if (req == null) {
return false;
}
if (!"GET".equalsIgnoreCase(req.getMethod())) {
return false;
}
String url = req.getRequestURL().toString();
if (url.endsWith("/decision/login") || url.endsWith("/decision/login/")) {
return true;
}
return false;
}
@Override
@ExecuteFunctionRecord
public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) {
try {
if(isLogOut(request)){
delLoginOut(request, httpServletResponse);
return;
}
if(isLoginRequest(request)){
String isAdmin = request.getParameter("isAdmin");
if (StringUtils.equals(isAdmin,"1")) {
request.getSession(true).setAttribute("adminLogin",true);
}
}
if (needFilter(request)) {
Map<String, String> cookies = getCookies(request);
//校验是否本地有cookies
String value;
if (cookies.containsKey(AuthCookieName) && (value = cookies.get(AuthCookieName)) != null) {
if (cookies.containsKey(FRCookieName) && StringUtils.equals(cookies.get(FRCookieName), value) && isLogin(request)) {
//如果登陆了就继续后续流程,如果没有登录还要去校验token走流程
filterChain.doFilter(request, httpServletResponse);
return;
}
//本地不存在FRCookieName或者两个不一致,就去验证AuthCookieName
Boolean success = checkCookies(value);
if (success) {
//通过token获取code,code换用户信息
boolean loginSuccess = loginByToken(value, request, httpServletResponse);
if(loginSuccess){
setCookie(httpServletResponse, FRCookieName, value);
}
}
}else{
if(isLogin(request)){
//登出系统
LoginService.getInstance().crossDomainLogout(request, httpServletResponse, "xx");
deleteCookieByName(request, httpServletResponse, FRCookieName);
}
}
if(!isLogin(request)){
//校验token失败跳转去登陆页面
String originalURL = WebUtils.getOriginalURL(request);
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String encode = URLEncoder.encode(originalURL, "UTF-8");
String format = String.format("%s/user/login?BackAddr=%s", valAddr, encode);
sendRedirect(httpServletResponse, format);
return;
}
}
filterChain.doFilter(request, httpServletResponse);
} catch (IOException | ServletException e) {
printException2FrLog(e);
} catch (Exception e) {
printException2FrLog(e);
}
}
private boolean loginByToken(String token, HttpServletRequest req, HttpServletResponse res) throws Exception {
String code = getCode(token);
String accessToken = getAccessToken(code);
String userId = getUserId(accessToken);
UserService userService = UserService.getInstance();
User user = userService.getUserByUserName(userId);
if (user != null) {
login(req, res, userId);
return true;
} else {
WebUtils.printAsString(res, "用户" + userId + "在帆软系统中不存在");
return false;
}
}
private Boolean checkCookies(String value) {
XTLConfig xtlConfig = XTLConfig.getInstance();
String url = String.format("%s/api/verification/verificationLogin", xtlConfig.getValAddr());
JSONObject entries = new JSONObject();
entries.put("joinsysCode", xtlConfig.getLoginAppid());
entries.put("cookie", value);
HttpUtils httpUtils = new HttpUtils();
String resp = httpUtils.postJsonData(url, entries.toString());
JSONObject respJson = new JSONObject(resp);
String code = respJson.getString("code");
return StringUtils.equals(code, "200");
}
private String getUserId(String accessToken) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String url = String.format("%s/api/getUserInfo", valAddr);
Map<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer " + accessToken);
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getUserInfo返回:{}", resp);
JSONObject entries = new JSONObject(resp);
return entries.getString("userId");
}
private String getAccessToken(String code) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String frUrl = xtlConfig.getFrUrl() + "/url/oauth2/login";
String appid = xtlConfig.getAppid();
String loginClientSecret = xtlConfig.getLoginClientSecret();
String url = String.format("%s/api/oauth/getAccessToken?redirect_uri=%s&" +
"client_id=%s&" +
"client_secret=%s&code=%s&grant_type=authorization_code", valAddr, frUrl, appid, loginClientSecret, code);
Map<String, String> header = new HashMap<>();
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getAccessToken返回:{}", resp);
JSONObject entries = new JSONObject(resp);
int code1 = entries.getInt("code");
if (code1 == 200) {
return entries.getJSONObject("data").getString("access_token");
}
return "";
}
private String getCode(String token) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String loginAppid = xtlConfig.getLoginAppid();
String url = String.format("%s/api/oauth/getCode?joinsysCode=%s", valAddr, loginAppid);
Map<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer " + token);
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getCode返回:{}", resp);
JSONObject entries = new JSONObject(resp);
int code = entries.getInt("code");
if (code == 200) {
return entries.getString("msg");
}
return "";
}
private static void setCookie(HttpServletResponse response, String name, String value) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
response.addCookie(cookie);
}
private Map<String, String> getCookies(HttpServletRequest request) {
Map<String, String> cookieMap = new HashMap<String, String>();
Cookie[] cookies = request.getCookies();
if (null != cookies) {
for (Cookie cookie : cookies) {
cookieMap.put(cookie.getName(), cookie.getValue());
}
}
return cookieMap;
}
private void sendRedirect(HttpServletResponse res, String url) {
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
res.setHeader("Location", url);
}
private boolean needFilter(HttpServletRequest request) {
String requestURI = request.getRequestURI();
Object adminLogin = request.getSession().getAttribute("adminLogin");
if (adminLogin != null) {
return false;
}
if (StringUtils.isNotBlank(requestURI)) {
if (requestURI.endsWith("decision")) {
return true;
}
if (requestURI.endsWith("/view/form") || requestURI.endsWith("/view/report")) {
if (StringUtils.isNotBlank(request.getParameter("viewlet"))) {
return true;
}
}
if (requestURI.contains("/v5/design/report") && (requestURI.endsWith("/edit")|| requestURI.endsWith("/view"))) {
return true;
}
}
return false;
}
public static void printException2FrLog(Throwable e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String s = writer.toString();
FineLoggerFactory.getLogger().error("错误:{}", s);
}
private void login(HttpServletRequest req, HttpServletResponse res, String username) {
String token = null;
try {
UserService userService = UserService.getInstance();
User user = userService.getUserByUserName(username);
if (user != null) {
token = LoginService.getInstance().login(req, res, username);
req.setAttribute("fine_auth_token", token);
}
FineLoggerFactory.getLogger().error("login success");
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineLoggerFactory.getLogger().error("login failed");
}
}
private boolean isLogin(HttpServletRequest req) {
return LoginService.getInstance().isLogged(req);
}
}

15
src/main/java/com/fr/plugin/XTLHttpHander.java

@ -0,0 +1,15 @@
package com.fr.plugin;
import com.fr.decision.fun.HttpHandler;
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
import com.fr.plugin.handler.LoginCallBackHander;
public class XTLHttpHander extends AbstractHttpHandlerProvider {
private HttpHandler[] actions = new HttpHandler[]{new LoginCallBackHander() };
@Override
public HttpHandler[] registerHandlers() {
return actions;
}
}

16
src/main/java/com/fr/plugin/XTLLifeCycleMonitor.java

@ -0,0 +1,16 @@
package com.fr.plugin;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
public class XTLLifeCycleMonitor extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
XTLConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
}

26
src/main/java/com/fr/plugin/XTLURLAliasBridge.java

@ -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;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.plugin.transform.FunctionRecorder;
/**
* 将长连接转换为短连接
* 参考文档
* https://wiki.fanruan.com/display/PD/com.fr.decision.fun.URLAliasProvider
*/
@FunctionRecorder
public class XTLURLAliasBridge extends AbstractURLAliasProvider
{
@Override
@ExecuteFunctionRecord
public URLAlias[] registerAlias() {
//像这样配置之后再访问/api就可以通过http(s)://ip:port/webroot/decision/url/api。 进行访问
return new URLAlias[]{
URLAliasFactory.createPluginAlias("/oauth2/login", "/login", true),
};
}
}

170
src/main/java/com/fr/plugin/handler/LoginCallBackHander.java

@ -0,0 +1,170 @@
package com.fr.plugin.handler;
import com.fanruan.api.net.http.HttpKit;
import com.fr.data.NetworkHelper;
import com.fr.decision.authority.data.User;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.decision.mobile.terminal.TerminalHandler;
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.ComparatorUtils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.XTLConfig;
import com.fr.security.JwtUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.third.jodd.util.StringUtil;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class LoginCallBackHander extends BaseHttpHandler {
@Override
public RequestMethod getMethod() {
return null;
}
@Override
public String getPath() {
return "/login";
}
@Override
public boolean isPublic() {
return true;
}
@Override
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
String token = req.getParameter("token");
if (StringUtils.isNotBlank(token)) {
String code = getCode(token);
if (StringUtils.isEmpty(code)) {
WebUtils.printAsString(res, " 通过" + token + "获取code失败返回内容无效");
return;
}
String accessToken = getAccessToken(code);
if (StringUtils.isEmpty(accessToken)) {
WebUtils.printAsString(res, " 通过" + token + "获取accessToken失败返回内容无效");
return;
}
String userId = getUserId(accessToken);
if (StringUtils.isEmpty(userId)) {
WebUtils.printAsString(res, " 通过" + accessToken + "获取用户失败返回内容无效");
return;
}
UserService userService = UserService.getInstance();
User user = userService.getUserByUserName(userId);
if (user != null) {
login(req, res, userId);
XTLConfig xtlConfig = XTLConfig.getInstance();
String frUrl = xtlConfig.getFrUrl();
sendRedirect(res, frUrl);
return;
} else {
WebUtils.printAsString(res, "用户" + userId + "在帆软系统中不存在");
return;
}
}
WebUtils.printAsString(res, " 没有token信息");
}
private String getUserId(String accessToken) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String url = String.format("%s/getUserInfo", valAddr);
Map<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer " + accessToken);
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getUserInfo返回:{}", resp);
JSONObject entries = new JSONObject(resp);
return entries.getString("userId");
}
private String getAccessToken(String code) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String frUrl = xtlConfig.getFrUrl() + "/url/oauth2/login";
String appid = xtlConfig.getAppid();
String loginClientSecret = xtlConfig.getLoginClientSecret();
String url = String.format("%s/oauth/getAccessToken?redirect_uri=%s&" +
"client_id=%s&" +
"client_secret=%s&code=%s&grant_type=authorization_code", valAddr, frUrl, appid, loginClientSecret, code);
Map<String, String> header = new HashMap<>();
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getAccessToken返回:{}", resp);
JSONObject entries = new JSONObject(resp);
int code1 = entries.getInt("code");
if (code1 == 200) {
return entries.getJSONObject("data").getString("access_token");
}
return "";
}
private String getCode(String token) throws IOException {
XTLConfig xtlConfig = XTLConfig.getInstance();
String valAddr = xtlConfig.getValAddr();
String loginAppid = xtlConfig.getLoginAppid();
String url = String.format("%s/oauth/getCode?joinsysCode=%s", valAddr, loginAppid);
Map<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer " + token);
String resp = HttpKit.get(url, new HashMap<>(), header);
FineLoggerFactory.getLogger().info("访问getCode返回:{}", resp);
JSONObject entries = new JSONObject(resp);
int code = entries.getInt("code");
if (code == 200) {
return entries.getString("msg");
}
return "";
}
private void sendRedirect(HttpServletResponse res, String url) {
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
res.setHeader("Location", url);
}
private boolean login(HttpServletRequest req, HttpServletResponse res, String username) {
try {
String oldToken = TokenResource.COOKIE.getToken(req);
if ((oldToken == null) || (!checkTokenValid(req, oldToken, username))) {
HttpSession session = req.getSession(true);
String token = LoginService.getInstance().login(req, res, username);
session.setAttribute("fine_auth_token", token);
FineLoggerFactory.getLogger().error("fr CookieFilter is over with username is ###" + username);
return true;
} else {
FineLoggerFactory.getLogger().error("no need login: {}", username);
return true;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return false;
}
}
private boolean checkTokenValid(HttpServletRequest req, String token, String currentUserName) {
try {
if (!ComparatorUtils.equals(currentUserName, JwtUtils.parseJWT(token).getSubject())) {
FineLoggerFactory.getLogger().info("username changed:" + currentUserName);
return false;
} else {
Device device = NetworkHelper.getDevice(req);
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
return true;
}
} catch (Exception var5) {
return false;
}
}
}
Loading…
Cancel
Save