泛微二开系列(六)OA单点登录到异构系统

泛微OA开发例子:

https://segmentfault.com/a/1190000040429226

一、依赖集成登录模块的Entrance.jsp

以帆软BI为例子,基于/interface/Entrance.jsp。通过判断来实现

1.1 集成登录处新增单点登录

下面的加密算法不用选

基础技术、泛微二开泛微二开系列(六)OA单点登录到异构系统插图

切记这里的标识是“BI”在jsp文件中使用到

1.2 在Entrance.jsp追加标识判断

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="weaver.general.Util" %>
<%@ page import="weaver.integration.entrance.bean.OutterLoginBean" %>
<%@ page import="weaver.integration.entrance.service.EntranceService" %>
<%@ page import="weaver.integration.entrance.service.IOutterSysServer" %>
<%@ page import="weaver.integration.entrance.service.OutterSysServer" %>
<%@ page import="weaver.integration.entrance.service.permission.IPermissionService" %>
<%@ page import="weaver.integration.entrance.service.permission.PermissionService" %>
<%@ page import="weaver.integration.entrance.utils.StringUtils" %>
<%@ page import="weaver.integration.entrance.exceptions.OtherParamsEncryptException" %>
<%@ page import="weaver.integration.entrance.exceptions.AccountOrPasswordEncryptException" %>
<%@ page import="weaver.integration.logging.LoggerFactory" %>
<%@ page import="weaver.integration.logging.Logger" %>
<%@ page import="com.alibaba.fastjson.JSONObject" %>

<%@ page import="weaver.hrm.User" %>
<%@ page import="weaver.hrm.HrmUserVarify" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="weaver.systeminfo.SystemEnv" %>
<%@ page import="java.util.Objects" %>
  <%@ page import="com.sso.finereport" %>

  <%--<script type="text/javascript" src="/js/jquery/jquery_wev8.js"></script>--%>
<%--<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>--%>
<%--<%@ include file="/systeminfo/init_wev8.jsp" %>--%>


<script language=javascript src="<%=weaver.general.GCONST.getContextPath()%>/wui/theme/ecology8/jquery/js/zDialog_wev8.js"></script>

<jsp:useBean id="rs" class="weaver.conn.RecordSet" scope="page"/>
<jsp:useBean id="RecordSet" class="weaver.conn.RecordSet" scope="page"/>
<jsp:useBean id="RecordSet1" class="weaver.conn.RecordSet" scope="page"/>

<%

    Logger integration_logger = LoggerFactory.getLogger();


    User this_user = HrmUserVarify.getUser(request,response);

    //企业微信集成时,构造的用户session会缺少loginid,导致在企业微信中引用集成登录时,因获取不到用户名导致无法单点登录。
    if(Util.null2String(this_user.getLoginid()).equals("")){
        //查询loginid
        RecordSet.executeSql("select loginid from HrmResource where id="+this_user.getUID());
        if(RecordSet.next()){
            this_user.setLoginid(Util.null2String(RecordSet.getString("loginid")));
        }
        //重新设置用户session
        request.getSession(true).setAttribute("weaver_user@bean", this_user);
    }

    IPermissionService permissionService=new PermissionService();
    String operationType = permissionService.getOperationType(request);

    String sysid = Util.null2String(request.getParameter("id"));// 系统标识

    integration_logger.info("sysid=========================" + sysid);
    integration_logger.info("operationType=========================" + operationType);

    if(sysid=="BI"){
        finereport finereportClass = new finereport();
        String BIUrl = finereportClass.FineAccessUrl(this_user.getLoginid());
        response.sendRedirect(BIUrl);
        return;
    }


    if ("".equals(operationType)) {
        // 权限判断
        // 得到有权限查看的集成登录
        String access = permissionService.isAccess(sysid, request, response);

        if (!StringUtils.isBlank(access)){


            if(access.startsWith("/")&&!access.startsWith(weaver.general.GCONST.getContextPath())){
                access = weaver.general.GCONST.getContextPath()+access;
            }
            response.sendRedirect(access);
            return;
        }
    }

    EntranceService entranceService = new EntranceService();
    IOutterSysServer   outterSysServer = new OutterSysServer();
    OutterLoginBean loginBean = null;
    Map<String, Object> map = new HashMap<String, Object>();
    try {
        loginBean = entranceService.getLoginBean(outterSysServer, sysid, operationType, request, response);
        map = entranceService.getUrl(outterSysServer, loginBean, operationType, request, response);
        integration_logger.info("map=========================" + JSONObject.toJSONString(map));


    } catch (ClassNotFoundException e) {
%>
<script language=javascript>
    top.Dialog.alert("<%= SystemEnv.getHtmlLabelNames("508601",this_user.getLanguage()) %>", function () {
        window.close();
    }, 420, 130);
</script>
<%
}catch (NoSuchMethodException e){
    e.printStackTrace();
%>
<script language=javascript>
    top.Dialog.alert("<%= SystemEnv.getHtmlLabelNames("508602",this_user.getLanguage()) %>", function () {
        window.close();
    }, 420, 130);
</script>
<%
}catch (IllegalAccessException e){
%>
<script language=javascript>
    top.Dialog.alert("<%=SystemEnv.getHtmlLabelNames("508603",this_user.getLanguage()) %>", function () {
        window.close();
    }, 420, 130);
</script>
<%
}catch (InstantiationException e){
%>
<script language=javascript>
    top.Dialog.alert("<%= SystemEnv.getHtmlLabelNames("508604",this_user.getLanguage())%>", function () {
        window.close();
    }, 420, 130);
</script>
<%
}catch (NoClassDefFoundError e){
%>
<script language=javascript>
    top.Dialog.alert("<%= SystemEnv.getHtmlLabelNames("508605",this_user.getLanguage())%>", function () {
        window.close();
    }, 420, 130);
</script>
<%
}catch (OtherParamsEncryptException e) {
%>
<script language=javascript>
    top.Dialog.alert("<%= SystemEnv.getHtmlLabelNames("508614",this_user.getLanguage())%>", function () {
        window.close();
    }, 420, 130);
</script>
<%

} catch (AccountOrPasswordEncryptException e) {
%>
<script language=javascript>
    top.Dialog.alert("<%= SystemEnv.getHtmlLabelNames("508615",this_user.getLanguage())%>", function () {
        window.close();
    }, 420, 130);
</script>
<%
}catch (Exception e){
%>
<script language=javascript>
    top.Dialog.alert("系统异常,请联系管理员", function () {
        window.close();
    }, 420, 130);
</script>
<%
    }

    if (Objects.nonNull(map)){
        if (map.get("isError")!= null&&"true".equals(map.get("isError"))){
%>
<script language=javascript>
    top.Dialog.alert("<%= map.get("errorMsg") %>", function () {
        window.close();
    }, 420, 130);
</script>
<%
            return;
        }
        if (map.get("isRedirect")!=null && "true".equals(map.get("isRedirect"))){
            response.sendRedirect(map.get("redirectUrl").toString());
            return;
        }
        if (map.get("isRedirect")!=null && "false".equals(map.get("isRedirect"))){
            out.println(map.get("redirectUrl").toString());
            return;
        }
    }else {
        integration_logger.error("map is null ====================================================");
    }

%>
基础技术、泛微二开泛微二开系列(六)OA单点登录到异构系统插图1

1.3 定义一个“finereport”的java类

package com.sso;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.annotation.Nullable;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;

public class finereport {
    private static final int FRAGMENT_LENGTH = 245;

    public finereport() {
    }

    public String FineAccessUrl(String username) {
        String accessUrl = "";
        //填入公钥
        String publicKey = "*****************";
        String encrypt = encrypt(username, publicKey);
        System.out.println("encrypted username: " + encrypt);
        String encode = null;

        try {
            encode = URLEncoder.encode(encrypt, "UTF-8");
        } catch (UnsupportedEncodingException var7) {
            var7.printStackTrace();
        }

        System.out.println("ssoToken: " + encode);
        //修改地址
        accessUrl = "http://*************/decision?ssoToken=" + encode;
        return accessUrl;
    }

    public static String encrypt(String plainText, String customPublicKey) {
        return encrypt((String)plainText, (Key)string2PublicKey(customPublicKey));
    }

    public static byte[] encrypt(byte[] plainTextData, Key publicKey) {
        if (plainTextData.length == 0) {
            return plainTextData;
        } else {
            try {
                Cipher c1 = Cipher.getInstance("RSA");
                c1.init(1, publicKey);
                return dealEncryptFragment(plainTextData, c1);
            } catch (Exception var3) {
                var3.printStackTrace();
                return null;
            }
        }
    }

    public static String encrypt(String plainText, Key publicKey) {
        if (plainText != null && !"".equals(plainText)) {
            byte[] publicEncrypt = encrypt(plainText.getBytes(StandardCharsets.UTF_8), publicKey);
            return Base64.getEncoder().encodeToString(publicEncrypt);
        } else {
            return plainText;
        }
    }

    public static PublicKey string2PublicKey(String pubStr) {
        try {
            byte[] keyBytes = base642Byte(pubStr);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePublic(keySpec);
        } catch (Exception var4) {
            var4.printStackTrace();
            return null;
        }
    }

    public static byte[] base642Byte(String base64Key) throws Exception {
        finereport.BASE64Decoder decoder = new finereport.BASE64Decoder();
        return decoder.decodeBuffer(base64Key);
    }

    private static byte[] dealEncryptFragment(byte[] data, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException {
        byte[] result = new byte[0];

        for(int i = 0; i < data.length; i += 245) {
            byte[] fragment = subarray(data, i, i + 245);
            byte[] update = cipher.doFinal(fragment);
            result = addAll(result, update);
        }

        return result;
    }

    public static byte[] subarray(@Nullable byte[] array, int startIndexInclusive, int endIndexExclusive) {
        if (array == null) {
            return null;
        } else {
            if (startIndexInclusive < 0) {
                startIndexInclusive = 0;
            }

            if (endIndexExclusive > array.length) {
                endIndexExclusive = array.length;
            }

            int newSize = endIndexExclusive - startIndexInclusive;
            if (newSize <= 0) {
                return new byte[0];
            } else {
                byte[] subarray = new byte[newSize];
                System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
                return subarray;
            }
        }
    }

    public static byte[] addAll(@Nullable byte[] array1, @Nullable byte... array2) {
        if (array1 == null) {
            return clone(array2);
        } else if (array2 == null) {
            return clone(array1);
        } else {
            byte[] joinedArray = new byte[array1.length + array2.length];
            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
            return joinedArray;
        }
    }

    public static byte[] clone(@Nullable byte[] array) {
        return array == null ? null : (byte[])((byte[])array.clone());
    }

    static class BASE64Decoder extends finereport.CharacterDecoder {
        private static final char[] pem_array = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
        private static final byte[] pem_convert_array = new byte[256];
        byte[] decode_buffer = new byte[4];

        public BASE64Decoder() {
        }

        protected int bytesPerAtom() {
            return 4;
        }

        protected int bytesPerLine() {
            return 72;
        }

        protected void decodeAtom(PushbackInputStream var1, OutputStream var2, int var3) throws Exception {
            byte var5 = -1;
            byte var6 = -1;
            byte var7 = -1;
            byte var8 = -1;
            if (var3 < 2) {
                throw new Exception("BASE64Decoder: Not enough bytes for an atom.");
            } else {
                int var4;
                do {
                    var4 = var1.read();
                    if (var4 == -1) {
                        throw new Exception();
                    }
                } while(var4 == 10 || var4 == 13);

                this.decode_buffer[0] = (byte)var4;
                var4 = this.readFully(var1, this.decode_buffer, 1, var3 - 1);
                if (var4 == -1) {
                    throw new Exception();
                } else {
                    if (var3 > 3 && this.decode_buffer[3] == 61) {
                        var3 = 3;
                    }

                    if (var3 > 2 && this.decode_buffer[2] == 61) {
                        var3 = 2;
                    }

                    switch(var3) {
                    case 4:
                        var8 = pem_convert_array[this.decode_buffer[3] & 255];
                    case 3:
                        var7 = pem_convert_array[this.decode_buffer[2] & 255];
                    case 2:
                        var6 = pem_convert_array[this.decode_buffer[1] & 255];
                        var5 = pem_convert_array[this.decode_buffer[0] & 255];
                    default:
                        switch(var3) {
                        case 2:
                            var2.write((byte)(var5 << 2 & 252 | var6 >>> 4 & 3));
                            break;
                        case 3:
                            var2.write((byte)(var5 << 2 & 252 | var6 >>> 4 & 3));
                            var2.write((byte)(var6 << 4 & 240 | var7 >>> 2 & 15));
                            break;
                        case 4:
                            var2.write((byte)(var5 << 2 & 252 | var6 >>> 4 & 3));
                            var2.write((byte)(var6 << 4 & 240 | var7 >>> 2 & 15));
                            var2.write((byte)(var7 << 6 & 192 | var8 & 63));
                        }

                    }
                }
            }
        }

        static {
            int var0;
            for(var0 = 0; var0 < 255; ++var0) {
                pem_convert_array[var0] = -1;
            }

            for(var0 = 0; var0 < pem_array.length; ++var0) {
                pem_convert_array[pem_array[var0]] = (byte)var0;
            }

        }
    }

    abstract static class CharacterDecoder {
        public CharacterDecoder() {
        }

        protected abstract int bytesPerAtom();

        protected abstract int bytesPerLine();

        protected void decodeBufferPrefix(PushbackInputStream var1, OutputStream var2) throws Exception {
        }

        protected void decodeBufferSuffix(PushbackInputStream var1, OutputStream var2) throws Exception {
        }

        protected int decodeLinePrefix(PushbackInputStream var1, OutputStream var2) throws Exception {
            return this.bytesPerLine();
        }

        protected void decodeLineSuffix(PushbackInputStream var1, OutputStream var2) throws Exception {
        }

        protected void decodeAtom(PushbackInputStream var1, OutputStream var2, int var3) throws Exception {
            throw new Exception();
        }

        protected int readFully(InputStream var1, byte[] var2, int var3, int var4) throws Exception {
            for(int var5 = 0; var5 < var4; ++var5) {
                int var6 = var1.read();
                if (var6 == -1) {
                    return var5 == 0 ? -1 : var5;
                }

                var2[var5 + var3] = (byte)var6;
            }

            return var4;
        }

        public void decodeBuffer(InputStream var1, OutputStream var2) throws Exception {
            int var4 = 0;
            PushbackInputStream var5 = new PushbackInputStream(var1);
            this.decodeBufferPrefix(var5, var2);

            while(true) {
                try {
                    int var6 = this.decodeLinePrefix(var5, var2);

                    int var3;
                    for(var3 = 0; var3 + this.bytesPerAtom() < var6; var3 += this.bytesPerAtom()) {
                        this.decodeAtom(var5, var2, this.bytesPerAtom());
                        var4 += this.bytesPerAtom();
                    }

                    if (var3 + this.bytesPerAtom() == var6) {
                        this.decodeAtom(var5, var2, this.bytesPerAtom());
                        var4 += this.bytesPerAtom();
                    } else {
                        this.decodeAtom(var5, var2, var6 - var3);
                        var4 += var6 - var3;
                    }

                    this.decodeLineSuffix(var5, var2);
                } catch (Exception var7) {
                    this.decodeBufferSuffix(var5, var2);
                    return;
                }
            }
        }

        public byte[] decodeBuffer(String var1) throws Exception {
            byte[] var2 = new byte[var1.length()];
            var1.getBytes(0, var1.length(), var2, 0);
            ByteArrayInputStream var3 = new ByteArrayInputStream(var2);
            ByteArrayOutputStream var4 = new ByteArrayOutputStream();
            this.decodeBuffer(var3, var4);
            return var4.toByteArray();
        }

        public byte[] decodeBuffer(InputStream var1) throws Exception {
            ByteArrayOutputStream var2 = new ByteArrayOutputStream();
            this.decodeBuffer(var1, var2);
            return var2.toByteArray();
        }

        public ByteBuffer decodeBufferToByteBuffer(String var1) throws Exception {
            return ByteBuffer.wrap(this.decodeBuffer(var1));
        }

        public ByteBuffer decodeBufferToByteBuffer(InputStream var1) throws Exception {
            return ByteBuffer.wrap(this.decodeBuffer(var1));
        }
    }
}

二、依赖集成登录模块的自定义加密方式

2.1、创建BI的加密算法

基础技术、泛微二开泛微二开系列(六)OA单点登录到异构系统插图2
基础技术、泛微二开泛微二开系列(六)OA单点登录到异构系统插图3

2.2、创建一个java类并命名为“finereport_RSA”

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.gani.sso.finereport.finereport_RSA;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import weaver.interfaces.encode.IEncode;

public class finereport_RSA implements IEncode {
  private String pwd = null;
  
  public finereport_RSA() {}
  
  public finereport_RSA(String var1) {
    this.pwd = var1;
  }
  
  public String encode(String var1) {
    if (this.pwd == null)
      //公钥
      this.pwd = ""; 
    RSA pubRsa = new RSA(null, this.pwd);
    String encodeStr = pubRsa.encryptBase64(var1, KeyType.PublicKey);
    String encode = null;
    try {
      encode = URLEncoder.encode(encodeStr, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } 
    return encode;
  }
  
  public String decode(String var1) {
    String decodeStr = null;
    try {
      decodeStr = URLDecoder.decode(var1, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } 
    if (this.pwd == null)
      //公钥
      this.pwd = ""; 
    RSA priRsa = new RSA(this.pwd, null);
    String decode = priRsa.decryptStr(decodeStr, KeyType.PrivateKey);
    return decode;
  }
  
  public boolean setPwd(String var1) {
    this.pwd = var1;
    return true;
  }
  
  public boolean setIv(String var1) {
    return true;
  }
}

2.3 配置集成登录界面

基础技术、泛微二开泛微二开系列(六)OA单点登录到异构系统插图4

三、无依赖集成登录自定义JSP方式

3.1 创建一个jsp用于访问使用

<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@page import="weaver.conn.RecordSet"%>
<%@ page import="java.util.*" %>
<%@ page import="weaver.general.*" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="selfdev.util.log.LogTool" %>
<%@ page import="com.util.ssoUtil" %>
<%@ page import="com.alibaba.fastjson.JSONObject" %>
<%@ page import="java.util.Base64" %>
<%@ include file="/systeminfo/init_wev8.jsp" %>
<%
  
  LogTool mylog = new LogTool("/log/selfdev/EntranceSso/login/", false);
  String userId = user.getUID()+"";
  String loginid = user.getLoginid();//获取当前用户登录名
  ssoUtil ssoUtil = new ssoUtil();
  mylog.writeLog("当前用户loginid------>"+loginid);



  String username = request.getParameter("account");
  byte[] passwordStr = Base64.getDecoder().decode(request.getParameter("password"));
  String password = new String(passwordStr);
  String clientid = "client_id";    //client_id
  String clientsecret = "client_secret";//client_secret
  mylog.writeLog("username="+username+"----password="+password);
  //用户是否有权限登录JD
  //userId="60";
//  JSONObject checkUserObject = JSONObject.parseObject(ssoUtil.checkUser(userId));
//  if (checkUserObject.getString("status").equals("E")){
//    out.print(checkUserObject.get("msg"));
//    return;
//  }
//  if("1".equals(userId)) {//系统管理员
//    out.print("当前用户无权限登录商城系统,请联系系统管理员开通权限~");
//    return;
//  }

  //String clientid = JSONObject.parseObject(checkUserObject.getString("data")).getString("clientid");
  //String clientsecret = JSONObject.parseObject(checkUserObject.getString("data")).getString("clientsecret");
  //String username = JSONObject.parseObject(checkUserObject.getString("data")).getString("username");
  //String password = JSONObject.parseObject(checkUserObject.getString("data")).getString("password");


  //mylog.writeLog("读取配置表=userName="+username+"--passWord="+password+"--clientid="+clientid+"--client_secret="+clientsecret);


  /*
  * 1.判断用户身份
  * 2.请求获取TOKEN
  * 3.SSO登录
  * */

  if(loginid!=null&&!"".equals(loginid)){  //先判断用户ID是否存在,不存在提示异常信息
    String token = ssoUtil.getAccessToken(username, password,clientid,clientsecret);
    mylog.writeLog("获取token="+token);
    if (token.equals("")){
      out.print("获取TOEKN失败,请联系系统管理员~");
      return;
    }
    //String token = SM4Util.getFileSysToken("http://10.8.31.169:8080/genericSSO/brunpToken.do");
    String code = ssoUtil.getstrustNo(username, password,token,clientid,clientsecret);
    mylog.writeLog("获取code="+code);
    if (code.equals("")){
      out.print("获取登录标识code失败,请联系系统管理员~");
      return;
    }
    try {
      String url = ssoUtil.getloginUrl(username,code);
      if (!url.equals("")){
        response.sendRedirect(url);
      }
    }catch (Exception e){
      mylog.writeLog(e.toString());
      out.print("程序执行异常,请联系管理员进行维护");
      return;
    }
  }else{
      mylog.writeLog("您的登录名不存在,请联系管理员进行维护。");
      out.print("您的登录名不存在,请联系管理员进行维护。");
      return;
  }
%>

3.2 创建一个ssoUtil的java类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.huawei.shade.org.apache.http.NameValuePair;
import com.huawei.shade.org.apache.http.client.entity.UrlEncodedFormEntity;
import com.util.ssoUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import selfdev.util.base.TimeCommonUtil;
import selfdev.util.log.LogTool;
import weaver.conn.RecordSet;

public class ssoUtil {
  private static LogTool log = new LogTool("/log/selfdev/EntranceSso/login/", false);
  
  private static String accessTokenUrl = "https://bizapi.jd.com/oauth2/accessToken";
  
  private static String grant_type = "access_token";
  
  private static String trustedLoginUrl = "https://bizapi.jd.com/api/trustedLogin";
  
  private static String LoginUrl = "https://vsp.jd.com/strust/login";
  
  public static void main(String[] args) {}
  
  public String checkUser(String userId) {
    HashMap<String, Object> res = new HashMap<>();
    HashMap<String, String> data = new HashMap<>();
    RecordSet rs = new RecordSet();
    String sql = "select * from uf_SsoConfig where oaId=" + userId;
    if (rs.execute(sql)) {
      while (rs.next()) {
        data.put("clientid", rs.getString("clientid"));
        data.put("clientsecret", rs.getString("clientsecret"));
        data.put("username", rs.getString("username"));
        data.put("password", rs.getString("password"));
        res.put("status", "S");
        res.put("data", data);
        res.put("msg", ");
      } 
    } else {
      res.put("status", "E");
      res.put("msg", ");
    } 
    log.writeLog(getCurentDate() + " + userId + "+ res.toString());
    return JSON.toJSONString(res, new SerializerFeature[] { SerializerFeature.DisableCircularReferenceDetect });
  }
  
  public HashMap<String, String> getAccessToken(String userName, String passWord, String clientid, String client_secret) {
    log.writeLog("userName=" + userName + "--passWord=" + passWord + "--clientid=" + clientid + "--client_secret=" + client_secret);
    String access_token = "";
    HashMap<String, String> rs = new HashMap<>();
    try {
      String timeStamp = getCurentDate();
      String signContent = client_secret + timeStamp + clientid + userName + DigestUtils.md5Hex(passWord).toLowerCase() + grant_type + client_secret;
      String sign = DigestUtils.md5Hex(signContent).toUpperCase();
      Map<String, String> request = new HashMap<>();
      request.put("grant_type", grant_type);
      request.put("client_id", clientid);
      request.put("timestamp", timeStamp);
      request.put("username", userName);
      request.put("password", DigestUtils.md5Hex(passWord).toLowerCase());
      request.put("sign", sign);
      JSONObject resultObj = JSONObject.parseObject(post(request, accessTokenUrl, new HashMap<>(), "application/x-www-form-urlencoded"));
      log.writeLog("+ resultObj.toString());
      if (((Boolean)resultObj.get("success")).booleanValue()) {
        access_token = JSONObject.parseObject(resultObj.getString("result")).getString("access_token");
        rs.put("status", resultObj.get("success").toString());
        rs.put("access_token", access_token);
        rs.put("resultMessage", resultObj.getString("resultMessage"));
      } else {
        rs.put("status", resultObj.get("success").toString());
        rs.put("access_token", "");
        rs.put("resultMessage", resultObj.getString("resultMessage"));
      } 
    } catch (Exception e) {
      log.writeLog(accessTokenUrl + "+ e.toString());
    } 
    return rs;
  }
  
  public String getstrustNo(String userName, String passWord, String token, String clientid, String client_secret) {
    log.writeLog("userName=" + userName + "--passWord=" + passWord + "--clientid=" + clientid + "--client_secret=" + client_secret + "--token=" + token);
    String code = "";
    try {
      String time = String.valueOf((new Date()).getTime());
      String signContent = userName + userName + time;
      String sign = DigestUtils.md5Hex(signContent).toLowerCase();
      log.writeLog("+ signContent + "----+ sign);
      Map<String, String> request = new HashMap<>();
      request.put("token", token);
      request.put("Pin", userName);
      request.put("time", time);
      request.put("uniqueNo", userName);
      request.put("sign", sign);
      JSONObject resultObj = JSONObject.parseObject(post(request, trustedLoginUrl, new HashMap<>(), "application/x-www-form-urlencoded"));
      if (((Boolean)resultObj.get("success")).booleanValue())
        code = resultObj.getString("result"); 
    } catch (Exception e) {
      log.writeLog(trustedLoginUrl + "+ e.toString());
    } 
    return code;
  }
  
  public String getloginUrl(String userName, String code, String redirectUrl) {
    log.writeLog("userName=" + userName + "--code=" + code);
    String loginUrl = "";
    try {
      String signContent = userName + userName + code + "VSP";
      String sign = DigestUtils.md5Hex(signContent).toLowerCase();
      log.writeLog("+ signContent + "----+ sign);
      if (!redirectUrl.equals("")) {
        loginUrl = redirectUrl + "?pin=" + userName + "&strustNo=" + code + "&appId=VSP&uniqueNo=" + userName + "&sign=" + sign;
      } else {
        loginUrl = LoginUrl + "?pin=" + userName + "&strustNo=" + code + "&appId=VSP&uniqueNo=" + userName + "&sign=" + sign;
      } 
    } catch (Exception e) {
      log.writeLog(loginUrl + "+ e.toString());
    } 
    log.writeLog("+ loginUrl);
    return loginUrl;
  }
  
  public static String postWithParamsForString(String url, List<NameValuePair> params) {
    log.writeLog("+ url + "----params=" + params);
    CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);
    String s = "";
    try {
      httpPost.setEntity((HttpEntity)new UrlEncodedFormEntity(params, "UTF-8"));
      httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
      HttpResponse response = closeableHttpClient.execute((HttpUriRequest)httpPost);
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) {
        HttpEntity entity = response.getEntity();
        s = EntityUtils.toString(entity);
      } 
    } catch (IOException e) {
      e.printStackTrace();
    } 
    log.writeLog("+ s.toString());
    return s;
  }
  
  private String getCurentDate() {
    String currDate = TimeCommonUtil.getCurrentDate();
    String currTime = TimeCommonUtil.getCurrentTime();
    return currDate + " " + currTime;
  }
  
  public static String post(Map<String, String> map, String url, Map<String, String> headerMap, String contentType) throws Exception {
    CloseableHttpClient httpclient = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost(url);
    CloseableHttpResponse response = null;
    InputStream in = null;
    BufferedReader br = null;
    String result = "";
    log.writeLog("map=" + map + "--url=" + url + "--headerMap=" + headerMap + "--contentType=" + contentType);
    try {
      List<NameValuePair> nameValuePairs = getNameValuePairList(map);
      UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
      urlEncodedFormEntity.setContentType(contentType);
      post.setEntity((HttpEntity)urlEncodedFormEntity);
      post.setHeader("Content-Type", contentType);
      Set<Map.Entry<String, String>> headerEntries = headerMap.entrySet();
      for (Map.Entry<String, String> headerEntry : headerEntries)
        post.setHeader(headerEntry.getKey(), headerEntry.getValue()); 
      response = httpclient.execute((HttpUriRequest)post);
      in = response.getEntity().getContent();
      br = new BufferedReader(new InputStreamReader(in, "utf-8"));
      StringBuilder strber = new StringBuilder();
      String line = null;
      while ((line = br.readLine()) != null)
        strber.append(line + '\n'); 
      result = strber.toString();
      if (response.getStatusLine().getStatusCode() != 200) {
        log.writeLog(");
        result = ";
        throw new Exception(result);
      } 
    } catch (Exception e) {
      log.writeLog("+ e.getMessage());
      throw new Exception(e.getMessage());
    } finally {
      br.close();
      in.close();
      response.close();
      httpclient.close();
    } 
    return result;
  }
  
  private static List<NameValuePair> getNameValuePairList(Map<String, String> map) {
    List<NameValuePair> list = new ArrayList<>();
    for (String key : map.keySet())
      list.add(new BasicNameValuePair(key, map.get(key))); 
    return list;
  }
}