ID令牌

创造了一个 ID Tokens 最终不是由OAuthLib完成的,而是由您的 RequestValidator 子类。这是因为它们的内容取决于您对用户的实现、他们的属性、您可能希望支持的任何声明,以及您如何对客户端应用程序的概念建模的细节。因此,OAuthLib只是调用您的验证器的 finalize_id_token 方法,具体取决于请求的授权类型(授权码、隐式、混合等)。

请参见下面的示例。

class oauthlib.openid.RequestValidator[源代码]
finalize_id_token(id_token, token, token_handler, request)[源代码]

最终确定OpenID连接ID令牌并签名或加密。

在OpenID Connect工作流中,当请求ID令牌时,会调用此方法。子类应该实现ID令牌的构造、签名和可选加密,如OpenID Connect规范中所述。

这个 id_token 参数是一个包含两个与规范相关的OIDC技术字段的字典。预填充的属性包括:

  • aud ,等于 request.client_id

  • iat 等于当前时间。

  • nonce 如果存在,则等于 nonce 从授权请求中删除。

  • at_hash 、散列值 access_token ,如果相关的话。

  • c_hash 、散列值 code ,如果相关的话。

此方法必须提供必填字段,如下所示:

  • iss ,必填。颁发者响应的颁发者的标识符。

  • sub ,必填。主题标识符

  • exp ,必填。使用OP执行身份验证时,RP不能接受ID令牌的过期时间。

必须添加其他报销申请,请注意 request.scope 应用于确定索赔清单。

欲了解更多信息,请访问 OpenID Connect Core#Claims

参数:
  • id_token -- 包含ID_TOKEN技术字段的词典

  • token -- 不记名代币词典

  • token_handler -- 令牌处理程序(BearerToken类)

  • request (oauthlib.common.Request) -- OAuthlib请求。

返回:

ID令牌(JWS签名的JWT或JWE加密的JWT)

使用pyjwt库的JWT/JWS示例

下面的示例使用加密库加载私钥,并使用PyJWT对JWT进行签名。请注意,“data”字典中的声明列表必须根据身份验证请求进行相应设置。

如果您想返回JWE,可以切换到jwcrypto库。

class MyValidator(RequestValidator):
  def __init__(self, **kwargs):
      with open(path.join(path.dirname(path.realpath(__file__)), "./id_rsa"), 'rb') as fd:
          from cryptography.hazmat.backends import default_backend
          from cryptography.hazmat.primitives import serialization
          self.private_pem = serialization.load_pem_private_key(
              fd.read(),
              password=None,
              backend=default_backend()
          )

      super().__init__(self, **kwargs)

  def finalize_id_token(self, id_token, token, token_handler, request):
      import jwt

      id_token["iss"] = "https://my.cool.app.com"
      id_token["sub"] = request.user.id
      id_token["exp"] = id_token["iat"] + 3600 * 24  # keep it valid for 24hours
      for claim_key in request.claims:
          id_token[claim_key] = request.userattributes[claim_key]  # this must be set in another callback

      return jwt.encode(id_token, self.private_pem, 'RS256')