IBM Cloud Docs
验证令牌

验证令牌

令牌验证是现代应用程序开发中的重要组成部分。 通过验证令牌,您可以保护应用程序或 API 免受未经授权的用户的影响。IBM Cloud® App ID 使用访问令牌和身份令牌,以确保在授予用户或应用程序访问权之前对其进行认证。 如果使用的是 App ID 提供的其中一个 SDK,那么已为您获取并验证令牌!

有关如何在 App ID 中使用令牌的更多信息,请参阅了解令牌

令牌用于验证个人的身份是否与其声明的一致。 令牌确认用户在指定的时间长度内可能拥有的任何访问许可权。 当用户登录到您的应用程序并获得一个令牌时,您的应用程序必须在用户获得访问权限之前对其进行验证。

如果 App ID 没有与我所用语言对应的 SDK 该怎么做?

有三个选项供您使用:

  • 使用 App ID API
  • 实现您自己的验证逻辑
  • 使用符合 OIDC 的任何开放式源代码 SDK

使用 App ID API

可以使用 App ID 通过自省来验证令牌。

  1. /introspect API 端点发送 POST 请求以验证令牌。 请求必须提供令牌以及包含客户端标识和私钥的基本授权头。

    示例请求:

    POST /oauth/v4/<tenantID>/introspect HTTP/1.1
    Host: us-south.appid.cloud.ibm.com
    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic jdFlUaGlZUzAwTW0Tjk15TmpFMw==
    Cache-Control: no-cache
    
    token=XXXXX.YYYYY.ZZZZZ
    
  2. 服务器会检查令牌的到期时间和签名,并返回一个 JSON 对象,指示令牌是处于活动状态还是不活动状态。

    示例响应:

    {
    "active": true
    }
    

手动验证令牌

您可以在本地通过解析令牌,验证令牌签名和验证存储在令牌中的声明来验证令牌。

  1. 解析令牌。 JSON 网络令牌(JWT) 是一种安全传递信息的标准方式。 它包含三个主要部分:头、有效内容和签名。 它们采用 base64URL 编码,并以点 (.) 分隔。您可以使用可用于解析令牌的任何 base64URL 解码器。 或者,您可以使用 列出的任何库来解析令牌。

    已编码的令牌示例:

    eyJhbGciOiJSUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJhMmszIn0
    .eyJpc3MiOiJhcHBpZC1vYXV0aCIsImF1ZCI6ImFiYzEyMyIsImV4cCI6MTU2NDU2Nn0
    .IycnAGUmMHzpTWbe-qaRsx0B4Zi-SVav710Fb_8CTCQvLrHX9d42WuCZ5bW
    d-ikgEsf6waQxeBfhfwYxwHN87LZupApagVMZtylVAnXhG1pHu_32wbZsPvg6QjzNO
    j6ys2Lfl3qfb5Qrp9u4IsZltKPEN8HdfeOcKXxpw6UqP-8
    

    解码的令牌示例:

    {
    "alg": "RS256",
    "typ": "JOSE",
    "kid": "a2k3",
    "iss": "https://us-south.appid.cloud.ibm.com/oauth/v4/39a37f57-a227-4bfe-a044-93b6e6050a61",
    "aud": "abc123",
    "exp": 1564566
    }
    
  2. 调用 /publickeys 端点 以检索公用密钥。 返回的公钥格式为 JSON 网络密钥(JWK)

    示例请求:

    GET /oauth/v4/<tenantID>/publickeys HTTP/1.1
    Host: us-south.appid.cloud.ibm.com
    Cache-Control: no-cache
    
  3. 将密钥存储在应用程序高速缓存中以供未来使用。 存储密钥会加快进程,并可在发出其他调用时防止网络延迟。

  4. 导入公用密钥参数。

    示例响应:

    {
    "keys": [
       {
          "kty": "RSA",
          "use": "sig",
          "n": "AsdaE",
          "e": "SDAasw",
          "kid": "ad123dCAz"
       }
    ]
    }
    
    公钥参数
    参数 描述
    kty 定义所使用的算法。
    use 定义密钥的用途。
    kid 定义密钥的唯一标识。
    其他 可能还有特定于算法的其他剩余参数也必须导入。
  5. 验证令牌的签名。 令牌头包含用于对令牌签名的算法以及匹配的公用密钥的密钥标识或 kid 声明。 公用密钥不会频繁更改,所以可以在应用程序中高速缓存公用密钥,有时也可以对公用密钥进行刷新。 如果高速缓存的密钥缺少 kid 声明,那么可以在本地验证令牌。

    1. 使应用程序验证入局令牌头的内容是否与公用密钥的参数相匹配。
    2. 具体检查是否使用了相同的算法,以及公用密钥高速缓存是否包含具有相关密钥标识的密钥。
    3. 确保散列值与公用密钥的 PEM 格式的签名相同。 可以通过组合并散列化令牌的有效内容头来获取散列值。 由于此过程可能很复杂,难以手动实现,因此使用其中一个列出的库来验证签名可能会很有用。
  6. 验证存储在令牌中的声明。 要验证未来检查,可以使用此列表

    必须验证的索赔
    声明 描述
    iss 颁发者必须与 App ID OAuth 服务器相同。
    exp 当前时间必须早于到期时间。
    aud 受众必须包含应用程序的客户端标识。
    tenant 租户必须包含应用程序的租户标识。
    scope 授予用户的许可权的作用域。 这是特定于访问令牌的。