一个Jupyter扩展,用于在笔记本中执行OAuth2流程(例如令牌、代码)。
项目描述
OAuth2在Jupyter笔记本上
一个Jupyter扩展,用于在笔记本中执行OAuth2流程(例如令牌、代码)。
理由
使用笔记本中的API的一个主要挑战是建立客户端(笔记本)与API之间的信任关系。
这个问题通常通过信任内核的主机来解决。这里典型的做法是通过元数据服务实现的托管标识模式,这是所有主要云提供商都提供的。这种模式的缺点是,任何可以访问执行引擎(通过笔记本访问内核)的用户都可以访问主机有权访问的任何API。也就是说,它不允许对API进行歧视性访问,因为它没有将“对笔记本的访问”与“对API的访问”分开。这通常会导致基于主机的访问架构,每个主机对应一组访问策略。这种模式的另一个局限性是,它鼓励供应商锁定,因为它意味着服务需要在供应商的基础设施上运行。
解决这个问题的另一种模式是使用服务主体(OAuth2)通过客户端密钥访问API。遗憾的是,这也面临着与托管标识相同的问题:它会导致任何可以访问执行引擎的人都能无差别地访问API。这种模式还有另一个风险:在笔记本的上下文中,很容易以编程方式获取客户端密钥,这会给攻击者提供对API的无差别访问,无论在零信任网络中的哪个主机。
此包
此包允许用户在笔记本中执行OAuth2流程(例如令牌、代码),因此将笔记本和内核视为具有有限信任的客户端应用程序。这允许内核在没有元数据服务的基础设施上运行,同时保持高标准的安全性。
如何安装
pip install ipython-oidc-client
jupyter nbextension install --py ipython_oidc_client
jupyter nbextension enable --py ipython_oidc_client
jupyter serverextension enable --py ipython_oidc_client
在您的身份提供者(例如Azure、Google、Auth0)中,将响应URL添加到路径/redirect.html
,例如https://example.com/redirect.hml
。
如何使用
打开一个新的笔记本并运行
from ipython_oidc_client import authenticate
access_configuration = {
'authority': 'https://.../.well-known/openid-configuration',
'client_id': '...',
'response_type': '...',
'scope': '...',
}
# valid variables available here: https://github.com/IdentityModel/oidc-client-js/wiki#usermanager
token = {}
authenticate(access_configuration, token) # this changes token (see note in README.md)
在此阶段,您将被重定向到在authority
中声明的身份提供者的认证页面。认证成功(例如通过多因素认证)后,您将被重定向回笔记本。
回到笔记本后,重新运行上面的单元格,token['access_token']
就成为了授权机构返回的访问令牌。重新运行第一个单元格不会触发新的认证;实际上,在同一个jupyterhub上的任何笔记本上运行该单元格都会得到相同的访问令牌。
此时,您可以运行如下操作。
import requests
r = requests.get('https://api....', headers={'Authorization': f'Bearer {token["access_token"]}'})
令牌过期后(通常在1小时后),重新运行上面的单元格以获取新的令牌。
此过程可以重复用于同一笔记本内多个API的访问令牌。
为什么不直接返回令牌呢?
由于Jupyter的一个限制,访问令牌只有在执行整个单元格后才会对内核可用。因此,我们无法从authenticate
中返回令牌,而必须将其分配给全局作用域的变量。这可能在将来改变。
示例
Dockerfile包含了一个在服务器上从PyPI安装包的完整安装,演示了管理员如何全局安装此扩展。使用以下命令运行它:
docker build -t t . && docker run -p 8888:8888 --rm -it t
并将https://:8888/redirect.html
作为响应URL添加到您的身份提供者中的应用程序中。
启动后,将上面的代码片段复制到单元格中并运行。
安全性
此包必须处理两个执行环境
- javascript,在浏览器上
- Python,在内核上
在浏览器上,它使用oidc-client-js执行oauth2流程。在Python中,它使用此包的源代码,该源代码执行重定向并与浏览器通信。
运行上述示例后的流程是
- 客户端代码在内核启动时加载,加载外部客户端依赖项(见下文)
- 单元格运行,将当前路径存储在cookie中,并触发javascript重定向到身份提供者
- 身份提供者在认证成功后重定向到
/redirect.html
- 回调客户端代码存储令牌并将用户重定向到cookie中的路径
此包不提供js依赖项;客户端需要访问
- https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.10.0/oidc-client.min.js
- https://unpkg.com/universal-cookie@3/umd/universalCookie.min.js
这可能在将来改变。
内核-浏览器信任
此包假设内核不如浏览器可信。这是因为,在设计上,在笔记本环境中,很容易
- 在笔记本的输出单元格上打印一个变量
- 与他人共享笔记本
这些因素可能会导致无意中共享令牌的风险,特别是刷新令牌。为了降低这种风险,浏览器仅与内核共享访问令牌,这些令牌对于与API通信是严格必要的。
此模式的另一个优点是,对内核服务器的攻击需要付出更多的努力才能授予访问API的权限:用户需要将其访问令牌打印到笔记本上,攻击者需要在令牌过期日期(1小时内)内访问该笔记本(具有特权的访问)。这与元数据服务形成对比,元数据服务对主机上运行的任何进程都是可用的(参见AWS和Azure)。
浏览器信任
此库使用的模式具有单页应用程序相同的风险,包括从浏览器中窃取秘密。这意味着需要对Jupyter发送给最终用户的任何客户端代码进行审计,以防止从客户端窃取令牌。
如何开发
本软件包包含4个组件
开发此软件包的最简单方法是运行
docker build -f Dockerfile.dev -t t . && docker run -p 8888:8888 -v $(pwd):/project --rm -it t
然后在浏览器中打开https://:8888/?token=(注意,不是 127.0.0.1)。之后,将https://:8888/redirect.html
添加为你的身份提供者的回复URL。
它运行一个基于Python的图像,其中包含Jupyter和安装的软件包,更改js只需要刷新页面。更改Python代码需要重新运行图像。
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定要选择哪个,请了解有关安装软件包的更多信息。
源代码分发
构建分发
ipython_oidc_client-0.1.3.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 757193f4c00ddef5857b30f1d9906731e384e705358f6477f0472a50788f674f |
|
MD5 | 770631b59dc8a72ee3a71f023931af1d |
|
BLAKE2b-256 | 5d21561908d87b06f7fc2bfdc4f7ef539f5ff5bf04e65c562db93182ae92fe59 |
ipython_oidc_client-0.1.3-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a951e53325b567e8d01b03927b6615b8f96bf4a1bc1e46ef35d49c10d57bc97a |
|
MD5 | 7bf67a1d9848c22e8d149f1229c4fe7f |
|
BLAKE2b-256 | 6b4cfb5d38e15770dd230b63574f3a6a1b44566fc850f50b82fa724104876824 |