云简标准SSO

文档说明

本文旨在提供标准的云简系统的单点登录方式,由云简提供认证服务。

术语

  • 加密模式。云简标准SSO支持AES/ECB/PKCS5Padding和AES/CBC/PKCS5Padding两种加密模式,默认AES/ECB/PKCS5Padding。用于加密用户信息。
  • 公司编码和密钥。客户在云简系统拥有唯一编码和密钥,用于获取用户标识加密code。
  • 用户标识。云简和客户双方需要约定用户的唯一标识(员工号/用户名/邮箱等),默认员工号。

步骤

  1. 选择加密方式和用户标识。
  2. 根据云简提供的公司编码(company_code)和密钥(company_key),获取/生成用户标识加密code。
  3. 拼接SSO跳转链接。

要点

  1. SSO链接有效期默认十分钟,可配置,需在选用加密模式和用户标识阶段确定。
  2. 获取用户信息的加密code分两种方式:接口调用/代码实现,详见附录1。
  3. 拼接SSO跳转链接详见附录2,生产环境与测试环境的链接不同。

附录1

接口调用

  • 接口说明:获取用户信息的加密code

  • 接口地址:common/oauth2/unAuth/authorize

  • Method:POST

  • 请求参数:

字段 类型 说明 必须
bizId String 业务唯一识别码
timestamp long 时间戳
data.user_id String[] 用户唯一标识
data.company_code String 公司编码
data.company_key String company_key和timestamp MD5加密结果。详见下文。
data.timestamp long 时间戳
  • 请求示例:
{
  "bizId": "634899ef-d591-4829-ac18-0bcc135251ff",
  "timestamp": 1605010305740,
  "data": {
    "user_id": "xxxx@xxx.com",
    "company_code": "xxx",
    "company_key": "xxx",
    "timestamp": "1605010305740"
  }
}
  • 返回参数:
字段 类型 说明
resCode Integer 状态码
resMsg String 描述信息
bizId String 业务唯一识别码
data.code String 用户加密code
  • 返回示例:
成功:
{
  "resCode": 200000,
  "resMsg": "生成code成功",
  "bizId" : "634899ef-d591-4829-ac18-0bcc135251ff",
  "data": {
    "code":"jdsPBlZkOFjQKYokgaSTILKC47Ey9q5Rw6gaS8YePvDaRkO8sWWnUMxqTYYIxDU0"
  }
}
失败:
{
  "resCode": 500000,
  "resMsg": "company key 验证失败",
  "bizId": "634899ef-d591-4829-ac18-0bcc135251ff "
}
MD5 DEMO
public static String byteArrayToHex(byte[] byteArray) {
  char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'a','b','c','d','e','f' };
  char[] resultCharArray =new char[byteArray.length * 2];
  int index = 0;
  for (byte b : byteArray) {
    resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];
    resultCharArray[index++] = hexDigits[b& 0xf];
  }
  return new String(resultCharArray);

}

public static String MD5(String str){
  MessageDigest md = null;
  try {
    md = MessageDigest.getInstance("MD5");
  } catch (Exception e){
    throw new RuntimeException("MD5 Exception");
  }
  md.update((str).getBytes(StandardCharsets.UTF_8));
  return MD5toString.byteArrayToHex(md.digest());
}

代码实现

public static String Encrypt(String sSrc, String sKey, String entryMode) {
  entryMode = !Strings.isNullOrEmpty(entryMode) ? entryMode : "AES/ECB/PKCS5Padding";
  try {
    if (sKey == null) {
      log.info("Key为空null");
      return null;
    }
    // 判断Key是否为16位
    if (sKey.length() != 16) {
      log.info("Key长度不是16位");
      return null;
    }
    byte[] raw = sKey.getBytes("utf-8");
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance(entryMode);//"算法/模式/补码方式"
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
    //此处使用BASE64做转码功能,同时能起到2次加密的作用。
    return URLEncoder.encode(new Base64().encodeToString(encrypted), "utf-8");
  } catch (Exception e) {
    log.error("加密出错", e);
  }
  return null;
}

附录2

跳转地址:https://qa.cloudpense.com/tmp/sso.html?source=new&companyCode=COMPANYCODE&position=POSITION&pathId=PATHID&documentId=DOCUMENTID&headerTypeId=HEADERTYPEID&embedded=EMBEDDED&code=CODE

参数说明如下:

变量 必须 说明
https://qa... 授权后重定向的回调地址,即跳转费控的地址。 qa:测试环境,www:生产环境
source 固定:new
companyCode 企业在费控的编码
position 跳转页面。 main:首页, approveList:审批列表页, claimList:单据列表, createClaim:创建单据页, claim:单据详情页, approve:审批详情页, financeApproval:财务审批页, claimView:单据查看, bankflowList:银行流水, deliveryOperation:集中收单, invoiceList:消费记录, purchaseInvoiceList:采购发票, approveHistoryDetail:审批历史详情, approvalHistoryDetail:财务审核历史详情 ,businessTravel:企业消费管理页
pathId 审批流ID,审批详情和财务审批页额外参数
position=approve&pathId={PATH_ID}
position=financeApproval&pathId={PATH_ID}
documentId 单据ID,单据详情页额外参数
position=claim&documentId={DOCUMENT_ID}
headerTypeId 单据类型ID,创建单据页/单据列表页额外参数, position=createClaim&headerTypeId={HEADER_TYPE_ID},或者
position= claimList&headerTypeId={HEADER_TYPE_ID}
headerId 否,仅 单据头ID,单据查看/审批历史详情/财务审核历史详情页面额外参数
position=claimView&headerId={HEADER_ID},或者
position=approveHistoryDetail&headerId={HEADER_ID},或者
position=approvalHistoryDetail&headerId={HEADER_ID}
groupNum 单据分组的group_num,单据列表页额外参数, 用于显示特定分组的单据列表 position=claimList&groupNum={GROUPNUM}
embedded 跳转网页时, 不需要菜单:Y,需要菜单:N
autoClose 仅用于web
Y:在审批/财务审核通过或拒绝之后会自动关闭页面
code 用户信息加密code

示例:https://qa.cloudpense.com/tmp/sso.html?source=new&companyCode=xxx&position=approve&pathId=25&code=CODE

跳转成功后的首页,如下所示:

main

results matching ""

    No results matching ""