Browse Source

open

master
pioneer 2 years ago
commit
81169dd7af
  1. 6
      README.md
  2. BIN
      doc/JSD-9713-需求确认书V1.docx
  3. BIN
      doc/单点使用文档.docx
  4. BIN
      doc/登录验证(外发).docx
  5. BIN
      lib/finekit-10.0-20200828.jar
  6. 22
      plugin.xml
  7. 12
      src/main/java/com/fr/plugin/FunctionRecoder.java
  8. 47
      src/main/java/com/fr/plugin/UASSLOGINConfig.java
  9. 18
      src/main/java/com/fr/plugin/UASSLOGINLifeCycleMonitor.java
  10. 65
      src/main/java/com/fr/plugin/USAAPassport.java
  11. 104
      src/main/java/com/fr/plugin/filter/UASSLOGIN1Filter.java
  12. 53
      src/main/java/com/fr/plugin/tools/EncryptTool.java
  13. 120
      src/main/java/com/fr/plugin/tools/ToolDES.java
  14. BIN
      src/main/java/com/fr/plugin/tools/img.png

6
README.md

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

BIN
doc/JSD-9713-需求确认书V1.docx

Binary file not shown.

BIN
doc/单点使用文档.docx

Binary file not shown.

BIN
doc/登录验证(外发).docx

Binary file not shown.

BIN
lib/finekit-10.0-20200828.jar

Binary file not shown.

22
plugin.xml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.eco.plugin.xxx.uasslogin</id>
<name><![CDATA[登录验证]]></name>
<active>yes</active>
<version>1.0.0</version>
<env-version>10.0</env-version>
<jartime>2021-02-10</jartime>
<vendor>fr.open</vendor>
<main-package>com.fr.plugin</main-package>
<!--用来记录这个任务的创建时间-->
<description><![CDATA[
]]></description>
<!--任务ID: 9713-->
<create-day>2022-4-1 13:17:34</create-day>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.filter.UASSLOGIN1Filter"/>
</extra-decision>
<lifecycle-monitor class="com.fr.plugin.UASSLOGINLifeCycleMonitor"/>
<function-recorder class="com.fr.plugin.FunctionRecoder"/>
</plugin>

12
src/main/java/com/fr/plugin/FunctionRecoder.java

@ -0,0 +1,12 @@
package com.fr.plugin;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.plugin.transform.FunctionRecorder;
@FunctionRecorder
public class FunctionRecoder {
@ExecuteFunctionRecord
public void exe(){
System.out.println("插件功能埋点,虽然不会执行,除非上架应用");
}
}

47
src/main/java/com/fr/plugin/UASSLOGINConfig.java

@ -0,0 +1,47 @@
package com.fr.plugin;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
@Visualization(category = "登录验证配置")
public class UASSLOGINConfig extends DefaultConfiguration {
private static volatile UASSLOGINConfig config = null;
public static UASSLOGINConfig getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(UASSLOGINConfig.class);
}
return config;
}
@Identifier(value = "apiUrl", name = "接口地址前缀", description = "描述", status = Status.SHOW)
private Conf<String> apiUrl = Holders.simple("http://*.*.*.*:88");
@Identifier(value = "secret", name = "认证秘钥", description = "在配置main_config.properties的des3privacykey内容", status = Status.SHOW)
private Conf<String> secret = Holders.simple("");
public String getApiUrl() {
return apiUrl.get();
}
public void setApiUrl( String apiUrl) {
this.apiUrl .set(apiUrl);
}
public String getSecret() {
return secret.get();
}
public void setSecret( String secret) {
this.secret.set(secret);
}
@Override
public Object clone() throws CloneNotSupportedException {
UASSLOGINConfig cloned = (UASSLOGINConfig) super.clone();
cloned.apiUrl = (Conf<String>) this.apiUrl.clone();
cloned.secret = (Conf<String>) this.secret.clone();
return cloned;
}
}

18
src/main/java/com/fr/plugin/UASSLOGINLifeCycleMonitor.java

@ -0,0 +1,18 @@
package com.fr.plugin;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
import com.fr.stable.fun.Authorize;
@Authorize
public class UASSLOGINLifeCycleMonitor extends AbstractPluginLifecycleMonitor {
@Override
public void afterRun(PluginContext pluginContext) {
UASSLOGINConfig.getInstance();
}
@Override
public void beforeStop(PluginContext pluginContext) {
}
}

65
src/main/java/com/fr/plugin/USAAPassport.java

@ -0,0 +1,65 @@
package com.fr.plugin;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.net.http.HttpKit;
import com.fr.decision.authorize.impl.AbstractPassport;
import com.fr.json.JSONObject;
import com.fr.plugin.tools.ToolDES;
import com.fr.stable.StringUtils;
import java.io.IOException;
public class USAAPassport extends AbstractPassport {
@Override
public boolean checkTicket(String username, String inputPassword, String savedPassword, String hashPassword) {
boolean checkTicket = false;
String st = null;
try {
st = getSt(username, inputPassword);
if (StringUtils.isBlank(st)) {
return false;
}
String un = getUserInfo(st);
if (StringUtils.equals(un,username)) {
return true;
}
} catch (IOException e) {
LogKit.error("认证失败:",e);
return false;
}
return checkTicket;
}
@Override
public String markType() {
return "USAA";
}
private String getSt(String name, String pwd) throws IOException {
String encrypt = ToolDES.encrypt(pwd);
UASSLOGINConfig uassloginConfig = UASSLOGINConfig.getInstance();
String url = String.format("%s/ssouas/ssologincheck?loginname=%s&password=%s", uassloginConfig.getApiUrl(), name, encrypt);
String resp = HttpKit.get(url);
LogKit.info("访问:{} 获取st 响应:{}", url, resp);
JSONObject entries = new JSONObject(resp);
String err = entries.getString("err");
if (StringUtils.equals(err, "1")) {
String st = entries.getString("st");
return st;
}
return resp;
}
private String getUserInfo(String st) throws IOException {
UASSLOGINConfig uassloginConfig = UASSLOGINConfig.getInstance();
String userInfoUrl = String.format("%s/ssouas/loginuass?st=%s", uassloginConfig.getApiUrl(), st);
String resp = HttpKit.get(userInfoUrl);
LogKit.info("访问:{} 获取userInfo 响应:{}", userInfoUrl, resp);
JSONObject entries = new JSONObject(resp);
String err = entries.getString("err");
if (StringUtils.equals(err, "1")) {
String userName = entries.getString("userName");
return userName;
}
return "";
}
}

104
src/main/java/com/fr/plugin/filter/UASSLOGIN1Filter.java

@ -0,0 +1,104 @@
package com.fr.plugin.filter;
import com.fr.base.ServerConfig;
import com.fr.data.NetworkHelper;
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
import com.fr.decision.authority.base.constant.type.operation.SyncOperationType;
import com.fr.decision.config.FSConfig;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
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.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.USAAPassport;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Device;
import com.fr.web.utils.WebUtils;
import com.fr.plugin.context.PluginContexts;
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;
public class UASSLOGIN1Filter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "UASSLOGIN1Filter";
}
@Override
public String[] urlPatterns() {
return new String[]{
"/decision/login",
};
}
@Override
public void init(FilterConfig filterConfig) {
super.init(filterConfig);
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
try {
if (PluginContexts.currentContext().isAvailable()) {
doLoginCheck(req, res, filterChain);
} else {
WebUtils.printAsString(res, "插件名:《xxxxx》插件id:com.eco.plugin.xxx.uasslogin 插件授权过期 请联系销售");
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
public void doLoginCheck(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
if (StringUtils.equals("POST", req.getMethod())) {
USAAPassport usaaPassport = new USAAPassport();
FSConfig.getInstance().setPassport(ManualOperationType.KEY, usaaPassport);
usaaPassport = new USAAPassport();
FSConfig.getInstance().setPassport(SyncOperationType.KEY, usaaPassport);
filterChain.doFilter(req, res);
} else {
filterChain.doFilter(req, res);
}
}
private void login(HttpServletRequest req, HttpServletResponse res, String username) {
String token = null;
try {
token = LoginService.getInstance().login(req, res, username);
req.setAttribute("fine_auth_token", token);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineLoggerFactory.getLogger().error("login failed");
}
FineLoggerFactory.getLogger().error("login success");
}
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;
}
private static void setCookie(HttpServletResponse response, String name, String value) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
response.addCookie(cookie);
}
}

53
src/main/java/com/fr/plugin/tools/EncryptTool.java

@ -0,0 +1,53 @@
package com.fr.plugin.tools;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Encoder;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
public class EncryptTool
{
private byte[] encryptString(byte[] data, byte[] rawKeyData)
throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, IllegalStateException
{
SecureRandom sr = new SecureRandom();
DESKeySpec dks = new DESKeySpec(rawKeyData);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(1, key, sr);
byte[] encryptedData = cipher.doFinal(data);
return encryptedData;
}
public String encryptString(String rawStr, String rawKey)
throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, IllegalStateException, IOException
{
byte[] rawStrData = rawStr.getBytes();
byte[] rawKeyData = rawKey.getBytes();
byte[] encryptData = encryptString(rawStrData, rawKeyData);
String encryptStr = new BASE64Encoder().encode(encryptData);
byte[] c = encryptStr.getBytes();
StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < c.length; ++i)
{
int t = c[i];
String str = Integer.toHexString(t);
if (str.length() == 1)
strBuf.append(0);
strBuf.append(Integer.toHexString(t));
}
return strBuf.toString();
}
}

120
src/main/java/com/fr/plugin/tools/ToolDES.java

@ -0,0 +1,120 @@
package com.fr.plugin.tools;
import com.fanruan.api.log.LogKit;
import com.fr.plugin.UASSLOGINConfig;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
*
*/
public class ToolDES {
//public final static String PRIVACY_KEY = WebContant.DES_PRIVACYKEY;
public final static String PRIVACY_KEY;
private static final String Algorithm = "DESede"; // 定义
private static final String encoding = "UTF8";
// 密钥
private static byte[] keyBytes = null;
static {
// String temp = "chinamobileimpgwandother" ;
PRIVACY_KEY = UASSLOGINConfig.getInstance().getSecret();
keyBytes = UASSLOGINConfig.getInstance().getSecret().getBytes(StandardCharsets.UTF_8);
}
// keybyte为加密密钥,长度为24字节
// src为被加密的数据缓冲区(源)
public static byte[] encryptMode(byte[] keybyte, byte[] src) {
try {
// 生成密钥
SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
// 加密
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE, deskey);
return c1.doFinal(src);
} catch (java.lang.Exception e) {
LogKit.error("", e);
}
return null;
}
// keybyte为加密密钥,长度为24字节
// src为加密后的缓冲区
public static byte[] decryptMode(byte[] keybyte, byte[] src) throws Exception {
// 生成密钥
SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
// 解密
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE, deskey);
return c1.doFinal(src);
}
// 转换成十六进制字符串
private static String byte2hexString(byte[] bytes) {
StringBuffer buf = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
if (((int) bytes[i] & 0xff) < 0x10) {
buf.append("0");
}
buf.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buf.toString();
}
// 将十六进制字符串byte数组
private static byte[] hexString2byte(String hexString) {
if (hexString == null || hexString.length() % 2 != 0) {
return null;
}
byte[] hanzi = new byte[hexString.length() / 2];
for (int i = 0; i < hexString.length(); i += 2) {
hanzi[i / 2] = (byte) (Integer.parseInt(hexString.substring(i, i + 2), 16) & 0xff);
}
return hanzi;
}
/**
* 加密字符串
*
* @param src 源字符串
* @return 加密后的字符串
*/
public static String encrypt(String src) {
String key = PRIVACY_KEY;
String result = null;
if (src == null) {
return result;
}
try {
EncryptTool ent = new EncryptTool();
// 加密字符串
LogKit.debug("加密字符串:" + ent);
result = ent.encryptString(src, key);
} catch (Exception e) {
LogKit.error("Exception occurred while encrypting [ " + src + " ] ,key[" + key + "],", e);
return null;
}
return result;
}
public static byte[] getKeyBytes(String key) {
if (key != null && "".equals(key)) {
key = PRIVACY_KEY;
}
if (key != null) {
keyBytes = key.getBytes();
}
return keyBytes;
}
}

BIN
src/main/java/com/fr/plugin/tools/img.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Loading…
Cancel
Save