Skip to main content

oauthlib 的低级 Pyramid 实现

项目描述

pyramid_oauthlib_lowlevel

Python 包

这是一个包,旨在通过允许更多自定义的低级接口使用 Pyramid 创建 oAuth 服务器。

在使用这个包之前,我建议你考虑一下这个包pyramid-oauthlib,它可能更适合你的需求,因为它提供了一个高级接口。

严重地。这个包提供了一个非常低级的接口来自定义oauthlibPyramid 中的包。大多数人会希望使用具有更简化包的更高级别的抽象。

高级与低级是什么意思?

highlevel:pyramid-oauthlib为您做出许多艰难的决定,并为您提供了一些钩子,可以轻松地将 oAuth 流程实现到您的 Pyramid 应用程序中。您无需了解太多关于 oAuth 的知识即可使用它。

低级:pyramid-oauthlib-lowlevel为在 Pyramid 应用程序中利用 oauthlib 库提供了一个非常基本的集成方案。您通常需要了解一些关于 oAuth 的报价才能处理此问题。

此包的一些用例是以下情况:

  1. 您需要支持 oAuth1。(pyramid-oauthlib仅支持 oAuth2)
  2. 您需要对 oAuth2 集成进行更细粒度的控制或托管多个 oAuth2 服务器。pyramid-oauthlib期望你以某种方式做事(这是很常见的现状)。
  3. 您需要支持/创建损坏的 oAuth 服务器。*
  • oAuth 服务器损坏?是的。即使是主要的互联网服务也经常以不完全符合规范或违反规范的方式实施 oAuth。离线集成测试套件可能需要创建可以模仿这种行为的服务器。

该包通常通过定义一个或多个子类来处理获取/设置数据对象,然后通过明确设计的 oAuth 提供程序在 Pyramid 请求上调用它们来工作。

这种方法将允许您创建多个 oAuth 服务器和/或在同一 Pyramid 服务器上运行的身份验证方法

使用这种方法进行开发的理由是需要:

  1. 在白标服务上支持多个 oAuth 版本和端点
  2. 从 Pyramid 请求中限制和隔离 oAuth 数据。

这个项目很大程度上是flask-oauthlib在核心oauthlib包之后建模的。此包中的文档字符串取自两者。此包中的重要部分代码是flask-oauthlibto的端口Pyramid;许多部分也直接适应位oauthlib

该软件包的一般设计方式

oauth1和命名空间都oauth2提供了一个providervalidator命名空间。

和类为从数据库oauth1.validator.OAuth1RequestValidator_Hooks和缓存中获取/设置数据oauth2.validator.OAuth2RequestValidator_Hooks提供了挂钩。RequestValidator在每个部署中,这些都必须被子类化。

oauth1.validator.OAuth1RequestValidatoroauth2.validator.OAuth2RequestValidator类提供用于处理 oAuth 请求的逻辑,适用于 Pyramid 。只有在极少数情况下,这些才应该被细分。

oauth1.provider.OAuth1Provideroauth2.provider.OAuth2Provider提供调用金字塔下端点作为逻辑工作单元的RequestValidator方法,它们是端点或资源验证器。只有在极少数情况下,这些才应该被细分。

  • oauth1.provider.OAuth1Provider

  • .endpoint__request_token

  • .endpoint__access_token

  • .extract__endpoint_authorize_data

  • .endpoint__authorize__authorize

  • .logic__is_authorized

  • oauth2.provider.OAuth2Provider

  • .endpoint__validate_authorization_request

  • .endpoint__confirm_authorization_request

  • .endopoint__token

  • .endpoint__revoke_token

  • .verify_request

通常使用将涉及以下步骤:

  • 子类hooks化应用程序中的对象
  • provider在请求中,首先使用自定义钩子创建一个新实例
  • 在请求上,然后调用所需的端点或请求验证。

测试是功能齐全的示例!

测试包含完整的示例应用程序/服务器和遍历不同 oAuth 策略的逻辑流。例如,oAuth2 测试包括(oAuth1 测试相同):

  • tests.oauth2_app定义了一个可以启动的功能齐全的 oAuth2 服务器
  • tests.oauth2.PyramidTestApp启动一个tests.oauth2_app实例,并使用它来发出请求
  • tests.oauth2.PyramidTestApp.test_valid_flow__get_access_token测试从 oAuth2 服务器获取“bearer_token”的流程
  • tests.oauth2_model定义单元测试和测试应用程序使用的持久性模型 (SqlAlchemy)
  • tests.oauth2_utils定义用于单元测试和测试应用程序的子类和实用程序

支持的流

理想情况下,将支持所有 oAuth 流程。非常欢迎 PR!

目前支持的流程有:

  • oAuth1 - 应用程序授权 - 新帐户注册(请参阅tests.oauth1.PyramidTestApp.test_valid_flow__registration
  • oAuth2 - 应用程序授权 - 新帐户注册(请参阅tests.oauth2.PyramidTestApp.test_valid_flow__registration
  • oAuth2 - 获取承载令牌(请参阅tests.oauth2.PyramidTestApp.test_valid_flow__get_access_token
  • oAuth2 - 刷新令牌(请参阅tests.oauth2.PyramidTestApp.test_valid_flow__registration
  • oAuth2 - 撤销令牌(请参阅tests.oauth2.PyramidTestApp.test_valid_flow__get_access_token

去做:

  • oAuth1 - 应用授权 - 绑定现有账户
  • oAuth2 - 应用授权 - 绑定现有账户

笔记:

  • New Account RegistrationApplication表示为现有用户建立了一个新帐户Authority
  • Bind Existing Account是指Application将其帐户连接到其现有帐户的现有用户Authority

上述这些元素都使用相同的 oAuth 流程和端点,只是它们的集成略有不同

教程

这是设计 oAuth 服务器的快速方法:

  1. 子类 OAuth1RequestValidator

    这是可选的

    class CustomValidator(OAuth1RequestValidator): """某些验证器方法确实需要覆盖。"""

     @property
     def realms(self):
     	return ['platform.actor', ]
    
     @property
     def client_key_length(self):
     	return (40, 64)
    
     ...
    
  2. 子类 OAuth1RequestValidator_Hooks

    该库提供了一个@catch_backend_failure更有意义的包装后端故障

    self.pyramid_request.dbSession 类 CustomValidator_Hooks(OAuth1RequestValidator_Hooks): """ 此自定义对象需要在"""上的 SqlAlchemy 连接

     @catch_backend_failure
     def _get_TokenRequest_by_verifier(self, verifier, request=None):
     	"""
     	:param verifier: The verifier string.
     	:param request: An oauthlib.common.Request object.
     	"""
     	verifierObject = sqla.get_Developer_oAuth1Server_TokenRequest__by_oauthVerifier(
     		self.pyramid_request.dbSession,
     		verifier,
     	)
     	return verifierObject
    
  3. 创建一个 oAuth 对象

    这可能是通过@reify 的请求属性

    def new_oauth1Provider(request): """this is used to build a new auth""" validatorHooks = CustomValidator_Hooks(request) provider = pyramid_oauthlib_lowlevel.oauth1.provider.OAuth1Provider(request, validator_api_hooks = validatorHooks, validator_class = CustomValidator) return provider

  4. 使用 oAuth 对象 - 检查 API 访问

    在您的授权例程中,您可以检查有效的 oauth 请求

    oauth1Provider = new_oauth1Provider(request) _is_authorized, req = oauth1Provider.logic__is_authorized(['platform.actor', ]) if not _is_authorized: raise HTTPUnauthorized(body="""'{"error": "Not Authorized (oAuth Failed)}' """, content_type='应用程序/json')

    req.client也许用and做点什么req.access_token

  5. 使用 oAuth 对象 - 授予访问权限的路由

    查看测试应用程序

一体化

因为这是一个_lowlevel库,所以这个包没有自动集成到 Pyramid 中。

在示例应用程序中,方便的方法用于根据需要创建 oauth 提供程序:

def new_oauth2Provider(pyramid_request):
	validatorHooks = CustomValidator_Hooks(pyramid_request)
	provider = oauth2_provider.OAuth2Provider(pyramid_request,
											  validator_api_hooks = validatorHooks,
											  validator_class = CustomValidator
											  )
	return provider

部署可以将其作为 Pyramid AUTH 的一部分、在 Tweens 或中间件中、作为请求属性或许多其他选项来处理。

oauth2 testapp 有一个值得注意的特殊流程:

ExampleApp.fetch_protected_resource用户必须登录到 ExampleApp 并拥有授权系统的授权令牌。此路由将加载令牌并使用它向权威系统发出 oAuth2 请求。

Authority_Oauth2_API_Public.protected_resource 资源受到 oauth2 令牌验证的保护。

    oauth2Provider = new_oauth2Provider(self.request)
    scopes = ['platform.actor', ]
    valid, req = oauth2Provider.verify_request(scopes)

oAuth 流程

在 oAuth 中可以执行许多不同的流程

该项目目前旨在实施以下流程系列:

  • Flow-AccountRegistration - 用户AuthorityApplication
  • ApplicationFlow-AccountBind -将其帐户链接到的现有用户Authority
  • Flow-Developer - 用户Authority已创建Application并需要访问令牌

Token过期和刷新注意事项

在刷新期间过期访问和刷新令牌有几种策略和问题。

一些部署希望在生成新的 access_token 时使用户的所有访问令牌过期。

这在 中进行oauth2_utils.OAuth2RequestValidator_Hooks.bearer_token_setter了说明,它将用户/客户端的现有实时令牌设置为非活动。

一些部署不希望这样做,例如基于云的系统可能需要一些时间来传播新凭据。

一些部署会希望refresh_token在多个 access_token 刷新之间循环。这是通过覆盖默认方法来支持的OAuth2RequestValidator

class CustomValidator(OAuth2RequestValidator):

	def rotate_refresh_token(self, request):
		"""Determine whether to rotate the refresh token. Default, yes.

		When access tokens are refreshed the old refresh token can be kept
		or replaced with a new one (rotated). Return True to rotate and
		and False for keeping original.

		:param request: oauthlib.common.Request
		:rtype: True or False

		Method is used by:
			- Refresh Token Grant
		"""
		return True

两种形式都包含在测试套件中(默认通过monkeypatching请求验证器覆盖,然后将其重置)

某些部署会希望在令牌过期或被撤销时删除它。该库旨在支持使用数据库标志来标记令牌是否处于活动状态、已撤销、已过期等。这是为簿记中的问题而设计的。

刷新令牌注意事项

OAuthlib 是一个优秀的库,但在刷新令牌时可能需要注意一些小问题。

  1. OAuthlib 不缓存 refresh_token 的对象,它只是验证它或其参数。除非您专门缓存它,否则您可以在每个验证操作的单个请求中多次加载它。许多使用 OAuthlib 的包不考虑这个实现细节——包括这个包。

  2. OAuthlib 不会跨刷新维护令牌的沿袭。如果您的应用程序支持不止一种类型的授权(例如同时支持authorization_codeAND client_credentials),这一点很重要。为了解决这个问题,我们建议执行以下操作:

  • 使用以下字段扩展令牌的存储:
  • grant_type
  • original_grant_type
  • 扩展bearer_token_setter以执行以下操作:
  • request.grant_type当您将其保存到数据库时,将其存储到新的令牌对象上。
  • 如果grant_type不是“refresh_token”,则将该值存储为original_grant_type
  • 如果grant_type是“refresh_token”,则加载“refresh_token”对象(request.refresh_token),并复制original_grant_type

此策略将允许您轻松区分 client_credential(应用程序)和 authentication_code(用户)令牌。

Python 兼容性

pyramid_oauthlib_lowlevel经测试可在Python2.7和Python3.6+下运行

执照

一些函数是从 oauthlib 和 flask-oauthlib 移植过来的;见 LICENSE.txt

某些功能是从 Pyramid 移植的,并出现在其许可证下;见许可证-Pyramid.txt

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

pyramid_oauthlib_lowlevel-0.2.4.tar.gz (67.5 kB 查看哈希

已上传 source