更新时间:2024-05-27 GMT+08:00
分享

开发概述

关于认证

在系统间API交互时,需要对API做认证。CraftArts IPDCenter定义了API认证的规范与SDK,应用在与CraftArts IPDCenter的API集成过程中,需要按照此规范完成认证逻辑。

认证集成简介

CraftArts IPDCenter提供卡片市场功能,在卡片市场中,第三方应用可以上传自定义卡片,卡片会调用第三方应用的API,此时API需要检验请求的合法性,通过集成认证SDK,可实现API合法性校验。

工作原理

统一认证SDK是基于JWT实现的一种认证机制,Json web token (JWT)是在网络应用环境间为了传递声明而执行的一种基于JSON的开放标准(RFC 7519)。该token的设计紧凑且安全,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便从资源服务器获取资源。它也可以被增加一些其它业务逻辑所必须的声明信息。该token可直接被用于认证,也可被加密。

API请求方将请求的用户信息利用私钥哈希生成签名,将用户信息与签名合并生成token,在调用API时将token传递给被调用方,API被调用方获取到此token后,利用公钥验证此token的正确性。

图1 机机认证方案

JWT的组成

图2 Json web token

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。形式为:

A.B.C

样本数据如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJhdWQiOlsiZGVmYXVsdCIsImdhdGV3YXkiXSwiYXBwSWQiOiJkZWZhdWx0IiwiaXNzIjoiZGVmYXVsdCIsImV4cCI6MTU0NDY5MDY0NywiaWF0IjoxNTQ0Njg4ODQ3fQ.J-ngHZy8009k-OAQ7-6Jt2kUzsml6N60d-atVIP3UydsQH_GqFv4rSY_uliqZ2_8ecgcKm0pWAAFtN88t7ehVQ

头部( Header )

JWT需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。

头部信息是经过BASE64编码的,包括以下几个属性:

表1 属性

位置

字段

名称

是否必填

字段类型

字段说明

Header

typ

类型

String

固定值:JWT

Header

alg

算法

String

固定值:RSA

Header

kid

密钥ID

String

密钥ID,由CraftArts IPDCenter颁发。

载荷(Payload)

载荷信息是经过BASE64编码解码后的JSON对象,包括以下几个属性:

表2 属性

位置

字段

名称

是否必填

字段类型

字段说明

使用方式

Payload

iss

发行人

String

该JWT的签发者

如果由机机自动触发,则放appId; 如果由人触发调用,可以放userName:userId:tenantId

Payload

sub

主题

String

该JWT所面向的用户

暂时为空,建议为被调用方appId

Payload

aud

接收系统

String[]

接收该JWT的一方

目标系统的{域名:端口/上下文根}

Payload

exp

过期时间

Date

标识JWT的过期时间

这里是一个Unix时间戳,默认5分钟

Payload

nbf

生效时间

Date

在此之前JWT不可用

暂未启用

Payload

iat

签发时间

Date

标识JWT的签发时间

Unix时间戳

Payload

jti

JWTID

String

JWT唯一标识符,防重放攻击

暂未启用

Payload

claims

私有声明

Map<String, Object>

一个集合,可自定义字段

暂未启用

签名(Signature)

将上面的两个Base64编码后的字符串都用英文句号“.”连接在一起(头部在前),就形成了:

eyJraWQiOiIyZWQ3YWQ4My0zYzhiLTQzYTktOTE2ZC1jOGI2ZWMyYzExNjUiLCJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIiLCJzdWIiOiIiLCJleHAiOjE3MTEwMjA0MTgsImlhdCI6MTcxMTAyMDExOCwianRpIjpudWxsLCJjbGFpbXMiOm51bGx9

我们将上面拼接完的字符串用RSA256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。如果我们用mystar作为密钥的话,那么就可以得到我们加密后的内容:

eyJraWQiOiIyZWQ3YWQ4My0zYzhiLTQzYTktOTE2ZC1jOGI2ZWMyYzExNjUiLCJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIiLCJzdWIiOiIiLCJleHAiOjE3MTEwMjA0MTgsImlhdCI6MTcxMTAyMDExOCwianRpIjpudWxsLCJjbGFpbXMiOm51bGx9.
kQM1KhjZVvfjLSK8aaBX_4HdQNuaDCR1mkZxNWXa7PC38fSGDoPvIxo7kepy0XXM4m1DyJ_zwbC3cwDf5Fz54Lk0WvLe9ulrUqIO86AGeetWfLslRD7X5L_w3H-T7QKffCBlEnEagv_GBLjpxEMpraDTRTPpQu8ERIjRZVioHwQ1XDO1PChgpal1rhOmnF2rOE4ljVbN0VdbN2w2dLLPXhikLvwtEiXLnBKaaOuI7vtFMmWXwjBlqTIFbg39PVyWM4kEpPu2B9LaK5kNVW3OBkOLCP_triZMHlNZlHldEH9gHh2_h8xLKHpAthHXUWvDprtSwWBdWH2rDZlMW03rhnwpXg3ABknRUPNfrtTNy8HDvEGUVLmfkAdTs_D2y1RNt-MRn_fH50DiINOGi_Zf4uErrf5yHL1qln5cprID64ETctd0IuzhCp7weK1TlxzIGqGXClHf6_yjwJ2kC7Xikdk38Zx946ZNB32jdfWbJDZoUnL2v3_T3KThW21huLgB

最后,我们在上面生成的token上加一个前缀“Internal:”,用于标识此token的类型,最后得到的token是:

Internal:eyJraWQiOiIyZWQ3YWQ4My0zYzhiLTQzYTktOTE2ZC1jOGI2ZWMyYzExNjUiLCJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIiLCJzdWIiOiIiLCJleHAiOjE3MTEwMjA0MTgsImlhdCI6MTcxMTAyMDExOCwianRpIjpudWxsLCJjbGFpbXMiOm51bGx9.kQM1KhjZVvfjLSK8aaBX_4HdQNuaDCR1mkZxNWXa7PC38fSGDoPvIxo7kepy0XXM4m1DyJ_zwbC3cwDf5Fz54Lk0WvLe9ulrUqIO86AGeetWfLslRD7X5L_w3H-T7QKffCBlEnEagv_GBLjpxEMpraDTRTPpQu8ERIjRZVioHwQ1XDO1PChgpal1rhOmnF2rOE4ljVbN0VdbN2w2dLLPXhikLvwtEiXLnBKaaOuI7vtFMmWXwjBlqTIFbg39PVyWM4kEpPu2B9LaK5kNVW3OBkOLCP_triZMHlNZlHldEH9gHh2_h8xLKHpAthHXUWvDprtSwWBdWH2rDZlMW03rhnwpXg3ABknRUPNfrtTNy8HDvEGUVLmfkAdTs_D2y1RNt-MRn_fH50DiINOGi_Zf4uErrf5yHL1qln5cprID64ETctd0IuzhCp7weK1TlxzIGqGXClHf6_yjwJ2kC7Xikdk38Zx946ZNB32jdfWbJDZoUnL2v3_T3KThW21huLgB

将上面的token在jwt网站(https://jwt.io/)上进行解析,可以看到具体的内容信息,如下:

图3 解析内容

密钥

上面的token在签名时需要用到一个密钥,方案采用了RSA非对称密钥算法,由私钥进行签名,公钥进行验证签名。此密钥对的生命周期由IPDCenter Space服务管理。由IPDCenter Space服务颁发密钥对,每个系统拥有自己的一对密钥,在颁发完成密钥后,IPDCenter将记录所有的公钥信息、密钥ID信息、APPID等信息。私钥则由应用自己保存。

公钥获取

公钥是用来检验token的,而且校验token时需要使用与私钥对应的公钥,因此,应用需要定时调用IPDCenter提供的接口,查询所有的公钥信息,加载到内存,检验token时找到对应的token进行检验。检验接口的规格如下:

接口地址:

https://域名/随机数文根/basic/mgmt/public/api/v1/keymanage/getPublicKeyList

接口header:
Authorization: 上面生成的token
Content-Type: application/json

接口body:

{
    "offset": 0,
    "limit": 2000
}

接口响应示例:

{
    "code": "IPDC.01020000",
    "datas": [
        {
            "appId": "121",
            "appName": "应用名称",
            "createTime": "2024-03-22T17:42:58.830872000",
            "creator": "xx",
            "isDeleteAble": "N",
            "keyId": "密钥ID, token中解析出密钥ID,根据ID找到对应的公钥,检验token是否合法",
            "publicKey": "公钥信息"
        }
    ],
    "message": "success",
    "totalCount": 3
}
分享:

    相关文档

    相关产品