keystone.oauth1.validator 模块

OAuthlib 请求验证器。

class keystone.oauth1.validator.OAuthValidator[源代码]

基类: ProviderAPIMixin, RequestValidator

check_access_token(access_token)[源代码]

检查令牌仅包含安全字符,并且不短于下限且不长于上限。

check_client_key(client_key)[源代码]

检查客户端密钥仅包含安全字符,并且不短于下限且不长于上限。

check_nonce(nonce)[源代码]

检查 nonce 仅包含安全字符,并且不短于下限且不长于上限。

check_request_token(request_token)[源代码]

检查请求令牌仅包含安全字符,并且不短于下限且不长于上限。

check_verifier(verifier)[源代码]

检查验证器仅包含安全字符,并且不短于下限且不长于上限。

property enforce_ssl
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 对象。

返回值:

根据 规范第 2.3 节

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

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

此方法由

  • AccessTokenEndpoint

property safe_characters
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_verifier 和 oauth_token 的字典

  • request – oauthlib.common.Request 对象。

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

请注意,与 save_x_token 不同,这里的 token 是先前保存的请求令牌中的 oauth_token 令牌字符串。

此方法由

  • AuthorizationEndpoint

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

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

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

  • token – 访问令牌字符串。

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

返回值:

True 或 False

请注意,如果提供了虚拟访问令牌,则应在与有效令牌大致相同的时间内进行验证。

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

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 请求。

返回值:

True 或 False

请注意,如果提供了虚拟客户端,则应在与有效客户端大致相同的时间内进行验证。

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

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 – 必须授予访问令牌的领域列表。

返回值:

True 或 False

提供程序选择如何使用 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 请求。

返回值:

True 或 False

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

通过要求注册所有重定向 URI,提供者应该能够轻松验证提供的 redirect_uri 是否有效。

或者,参考规范的 第 2.1 节

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

此方法由

  • RequestTokenEndpoint

validate_request_token(client_key, token, request)[source]

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

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

  • token – 请求令牌字符串。

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

返回值:

True 或 False

请注意,如果提供了虚拟 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)[source]

验证客户端是否有权请求访问领域。

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

  • realms – 客户端正在请求访问的领域列表。

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

返回值:

True 或 False

当获取请求令牌时会调用此方法,应该将领域与请求令牌关联起来,并且在用户授权后,此领域限制应该转移到访问令牌。

此方法由

  • RequestTokenEndpoint

validate_timestamp_and_nonce(client_key, timestamp, nonce, request, request_token=None, access_token=None)[source]

验证 nonce 是否已被使用。

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

  • timestampoauth_timestamp 参数。

  • nonceoauth_nonce 参数。

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

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

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

返回值:

True 或 False

参考规范的 第 3.3 节

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

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

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)[source]

验证验证码。

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

  • token – 请求令牌字符串。

  • verifier – 授权验证码字符串。

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

返回值:

True 或 False

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)[source]

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

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

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

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

返回值:

True 或 False

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

可以像这样简单:

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

此方法由

  • AuthorizationEndpoint

verify_request_token(token, request)[source]

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

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

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

返回值:

True 或 False

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

此方法由

  • AuthorizationEndpoint