Skip to content
marstone edited this page May 6, 2024 · 42 revisions

Abstract/概述

  • 本文旨在描述流程平台数字签章的工作原理和接入要求,其中内容包括两部分:
    • PDF数字签章:用于离线文件(PDF)的第三方公信
    • 网页文本签章:用于防篡改(保障文本内容变更后可检测)、防抵赖(保障签名文本来自可信的签名者)
  • 老版本参考:SignatureAPI(已废弃)

模块关系

模块编号 名称 提供功能
【A】 流程平台 负责签章流程的配置、签署过程、提供签章相关API
【B】 签章管理系统 负责提供签章分发授权管理、签署后文件的查看、和CA集成
【C】 CA平台 负责提供API实现证书管理、签章管理、PDF签署能力
【D】 SSO 负责实现多因子认证(MFA)
【E】 导出API 负责将Word导出为未盖章的PDF

Signature API

  • 签章API,需由 签章管理系统 实现。
  • 签章API包括两部分:
    • 后端API部分,提供PDF签署能力。采用 GraphQL 协议。可注册到 数据网关
    • 前端URL部分:提供用户选章页面,通过后端 discovery 接口给出
  • 签章API服务注册地址GraphQL 内省地址($ep)。

后端API部分

type Query {
  # 服务发现,查询跳转地址 
  discovery() : SignatureConfiguration
  # 查询用户可使用的印章列表,必须使用用户token或者account参数
  userSeals(): [Seal!]
  # 查询用户可管理的签章列表 
  adminSeals(filter: SealFilter): [Seal!]
}
type Mutation { 

  # 对PDF文件签名
  signFile(# 待签署文件地址
           file:URL!, 
           # 签署人ID 和 需满足的多因子认证 
           signer:String, mfa:String,
           # 印章ID 和 盖章位置 
           seal:String!, sealAttr:String, sealLoc: SignatureLocation, 
           # 盖章意见 和 盖章意见位置 
           comment:String, commentLoc: SignatureLocation
           # 是否归档、归档/签署时的流程 
           archive: Boolean, task: SignatureTask) : SignatureFile 

  # 对文本进行签名
  signText(text:String!, signer:String!, mfa:String!, seal:String!, sealAttr:String) : Signature 

  # 新建印章,必须使用用户token或者account参数
  createSeal( 
    # 签章显示名
    text:String!,
    # 签章图片数据,格式:"data:image/png;base64,iVBORw0KGgoA..." 
    imageData:String, 
    # 印章类型,可选值为:"personal", "corporate"。目前仅支持个人章
    kind: String
  ) : Seal!

  # 删除印章,必须使用用户token或者account参数
  deleteSeal(id: ID!) : Seal

  # 更新签章信息、签章使用权限
  updateSeal(id: ID!, userFilters: String) 

  # 分级授权:签章管理权限 
  updateSealAdmins(id: ID!, adminFilters: String, filter: SealFilter) 
}
 
type SignatureConfiguration { 
  # API版本,用于兼容性判断 
  apiVersion: Int 
  # 签章选择器URI地址 
  sealSelector: String 
  # 签章生成器URI地址,PC端,通过链接 
  sealGenerator: String 
  # 签章生成器URI地址,移动端,通过扫码 
  sealGeneratorBarcode: String 
  # 是否支持文本签名,默认 false  
  sealText: Boolean 
  # 是否支持签章增删,默认 false  
  sealEdit: Boolean
  # 功能特征列表,20240429 新增
  # "unique-personal-seal": 每用户只支持一个手写签名
  features: [ String! ]
}

# 一个电子印章 
type Seal {
  # 机读唯一编码
  name: ID
  # 显示名
  text: String
  # 印章图标的URI地址 
  image: String
  # 印章类型,可选值为:"personal", "corporate"
  kind: String
  # 证书
  certificate: Certificate 
  # 印章权限:可使用的人员身份列表 
  # UserFilter参考定义:https://github.com/infoplus/docs/wiki/UserFilter 
  userFilters: String 
  # 印章权限:可管理的人员身份列表 
  # UserFilter参考定义:https://github.com/infoplus/docs/wiki/UserFilter 
  adminFilters: String 
}

# 证书
type Certificate {
  # 机读标识(序列号)
  name: ID!
  # 版本
  version: String
  # 颁发者
  issuer: String
  # 使用者
  subject: String
  # Common Name
  commonName: String
  # 描述(含使用范围)
  description: String 
  # 有效期 - 开始时间
  validStart: Int
  # 有效期 - 结束时间
  validLimit: Int
  # 签名算法
  algorithm: String
  # 证书签名
  signature: String
  # 公钥
  publicKey: String
}

# 一个人员
type User {
   # 统一身份认证中的人员OpenID
   openid: ID 
   # 人员账号,企业内唯一
   account: String!
   # 姓名
   name: String
}

# 使用电子印章的一次签名
type Signature {
  # 签署人
  signer: User
  # 签署人选章时通过的多因子认证列表,空格分隔
  mfa: String 
  # 所盖章信息
  seal: Seal
  # 印章的签名算法
  algorithm: String
  # 印章的签名
  signature: String
  # 签名时间,Unix时间戳(精确到秒)
  timestamp: Int
  # 签署意见 
  comment: String 
  # 签署内容,可选,仅当签署文本时需要 
  text: String 
  # 文本摘要,格式 {MD5}XXXX 
  textHash: String 
  # 验签链接 
  uri: URI
  # 扩展属性,由签章选择器提供、保存 
  attributes: JSON 
}

# 使用电子印章签署过的一个PDF文件 
type SignatureFile {
    # FileAPI生成的文件ID 
    id: ID
    # 文件下载地址
    uri: String 
    # 文件名 
    text: String 
    # 文件大小
    size: Int        
    # 文件类型,仅支持 "application/pdf"
    mime: String
    # 最后更新时间,Unix时间戳(精确到秒)
    updated: Int
    # 所盖的签章列表 
    signatures: [Signature!]
}

# 盖章位置 
type SignatureLocation {
  x: Integer
  y: Integer
  keyword:String
}

# 盖章流程的任务信息,对于非任务级签章,此级别信息可能不完整 
# 可参考类比 https://github.com/infoplus/docs/wiki/TaskCenterAPI 定义
type SignatureTask {
  # 任务UUID 
  id: ID  
  # 任务所在的流程节点编码
  code: String 
  # 办理用户 
  actionUser: User 
  # 办理时选择的动作名称
  actionName: String 
  # 办理时选择的动作编码
  actionCode: String 
  # 导出PDF时使用的Word模版ID
  wordTemplate: String
  # 导出PDF时使用的Word模版文件名
  wordTemplateName: String
  # 签署文件的ID,用于连续签署
  signFileId: String 
  # 所属流程的流水信息 
  process: SignatureProcess 
}

# 盖章流水信息 
type SignatureProcess {
  # 流程实例流水号
  entry: String
  # 流程实例名称
  text: String 
  # 所属App
  app: SignatureApp
}

# 盖章流程应用的信息
type SignatureApp {
  # 流程应用UUID
  id: ID
  # 流程应用编码
  code: String 
  # 流程应用名称
  text: String 
}


# 印章过滤器
input SealFilter { 
  # 数据权限过滤器
  data: DataFilter 
}

# 数据权限过滤器 
input DataFilter {
  # 仅支持 "seal" (按印章的 adminFilters 过滤) 
  in: [ String! ]
} 
错误码 Explained
MFA_INSUFFICIENT 请求盖章时的mfa参数,不能被用户选择印章时通过的mfa涵盖
SEAL_UNAUTHORIZED 请求盖章时的seal参数,和通过签章选择器选择的印章ID不符或用户无权使用

前端URL部分:签章选择器

  • 参数列表
Parameter Type Explained
token String 回调时所需的凭证
file URL 要签署的文件地址
mfa String 可选。所需mfa级别。空格分隔。默认不需额外验证
sealKinds String 可选。支持的签章类型列表。空格分隔。默认不限制
sealIds String 可选。允许使用的签章Id列表。默认不限制
signers String 可选。允许签名的用户账号列表。默认不限制
tenantUserId String 当前登录用户Principal,用于避免iframe内外用户不一致
tenant String 租户编码
  • 返回值
    • 通过Hash返回所选的章。具体方式参考 InfoPlus IFrame 控件
    • 数据结构为 #seal=encodeURIComponent(JSON.stringify({Seal对象}))

Seal Control/印章控件

  • 支持数据类型:Signature
  • 签章控件 通过 SignatureAPI 前端部分规范,打开 签章选择器
  • 签章控件 在检测到 seal 返回值后,负责关闭签章选择器

Signature Control/签名控件

  • 支持数据类型:Signature
  • 除了支持外 签章选择 功能外:
    • 如可写,表单提交时,根据 format 生成文本数据
    • 如只读,显示时根据 format 生成文本数据对比验证,以及可调用后端接口进行服务端验证(待定)
Clone this wiki locally