请求验证器

class oauthlib.oauth1.RequestValidator[源代码]

OAuth 1提供程序的验证器/数据存储交互基类。

OAuth提供程序应该继承RequestValidator并实现下面概述的方法和属性。文档中提供了有关每个方法和属性的更多详细信息。

用于检查输入参数格式的方法。常见的测试包括长度、字符集、成员资格、范围或模式。这些测试被称为 whitelisting or blacklisting 。列入白名单更好,但列入黑名单有助于发现恶意活动。以下方法是默认实现:

  • check_client_key

  • check_request_token

  • check_access_token

  • check_nonce

  • check_verifier

  • check_realms

上面的方法默认将输入参数列入白名单,检查它们是否为字母数字,并且介于最小和最大长度之间。可以使用一些属性来配置这些方法,而不是重载这些方法。

  • @SAFE_CHARACTERS->(字符集)

  • @CLIENT_KEY_LENGTH->(最小、最大)

  • @REQUEST_TOKEN_LENGTH->(最小、最大)

  • @ACCESS_TOKEN_LENGTH->(最小、最大)

  • @NONCE_LENGTH->(最小、最大)

  • @VERIMER_LENGTH->(最小、最大)

  • @领域-> [list, of, realms]

用于验证/无效输入参数的方法。这些检查通常命中持久存储或临时存储,如数据库或文件系统。有关详细用法,请参阅每个方法文档。必须实施以下方法:

  • validate_client_key

  • validate_request_token

  • validate_access_token

  • validate_timestamp_and_nonce

  • validate_redirect_uri

  • validate_requested_realms

  • validate_realms

  • validate_verifier

  • invalidate_request_token

用于从存储中检索敏感信息的方法。必须实施以下方法:

  • get_client_secret

  • get_request_token_secret

  • get_access_token_secret

  • get_rsa_key

  • get_realms

  • get_default_realms

  • get_redirect_uri

用于保存凭据的方法。必须实施以下方法:

  • save_request_token

  • save_verifier

  • save_access_token

用于验证输入参数的方法。这些方法在用户(AuthorizationEndpoint)授权请求令牌时使用,用于检查参数是否有效。令牌授权请求未签名,因此不能使用“验证”方法。必须实施以下方法:

  • verify_realms

  • verify_request_token

为了防止计时攻击,即使客户端密钥或资源所有者密钥无效,也不能过早退出。相反,应该在剩余的验证过程中使用伪值。非常重要的是,伪客户端和令牌是方法GET_CLIENT_SECRET、GET_RSA_KEY和GET_(ACCESS/REQUEST)_TOKEN_SECRET的有效输入参数,并且当给出一个伪值时,这些方法的运行时间保持等于当给出一个有效的客户端/资源所有者时的运行时间。必须实现以下属性:

  • @dummy_client

  • @dummy_request_token

  • @dummy_access_token

已经提供了示例实现,请注意,所使用的数据库是简单的词典,并且仅用于说明性目的。使用任何适合您的项目的数据库,以及如何访问它完全由您决定。这些方法是按顺序介绍的,这样可以更直接地理解它们的用法,因此,按时间顺序阅读下面的内容可能是值得的。

check_access_token(request_token)[源代码]

检查令牌是否仅包含安全字符,并且不短于LOWER且不长于UPPER。

check_client_key(client_key)[源代码]

检查客户端密钥是否只包含安全字符,并且不短于LOWER且不长于UPPER。

check_nonce(nonce)[源代码]

检查现时值是否仅包含安全字符,并且不小于Low且不长于UPPER。

check_realms(realms)[源代码]

检查该领域是否为一组允许的领域之一。

check_request_token(request_token)[源代码]

检查请求令牌是否仅包含安全字符,并且不短于Low且不长于UPPER。

check_verifier(verifier)[源代码]

检查验证器是否仅包含安全字符,并且不小于Low且不长于UPPER。

property dummy_access_token

提供无效令牌时使用的虚拟访问令牌。

返回:

虚拟访问令牌字符串。

虚拟访问令牌应与访问令牌秘密相关联,以便GET_ACCESS_TOKEN_SECRET(..,Dummy_Access_Token)返回有效秘密。

此方法由以下人员使用

  • ResourceEndpoint

property dummy_client

提供无效客户端密钥时使用的伪客户端。

返回:

伪客户端密钥字符串。

根据支持的签名方法,伪客户端应该与客户端秘密、RSA密钥或两者相关联。供应商应确保

GET_CLIENT_SECRET(DUMY_CLIENT)GET_RSA_KEY(DUMMY_CLIENT)

返回虚拟客户端的有效密钥或密钥。

此方法由以下人员使用

  • AccessTokenEndpoint

  • RequestTokenEndpoint

  • ResourceEndpoint

  • SignatureOnlyEndpoint

property dummy_request_token

提供无效令牌时使用的伪请求令牌。

返回:

伪请求令牌字符串。

伪请求令牌应与请求令牌秘密相关联,以便GET_REQUEST_TOKEN_SECRET(..,DUMMY_REQUEST_TOKEN)返回有效秘密。

此方法由以下人员使用

  • AccessTokenEndpoint

get_access_token_secret(client_key, token, request)[源代码]

检索与访问令牌关联的共享密钥。

参数:
  • client_key -- 客户端/消费者密钥。

  • token -- 访问令牌字符串。

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

返回:

字符串形式的令牌密码。

此方法必须允许使用伪值,并且运行时间必须大致等于有效值的运行时间:

# Unlikely to be near constant time as it uses two database
# lookups for a valid client, and only one for an invalid.
from your_datastore import AccessTokenSecret
if AccessTokenSecret.has(client_key):
    return AccessTokenSecret.get((client_key, request_token))
else:
    return 'dummy'

# Aim to mimic number of latency inducing operations no matter
# whether the client is valid or not.
from your_datastore import AccessTokenSecret
return ClientSecret.get((client_key, request_token), 'dummy')

请注意,返回的密钥必须为明文。

此方法由以下人员使用

  • ResourceEndpoint

get_client_secret(client_key, request)[源代码]

检索与客户端密钥关联的客户端机密。

参数:
  • client_key -- 客户端/消费者密钥。

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

返回:

字符串形式的客户端密码。

此方法必须允许使用虚拟的CLIENT_KEY值。使用虚拟密钥获取密钥的时间必须与获取有效客户端的密钥的时间相同:

# Unlikely to be near constant time as it uses two database
# lookups for a valid client, and only one for an invalid.
from your_datastore import ClientSecret
if ClientSecret.has(client_key):
    return ClientSecret.get(client_key)
else:
    return 'dummy'

# Aim to mimic number of latency inducing operations no matter
# whether the client is valid or not.
from your_datastore import ClientSecret
return ClientSecret.get(client_key, 'dummy')

请注意,返回的密钥必须为明文。

此方法由以下人员使用

  • AccessTokenEndpoint

  • RequestTokenEndpoint

  • ResourceEndpoint

  • SignatureOnlyEndpoint

get_default_realms(client_key, request)[源代码]

获取客户端的默认域。

参数:
  • client_key -- 客户端/消费者密钥。

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

返回:

与客户端关联的默认域的列表。

默认领域列表将在客户端注册期间设置,不在OAuthLib的范围内。

此方法由以下人员使用

  • RequestTokenEndpoint

get_realms(token, request)[源代码]

获取与请求令牌关联的领域。

参数:
  • token -- 请求令牌字符串。

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

返回:

与请求令牌关联的领域列表。

此方法由以下人员使用

  • AuthorizationEndpoint

  • AccessTokenEndpoint

get_redirect_uri(token, request)[源代码]

获取与请求令牌关联的重定向URI。

参数:
  • token -- 请求令牌字符串。

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

返回:

与请求令牌关联的重定向URI。

如果重定向设置为“OOB”,则可能需要返回自定义URI。在这种情况下,用户将被重定向到返回的URI,并且在该端点处可以显示验证器。

此方法由以下人员使用

  • AuthorizationEndpoint

get_request_token_secret(client_key, token, request)[源代码]

检索与请求令牌关联的共享密钥。

参数:
  • client_key -- 客户端/消费者密钥。

  • token -- 请求令牌字符串。

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

返回:

字符串形式的令牌密码。

此方法必须允许使用伪值,并且运行时间必须大致等于有效值的运行时间:

# Unlikely to be near constant time as it uses two database
# lookups for a valid client, and only one for an invalid.
from your_datastore import RequestTokenSecret
if RequestTokenSecret.has(client_key):
    return RequestTokenSecret.get((client_key, request_token))
else:
    return 'dummy'

# Aim to mimic number of latency inducing operations no matter
# whether the client is valid or not.
from your_datastore import RequestTokenSecret
return ClientSecret.get((client_key, request_token), 'dummy')

请注意,返回的密钥必须为明文。

此方法由以下人员使用

  • AccessTokenEndpoint

get_rsa_key(client_key, request)[源代码]

检索以前存储的客户端提供的RSA密钥。

参数:
  • client_key -- 客户端/消费者密钥。

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

返回:

字符串形式的RSA公钥。

此方法必须允许使用虚拟的CLIENT_KEY值。使用虚拟密钥获取RSA密钥必须花费与获取有效客户端的密钥相同的时间量。伪密钥还必须与客户端密钥具有相同的位长度。

请注意,密钥必须以明文形式返回。

此方法由以下人员使用

  • AccessTokenEndpoint

  • RequestTokenEndpoint

  • ResourceEndpoint

  • SignatureOnlyEndpoint

invalidate_request_token(client_key, request_token, request)[源代码]

使使用的请求令牌无效。

参数:
  • client_key -- 客户端/消费者密钥。

  • request_token -- 请求令牌字符串。

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

返回:

人均 Section 2.3 规格的:

“服务器必须(...)确保临时凭据未过期或以前未被使用。”

此方法应确保提供的令牌不再有效。它可以简单地从存储中删除RequestToken或设置使其无效的特定标志(请注意,在请求令牌验证过程中也应该对此类标志进行验证)。

此方法由以下人员使用

  • AccessTokenEndpoint

save_access_token(token, request)[源代码]

保存OAuth1访问令牌。

参数:
  • token -- 带有令牌凭证的词典。

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

令牌词典将至少包括

  • oauth_token 访问令牌字符串。

  • oauth_token_secret 签名中使用的令牌特定密码。

  • oauth_authorized_realms 以空格分隔的领域列表。

客户端密钥可以从以下位置获取 request.client_key

领域列表(未连接的字符串)可从 request.realm

此方法由以下人员使用

  • AccessTokenEndpoint

save_request_token(token, request)[源代码]

保存OAuth1请求令牌。

参数:
  • token -- 带有令牌凭证的词典。

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

令牌词典将至少包括

  • oauth_token 请求令牌字符串。

  • oauth_token_secret 签名中使用的令牌特定密码。

  • oauth_callback_confirmed 这根弦 true

客户端密钥可以从以下位置获取 request.client_key

此方法由以下人员使用

  • RequestTokenEndpoint

save_verifier(token, verifier, request)[源代码]

将授权验证器与请求令牌关联。

参数:
  • token -- 请求令牌字符串。

  • verifier -- 包含OAUTH_VERIMER和OAUTH_TOKEN的词典

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

我们需要将验证器与令牌相关联,以便在访问令牌请求期间进行验证。

请注意,与save_x_内标识不同,此处是 oauth_token 先前保存的请求令牌中的令牌字符串。

此方法由以下人员使用

  • AuthorizationEndpoint

validate_access_token(client_key, token, request)[源代码]

验证提供的访问令牌是否已注册且有效。

参数:
  • client_key -- 客户端/消费者密钥。

  • token -- 访问令牌字符串。

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

返回:

真假

请注意,如果提供了虚拟访问令牌,则其验证时间应该与有效访问令牌相同或几乎相同。

确保即使对于虚拟客户端也能模拟导致延迟的任务。例如,使用::

from your_datastore import AccessToken
try:
    return AccessToken.exists(client_key, access_token)
except DoesNotExist:
    return False

而不是:

from your_datastore import AccessToken
if access_token == self.dummy_access_token:
    return False
else:
    return AccessToken.exists(client_key, access_token)

此方法由以下人员使用

  • ResourceEndpoint

validate_client_key(client_key, request)[源代码]

验证提供的客户端密钥是否为已注册且有效的客户端。

参数:
  • client_key -- 客户端/消费者密钥。

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

返回:

真假

请注意,如果提供了虚拟客户端,则它应该与有效客户端的验证时间相同或几乎相同。

确保即使对于虚拟客户端也能模拟导致延迟的任务。例如,使用::

from your_datastore import Client
try:
    return Client.exists(client_key, access_token)
except DoesNotExist:
    return False

而不是:

from your_datastore import Client
if access_token == self.dummy_access_token:
    return False
else:
    return Client.exists(client_key, access_token)

此方法由以下人员使用

  • AccessTokenEndpoint

  • RequestTokenEndpoint

  • ResourceEndpoint

  • SignatureOnlyEndpoint

validate_realms(client_key, token, request, uri=None, realms=None)[源代码]

验证对请求域的访问权限。

参数:
  • client_key -- 客户端/消费者密钥。

  • token -- 请求令牌字符串。

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

  • uri -- 领域正在保护的URI。

  • realms -- 必须已授予访问令牌的领域的列表。

返回:

真假

提供者如何选择使用Realm参数超出了OAuth规范,但它通常用于限制对受保护资源的子集的访问,例如“照片”。

Realms是一个方便的参数,可用于提供每个视图方法预定义的允许领域列表。

可以简单到::

from your_datastore import RequestToken
request_token = RequestToken.get(token, None)

if not request_token:
    return False
return set(request_token.realms).issuperset(set(realms))

此方法由以下人员使用

  • ResourceEndpoint

validate_redirect_uri(client_key, redirect_uri, request)[源代码]

验证客户端提供的重定向URI。

参数:
  • client_key -- 客户端/消费者密钥。

  • redirect_uri -- 授权成功后要重定向回的客户端的URI。

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

返回:

真假

强烈建议OAuth提供程序要求其客户端在请求中使用所有重定向URI之前注册它们,并将它们注册为绝对URI。看见 CWE-601 有关开放重定向攻击的详细信息,请参阅。

通过要求注册所有重定向URI,提供者应该可以直接验证提供的REDIRECT_URI是否有效。

另一种选择是 Section 2.1 规格的:

如果客户端无法接收回调,或者已通过其他方式建立回调URI,则参数值必须设置为“OOB”(区分大小写),以指示带外配置。

此方法由以下人员使用

  • RequestTokenEndpoint

validate_request_token(client_key, token, request)[源代码]

验证提供的请求令牌是否已注册且有效。

参数:
  • client_key -- 客户端/消费者密钥。

  • token -- 请求令牌字符串。

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

返回:

真假

请注意,如果提供了DUMMY REQUEST_TOKEN,则它的验证时间应该几乎与有效的相同。

确保即使对于虚拟客户端也能模拟导致延迟的任务。例如,使用::

from your_datastore import RequestToken
try:
    return RequestToken.exists(client_key, access_token)
except DoesNotExist:
    return False

而不是:

from your_datastore import RequestToken
if access_token == self.dummy_access_token:
    return False
else:
    return RequestToken.exists(client_key, access_token)

此方法由以下人员使用

  • AccessTokenEndpoint

validate_requested_realms(client_key, realms, request)[源代码]

验证客户端是否可以请求访问领域。

参数:
  • client_key -- 客户端/消费者密钥。

  • realms -- 客户端请求访问的领域的列表。

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

返回:

真假

此方法在获取请求令牌时被调用,并且应该将一个领域绑定到请求令牌,并且在用户授权之后,应该将这个领域限制转移到访问令牌。

此方法由以下人员使用

  • RequestTokenEndpoint

validate_timestamp_and_nonce(client_key, timestamp, nonce, request, request_token=None, access_token=None)[源代码]

验证该现时值以前从未使用过。

参数:
  • client_key -- 客户端/消费者密钥。

  • timestamp -- 这个 oauth_timestamp 参数。

  • nonce -- 这个 oauth_nonce 参数。

  • request_token -- 请求令牌字符串(如果有)。

  • access_token -- 访问令牌字符串(如果有)。

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

返回:

真假

人均 Section 3.3 规格的。

随机数是由客户端唯一生成的随机字符串,用于允许服务器验证以前从未进行过请求,并有助于防止通过不安全通道进行请求时的重播攻击。在具有相同时间戳、客户端凭据和令牌组合的所有请求中,随机数值必须是唯一的。

将进行的第一批验证检查之一是随机数和时间戳的有效性,它们与客户端密钥和可能的令牌相关联。如果无效,则立即通过返回FALSE使请求失败。如果之前使用过随机数/时间戳对,并且您可能刚刚检测到重放攻击。因此,不允许随机数/时间戳重用是OAuth安全性的重要组成部分。请注意,此验证检查是在检查客户端和令牌的有效性之前完成的。::

nonces_and_timestamps_database = [
   (u'foo', 1234567890, u'rannoMstrInghere', u'bar')
]

def validate_timestamp_and_nonce(self, client_key, timestamp, nonce,
   request_token=None, access_token=None):

   return ((client_key, timestamp, nonce, request_token or access_token)
            not in self.nonces_and_timestamps_database)

此方法由以下人员使用

  • AccessTokenEndpoint

  • RequestTokenEndpoint

  • ResourceEndpoint

  • SignatureOnlyEndpoint

validate_verifier(client_key, token, verifier, request)[源代码]

验证验证码。

参数:
  • client_key -- 客户端/消费者密钥。

  • token -- 请求令牌字符串。

  • verifier -- 授权验证器字符串。

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

返回:

真假

OAuth提供商在资源所有者授权访问后向客户端发布验证码。客户端使用此代码来获取令牌凭据,提供程序必须验证验证器是否有效以及是否与客户端和资源所有者关联。

验证器验证应该在接近恒定的时间内完成(以避免验证器枚举)。为了实现这一点,我们需要一个恒定的时间字符串比较,这是由OAuthLib在 oauthlib.common.safe_string_equals **

from your_datastore import Verifier
correct_verifier = Verifier.get(client_key, request_token)
from oauthlib.common import safe_string_equals
return safe_string_equals(verifier, correct_verifier)

此方法由以下人员使用

  • AccessTokenEndpoint

verify_realms(token, realms, request)[源代码]

验证授权域以查看它们是否与提供给令牌的域匹配。

参数:
  • token -- 访问令牌字符串。

  • realms -- 客户端尝试访问的领域的列表。

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

返回:

真假

这可以防止在授权步骤期间由客户端发送的授权领域列表被更改,以包括与请求令牌绑定的领域之外的领域。

可以简单到::

valid_realms = self.get_realms(token)
return all((r in valid_realms for r in realms))

此方法由以下人员使用

  • AuthorizationEndpoint

verify_request_token(token, request)[源代码]

验证给定的OAuth1请求令牌是否有效。

参数:
  • token -- 请求令牌字符串。

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

返回:

真假

此方法仅在AuthorizationEndpoint中使用,用于检查授权URL中给定的OAuth_Token是否有效。此请求未签名,因此类似 validate_request_token 方法不能使用。

此方法由以下人员使用

  • AuthorizationEndpoint