自定义 JWT 身份验证
自定义JSON web token身份验证提供者允许用户使用来自第三方系统( Atlas App Services外部)的身份验证档案登录,并使用该令牌通过App Services访问权限数据和服务。 外部系统必须返回已签名的JSON web token (JSON web token ) ID包含经过身份验证的用户的唯一 值。
身份验证和授权
第三方 JWT 提供商对用户进行身份验证并返回 JWT。App Services 使用 JWT 来识别应用程序的用户,并就用户请求提供授权。
App Services 不受第三方提供商使用的身份验证方法的影响。它不对外部身份验证系统的要求或身份验证方法施加限制。例如,系统可能要求用户执行多重身份验证 (MFA)、提供特定档案或以其他方式识别自己的身份。
JWT 身份验证的工作原理
网上有很多深入探讨 JWT 身份验证和令牌结构复杂性的资源。在 App Services 上下文中,下图提供了用户登录 Device Sync 应用的流程。图表下方的步骤提供了详细信息。
使用 App Services 进行 JWT 身份验证要遵循以下一般步骤:
用户通过提供商要求的任何方式登录到第三方身份验证提供商。
如果身份验证成功,提供商将向客户端应用程序返回 JWT。
客户端应用程序登录 App Services 应用程序,提供 JWT 凭据。
App Services 解析和解码 JWT。
如果您在 App Services 中手动提供签名密钥,则 App Services 会检查 JWT 中的签名密钥是否与您指定的签名密钥之一匹配。如果是这样,则用户已通过身份验证。
如果将 App Services 配置为使用 JSON Web 密钥 (JWK) URI,则 App Services 会将 JWT 和公钥传递给第三方提供商的 JWK API。
提供者对签名进行解码和验证,并返回一个 JWK。
App Services 会检查 JWK 中的签名是否与 JWT 的签名匹配。如果是这样,则用户已通过身份验证。
重要
访问令牌始终在 30 分钟后过期
App Services 始终会指定 30 分钟的访问令牌有效期,即使自定义 JWT 令牌会通过 exp
密钥来指定其他有效期:App Services 会检查自定义 JWT 令牌 exp
,从而确保该令牌在 30 分钟有效期之前仍然有效。有关 App Services 访问令牌的详细信息,请参阅管理用户会话。
配置
您可以通过用户界面或使用 CLI 配置自定义 JWT 身份验证。从下面选择您首选的方法。
您可以通过从 Authentication 页面选择 Custom JWT Authentication,从App Services用户界面启用JSON web token身份验证提供者程序。
要使用 启用和配置自定义JSON web token 身份验证提供者,请在App Services CLI 中为其定义 配置对象/auth/providers.json
。
自定义JSON web token提供商配置采用以下形式:
{ "custom-token": { "name": "custom-token", "type": "custom-token", "config": { "audience": "<JWT Audience>", "requireAnyAudience": <boolean>, "signingAlgorithm": "<JWT Signing Algorithm>", "useJWKURI": <boolean>, "jwkURI": "<JWK or JWKS URL>", }, "secret_config": { "signingKeys": [ "<Signing Key Secret Name>", ... ] }, "metadata_fields": [ { "required": <boolean>, "name": "<JWT Field Path>", "field_name": "<Metadata Field Name>", }, ... ], "disabled": <boolean> } }
验证方法
Verification Method 字段确定 App Services 如何验证从 JWT 提供者返回的 JWT。您可以将 App Services 配置为使用您提供的签名密钥来验证 JWT,或者使用第三方提供者颁发的 JSON Web 密钥 (JWK) URI 进行验证。
手动指定签名密钥
您可以将应用配置为使用一个或多个签名密钥来验证 JWT。您需要提供两个设置:
字段 | 说明 |
---|---|
Signing Algorithm config.signingAlgorithm | 外部系统用于对 JWT 进行签名的加密方法。自定义身份验证支持使用以下任一算法签名的 JWT:
|
Signing Key secret_config.signingKeys |
设置签名算法:
创建一个或多个签名密钥以对 JWT 进行签名。要执行此操作,请提供密钥名称(仅供以后参考),然后指定 256 位签名密钥。
"config": { "signingAlgorithm": "<JWT Signing Algorithm>", }, "secret_config": { "signingKeys": [ "<Signing Key Secret Name>", ... ] }
警告
Signing Key是一种密钥,而任何拥有该密钥的人员均可为您的应用程序颁发有效的用户档案。切勿将其存储在可公开访问的位置,例如 git 存储库、留言板或代码中。
Use a JWK URI
某些外部身份验证系统提供 JSON Web 密钥集(JWKS),它描述了系统用于对 JWT 进行签名的签名算法和签名密钥。您可以使用 JWKS 配置提供商,而无需手动指定签名算法和密钥。 返回的 JWKS 必须包含kid
标头,该标头指定 JWKS 中密钥的密钥ID 。 JWKS 最多可以指定三个签名密钥,并且必须使用RS256
算法。
注意
JWK 和 JWKS 会在 Atlas App Services 中同义使用。
您只需要提供一个值:
JWK URI
,这是托管 JWK 或 JWKS 服务的第三方 URL。选择此选项时,App Services 会自动将加密设置为所需的RS256
方法。
指定第三方 JWKS 端点的 URL:
"config": { "useJWKURI": <boolean>, "jwkURI": "<JWK or JWKS URL>" }
元数据字段
Metadata Fields 是描述每个内部 App Services 用户的额外数据。App Services 会根据第三方 JWT 包含的字段的值来确定每个元数据字段的值。例如,如果您设置了某一用户的 name
字段,App Services 则会在 JWT 中使用此字段作为该用户的显示名称。
注意
每当用户登录时,App Services 都会刷新用户的元数据,并显示用户元数据的 data
对象中的字段。
重要
JSON web token和元数据字段字符限制
JWT 令牌的长度随着令牌中元数据字段的数量和每个字段的大小而增加。App Services 将 JWT 令牌的长度限制为 1 百万个字符,并将每个元数据字段的长度限制为 4096 个字符。如果超限,App Services 将记录错误,并且工单不会被处理。
您需要为每个元数据字段指定三个值:
字段 | 说明 |
---|---|
Required required | 如果为 true ,则与该提供商关联的所有用户均须填写元数据字段。外部系统返回的 JWT 必须为 Path 指定的字段赋值。 |
Path name | JSON web token中包含元数据字段值的字段的名称或路径。 要指定嵌入式对象中字段的路径,请使用点表示法。 如果JSON web token中字段本身的名称包含句点 ( . ) 字符,请使用反斜杠 (\ ) 对句点进行转义。 示例,如果名称为http://example.com/id ,请使用http://example\.com/id 。 |
Field Name field_name | 可选。用户对象的 默认值规则
|
要定义元数据字段,请单击 Add Field 并指定 JWT 中的元数据字段与用户对象中相应字段名称之间的映射。
要在自定义JSON web token身份验证配置文件中定义元数据字段,请将该字段的条目添加到 metadata_fields
大量中。 每个条目都应是以下形式的文档:
{ required: <boolean>, name: "<field path>", field_name: "<metadata field name>" }
使用反斜杠 (\
) 对JSON web token密钥中的句点 (.
) 字符进行转义。
示例,在此JSON对象中,将路径名称中的"nested_key"
表示为valid\.json\.key\.nested_key
。
{ "valid.json.key": { "nested_key": "val" } }
例子
外部身份验证系统返回 JWT,其中在 user_data
字段中包含有关每个用户的附加信息:
(JWT JSON) { "aud": "myapp-abcde", "exp": 1516239022, "sub": "24601", "user_data": { "name": "Jean Valjean", "aliases": [ "Monsieur Madeleine", "Ultime Fauchelevent", "Urbain Fabre" ] } }
要将 user_data
字段中的值包含在每个用户的用户对象中,请在 App Services 配置中指定以下元数据字段:
路径 | 字段名称 |
---|---|
user_data.name | name |
user_data.aliases | aliases |
现在,用户对象将包括这些字段:
(USER METADATA OBJECT) { "id": "59fdd02846244cdse5369ebf", "type": "normal", "data": { "name": "Jean Valjean", "aliases": [ "Monsieur Madeleine", "Ultime Fauchelevent", "Urbain Fabre" ] }, identities: [ { "id": "24601", "provider_type": "custom-token", "data": { "name": "Jean Valjean", "aliases": [ "Monsieur Madeleine", "Ultime Fauchelevent", "Urbain Fabre" ] }, } ] }
互动讨论
JWT 的 Audience 指定令牌的预期接收者。JWT 在 aud
声明中描述了受众。App Services 希望 aud
包含已配置提供者的应用程序的应用程序 ID。但是,如果外部身份验证系统 JWT 指定不同的 aud
值,则您可以将提供者配置为使用此值。
您可以配置两个字段:
字段 | 说明 |
---|---|
Audience | 预期在客户端 JWT 中找到的一个或多个受众的单个值或以逗号分隔的值列表。 |
Require | 如果提供多个受众,则必须指定如何处理它们。您的选项包括:
|
要设立受众,请配置config.audience
。 您可以配置两个字段:
字段 | 说明 |
---|---|
audience | 一个字符串大量,用于指定预期在客户端JSON web token中找到的一个或多个受众。 |
requireAnyAudience | 布尔值。 如果为 false ,则JSON web token必须包括所有列出的受众。 如果为 true ,则JSON web token必须仅包含一个或多个列出的受众。 |
"config": { "audience": [ "<JWT Audience>", ], "requireAnyAudience": <boolean>, }
使用 JWT 身份验证
您可以注册新的自定义 JWT 用户并使用 Realm 软件开发工具包(Realm SDK)之一或 API 服务登录。
Realm SDKs
有关演示如何使用自定义 JWT 身份验证注册和登录的代码示例,请参阅您的首选语言和平台的 Realm 软件开发工具包文档:
API 服务
您可以使用自定义 JWT 提供商对 Data API 请求进行身份验证。您可以要求用户在使用服务之前创建帐户,也可以将 API 端点配置为在请求包含与现有用户不匹配的有效 JWT 时自动创建新用户帐户。在使用服务 API 时,有两种使用 JWT 的方法:
直接在
jwtTokenString
请求标头中指定 JWT使用 JWT 启动用户会话,并将会话访问令牌作为
Authorization
标头不记名令牌包含在内。
有关更多信息,请参阅对数据API请求进行身份验证。