跳转到主要内容

一个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中,它使用此包的源代码,该源代码执行重定向并与浏览器通信。

运行上述示例后的流程是

  1. 客户端代码在内核启动时加载,加载外部客户端依赖项(见下文)
  2. 单元格运行,将当前路径存储在cookie中,并触发javascript重定向到身份提供者
  3. 身份提供者在认证成功后重定向到/redirect.html
  4. 回调客户端代码存储令牌并将用户重定向到cookie中的路径

此包不提供js依赖项;客户端需要访问

这可能在将来改变。

内核-浏览器信任

此包假设内核不如浏览器可信。这是因为,在设计上,在笔记本环境中,很容易

  • 在笔记本的输出单元格上打印一个变量
  • 与他人共享笔记本

这些因素可能会导致无意中共享令牌的风险,特别是刷新令牌。为了降低这种风险,浏览器仅与内核共享访问令牌,这些令牌对于与API通信是严格必要的。

此模式的另一个优点是,对内核服务器的攻击需要付出更多的努力才能授予访问API的权限:用户需要将其访问令牌打印到笔记本上,攻击者需要在令牌过期日期(1小时内)内访问该笔记本(具有特权的访问)。这与元数据服务形成对比,元数据服务对主机上运行的任何进程都是可用的(参见AWSAzure)。

浏览器信任

此库使用的模式具有单页应用程序相同的风险,包括从浏览器中窃取秘密。这意味着需要对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 (6.8 kB 查看哈希值

上传时间 源代码

构建分发

ipython_oidc_client-0.1.3-py2.py3-none-any.whl (7.7 kB 查看哈希值

上传时间 Python 2 Python 3

支持