令牌机制
令牌机制
简单登录解决方案涉及两种类型的令牌。
- 关联令牌。 发放关联令牌是为了验证系统中用户的身份。关联令牌是与亚马逊用户关联的证据。关联令牌可能包含其他环境信息,例如关联账户的时间。
- 简单登录(SSI)令牌。 亚马逊每次为每个新的登录请求发放的临时令牌。SSI令牌用于将关联令牌安全地传输回应用。它在其中封装了一个关联令牌,用于证明底层关联令牌的有效性,并授权将其用于客户身份验证。
关联令牌优势
使用关联令牌具有以下优势。
- 提供一个强有力的断言,即用户已通过您的身份验证,并且已获得账户关联的批准。普通标识符不足以证明用户身份验证或授权。
- 允许您在亚马逊上消除存储和跟踪用户身份之间关联的繁重工作,同时仍然有权授予账户关联。
- 允许您捕获有关账户关联的更多环境信息,如源设备信息,作为令牌本身的一部分,它们可以在令牌验证期间使用这些信息。否则,您将需要构建一个自定义解决方案来维护这些数据。
关联令牌规范
关联令牌规范的版本使用字符串文字LINK-TOKEN-1.0
来标识。
- 关联令牌必须包含一个标识符,该标识符用于在您的身份管理系统中唯一标识应用的用户。
- 关联令牌的范围必须限于关联的亚马逊用户,这样就可以限制它的使用,从而仅限对该特定亚马逊用户注册的设备。这通过在令牌中嵌入亚马逊用户ID (
AmazonUserId
)来实现。亚马逊用户ID通过简单登录客户端API中的getUserAndLinks()
方法公开给应用。有关详细信息,请参阅SSI客户端API。 - 关联令牌必须包括关联验证密钥,这是一种用于检查相应SSI令牌的真实性和完整性的椭圆曲线(EC)公有密钥。有关关联验证密钥的详细信息,请参阅使用的加密密钥。
- 您可以加入其他环境字段,例如设置账户关联的时间,或从中启动账户关联的源应用或设备的元数据。
- 要保持令牌中编码的数据元素的机密性,请对令牌有效负载进行加密。用于加密和解密操作的加密密钥由您管理,不应与亚马逊共享。
- 若要在令牌验证期间验证令牌的完整性和真实性,必须对令牌进行数字签名。用于数字签名的加密密钥由应用所有者管理,不需要与亚马逊共享。
- 关联令牌没有到期时间。关联令牌的有效性与用户账户关联的当前状态有关。
- 从亚马逊的角度来看,关联令牌是一个不透明的字符串。该规范没有为令牌的构建规定任何具体的编码方案。
关联令牌生命周期
关联令牌没有到期时间。它们的使用受短期SSI令牌限制。关联令牌在系统中有效,直到用户启动让账户关联无效的操作为止。客户可以通过关闭简单登录来删除账户关联,无论是在其账户级别的全局登录还是特定于特定应用的登录。这些设置可以通过设备设置菜单进行管理,也可以通过亚马逊网站远程管理。当客户开始从亚马逊端取消关联时,关联被标记为已删除,并且相应的关联令牌在简单登录服务器上被销毁。
SSI令牌规范
SSI令牌规范使用字符串文字SSI-TOKEN-1.0
来标识。
- SSI令牌由亚马逊生成,用于安全地将关联令牌从亚马逊传输到您的系统,同时使用关联账户在应用上验证用户身份。
- SSI令牌将关联令牌封装在其内部,并额外包括以下数据以限制使用范围:
- 定向ID。 标识设备上当前有效的亚马逊用户。
- 时间戳字段。 用于指定令牌有效的时间窗口。此时间窗口的持续时间设置为自令牌发放之时起五分钟。这一时间长度通常足以完成正在进行的登录请求,并考虑到亚马逊服务器和您的服务器之间潜在的时钟差异。
- 令牌未加密。
- 该令牌由亚马逊使用关联签名密钥进行签名,该密钥由您在设置账户关联时与关联令牌一起发放。
该令牌被编码为签名的JSON Web令牌(JWT)。下面对字段进行了解释。
标头
{
"alg": "ES384",
"typ": "JWT",
"schema": "SSI-TOKEN-1.0"
}
有效负载
{ "iss": "https://ssi.amazon.com", //将亚马逊SSI服务标识为令牌发放方
"aud": "<PARTNER_VENDOR_ID>", //指示令牌的接收方。 一种唯一的供应商ID,由亚马逊应用商店开发者控制台在使用了开发者加入流程期间分配。
"linkInfo": {
"linkToken": {
"schema": "LINK-TOKEN-1.0",
"token": "<LINK_TOKEN>" //由开发者发放的关联令牌。
},
"amazonUser": "<AMZN_USER_ID>", //开发者限定范围的 定向ID,表示用户的亚马逊账户,其在源亚马逊设备上有效。 开发者将该值与关联令牌中捕获的亚马逊用户ID进行匹配,以验证关联令牌是否仅在预期设备上使用。
"partnerUser": "<PARTNER_USER_ID>", //定向ID,表示由开发者在账户关联期间提供的用户账户。
},
"nbf": 1589366574, //令牌有效性 - 开始时间 - 自epoch以来经过的秒数
"iat": 1589366874, //令牌发放时间 - 自 epoch以来经过的秒数
"exp": 1589367174, //令牌有效性 - 结束时间 - 自epoch以来经过的秒数
"jti": "<JWT_ID>" //令牌的唯一标识符
}
按以下方式将令牌序列化。
- unsignedToken = base64UrlEncode(header) + '.' + base64UrlEncode(payload)
- 签名
- 数字签名算法: 使用P-384和SHA-384的ECDSA
- 签名输入:unsignedToken
- 签名密钥:linkSigningKey
- 令牌 = unsignedToken + '.' + base64UrlEncode(signature)
SSI令牌和安全身份验证
- 关联令牌表示与所涉及的身份的联系。因此,只要账户关联有效,它就保持有效。SSI令牌用作授权令牌,该授权令牌断言账户关联仍然有效,并且用于批准使用相应的关联令牌来验证用户身份。
- 由于SSI令牌是暂时的,因此它将底层关联令牌的使用限制在短时间窗口内。对于使用关联账户的每次新登录尝试,都必须获取新的SSI令牌。
使用的加密密钥
本部分介绍如何在令牌生成和验证中使用加密密钥。它还指明了对密钥所有权和管理的期望。
AppStoreKeyPair
: 亚马逊应用商店在应用提交期间为每个应用自动提供的2048位RSA密钥对。公有密钥通过亚马逊应用商店开发者控制台与您共享。要查找公有密钥,请登录开发者控制台。在上传您的应用文件屏幕上,在Additional information(其他信息)部分单击View public key(查看公有密钥)。使用此密钥加密需要安全传输到亚马逊的有效负载。一旦分配AppStoreKeyPair
,其在应用的整个生命周期内保持不变,并且在提交新版本的应用时不会更改。LinkTokenEncryptionKey
和LinkTokenDecryptionKey
: 用于分别加密和解密关联令牌。您可以使用对称或非对称密钥加密。这些密钥由您在内部管理,不会与亚马逊共享。LinkTokenSigningKey
和LinkTokenVerificationKey
: 用于分别对关联令牌的真实性和完整性进行签名和验证。您可以使用具有非对称密钥对的数字签名,也可以使用采用了密钥的MAC生成的地址。您在内部管理密钥,不与亚马逊共享。
注意: 当您使用经过身份验证的加密方案(如AES-GCM)时,一个对称密钥将充当所有4个密钥的角色:
LinkTokenEncryptionKey
、LinkTokenDecryptionKey
、LinkTokenSigningKey
和LinkTokenVerificationKey
。LinkKeyPair
是一个椭圆曲线(ECC)密钥对(支持的曲线:secp384r1/NIST P-384),由您作为账户关联设置的一部分生成。必须为每个关联账户生成一个不同的密钥对。LinkSigningKey
(LinkKeyPair
的私钥部分)以及LinkVerificationKey
(LinkKeyPair
的公有密钥部分)用于签名和验证SSI令牌。这些密钥的使用方式如下:- 在账户关联设置过程中:
LinkSigningKey
使用特定于应用的AppStoreKeyPair
的公有密钥进行加密,相应的LinkVerificationKey
作为LinkToken
内的字段添加。- 在建立账户关联的请求中同时包含
LinkToken
和加密的LinkSigningKey
。 - 亚马逊使用
AppStoreKeyPair
的相应私钥解密LinkSigningKey
,并将解密后的密钥作为SSI服务器上账户关联对象的一部分持续保留。
- 当应用稍后查询关联账户以通过简单登录让客户登录时:
- 亚马逊为每个关联账户生成一个SSI令牌,并使用相应的
LinkSigningKey
进行签名。 - 使用通过解密和解码
LinkToken
获得的相应LinkVerificationKey
验证SSI令牌签名。
- 亚马逊为每个关联账户生成一个SSI令牌,并使用相应的
- 在账户关联设置过程中:
最佳实践
亚马逊应用商店建议您使用亚马逊的库来生成和验证令牌,因为这有助于大幅简化开发工作。SSI令牌库提供了一个默认实现,用于使用您提供的数据和加密密钥生成和验证关联令牌。每次生成关联令牌时,它都会负责自动生成一个新的关联密钥对。有关详细信息,请参阅SSI令牌库。
亚马逊应用商店建议您使用亚马逊的库来生成和验证令牌,因为这有助于大幅简化开发工作。SSI令牌库提供了一个默认实现,用于使用您提供的数据和加密密钥生成和验证关联令牌。每次生成关联令牌时,它都会负责自动生成一个新的关联密钥对。有关详细信息,请参阅SSI令牌库。
使用关联令牌的客户身份验证
要在简单登录流程中使用关联账户对客户进行身份验证,应用将在账户关联时使用与亚马逊共享的关联令牌。当应用查询关联账户时,亚马逊将关联令牌封装在签名的SSI令牌中,以证明账户关联仍然有效。
注意: 只有作为SSI令牌的一部分获得的关联令牌才能用于身份验证,因为其他关联令牌不足以证明账户关联的当前状态。作为SSI令牌的一部分获得的令牌还验证关联令牌的使用是否在其范围内,例如在预期设备上使用。
以下是身份验证步骤的摘要:
- 检查SSI令牌是否是有效签名的JWT,是否符合已发布的架构。
- 检查SSI令牌是否在其有效性时间窗口内使用(
ssiToken.payload.nbf
<=currentTime
<ssiToken.payload.exp
) - 将SSI令牌解封,以从其有效负载中提取关联令牌。
- 执行以下操作验证关联令牌:
- 解密令牌
- 验证令牌签名
- 令牌字段解码
- 使用从关联令牌中提取的
LinkVerificationKey
验证SSI令牌签名。 - 通过检查关联令牌限定范围的亚马逊用户是否与当前有效的亚马逊用户匹配,验证关联令牌权限。通过将关联令牌中编码的Amazon用户ID字段与SSI令牌中存在的亚马逊用户ID字段进行比较来完成此操作(
ssiToken.payload
>linkInfo
>amazonUser
)。 - 如果之前的所有步骤都成功完成,请使用关联令牌所代表的关联账户完成身份验证。如果出现任何故障,请中止简单登录流程,然后回退到其他标准登录选项。
Last updated: 2023年10月2日