我在Python 3.9中使用FastAPI。我还不能获得可用的oAuth2依赖项来与我们特定的Azure令牌身份验证一起工作,我最初尝试使用fastapi-azure-auth
时似乎也不匹配。
因此,我目前正在对fastapi.security.base.SecurityBase
进行子类化,以尝试创建自己的身份验证依赖项,我将fastapi.security.oauth2.OAuth2
和fastapi.security.oauth2.OAuth2PasswordBearer
中的方法用作指南。
这些模型依赖于fastapi.openapi.models.OAuth2
和fastapi.openapi.models.OAuthFlow
,这又回到了Pydantic的BaseModel
,其中除了初始化提供的字段之外,大概没有发生什么事情。
我能找到的关于将OAuth2与FastAPI一起使用的唯一信息似乎是对伟大的FastAPI安全性小教程的重复剪切和粘贴,该教程只为一个简单的虚拟示例提供指导。
在这个阶段,我真的很想知道一个问题的答案,这对我来说是一个谜。
1.我有一个"范围",我相信这可能是必不可少的提供安全计划的工作。
fastapi.security.oauth2.OAuth2
模型需要为其model
属性提供fastapi.openapi.models.OAuth2
模型。fastapi.openapi.models.OAuth2
模型需要为其flows
属性提供一个fastapi.openapi.models.OAuthFlows
模型。OAuthFlows
型号包含OAuthFlow<Type>
型号之一,OAuthFlow<Type>
型号是fastapi.openapi.models.OAuthFlow
的子类。OAuthFlow
基类是存储"作用域"的地方:scopes: Dict[str, str] = {}
在回到OAuthFlow
的路上,我似乎找不到一句关于OAuth2PasswordBearer
的行为和用法的话,甚至代码也完全没有任何关于这些类的内联文档。
- 但是从FastAPI教程和OpenAPI文档中可以清楚地看到,"作用域"是一个字符串;多个作用域有时候可以表示为一个字符串,用空格作为分隔符。我不能不得出这样的结论(我可以提供的作用域数据也证实了这一点),即"作用域"是标量:单个值。*
https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/表示:
- OAuth2规范将"作用域"定义为用空格分隔的字符串列表。
- 每个字符串的内容可以具有任何格式,但不应包含空格。
- 每个"作用域"只是一个字符串(没有空格)。
所以我的问题是:* * 我们应该如何向OAuthFlow.scopes
dict提供标量值?**
我的作用域(标量)看起来像这样:
api://a12b34cd-5e67-89f0-a12b-c3de456f78ab/.default
它应该作为键或值提供,还是两者都提供,否则另一个键/值可以留空(""
)、None
,或者应该放入什么(为什么?)?
此外,既然fastapi.security.oauth2.SecurityScopes
类 * 确实 * 将 * 标量 * 作用域存储为空格分隔的字符串,为什么有两种方法来存储作用域?它们如何交互(如果有的话)?
1条答案
按热度按时间9cbw7uwe1#
在提出这个问题之后,我在FastAPI高级用户指南中找到了我遗漏的几行代码,它们可以参考oAuth2教程,并添加一些使用作用域的示例代码:
示例代码中有一行定义了两个作用域:
scopes={"me": "Read information about the current user.", "items": "Read items."},
实际的 scope 似乎放在
scopes
字典的 key 中,而 value 似乎是任意的描述性文本,可能在某个适当的地方被推出(错误消息、异常,或者至少在OpenAPI文档中)。scopes参数接收一个dict,其中每个范围作为键,描述作为值
因此,对于我的特定问题,似乎可以肯定我可以提供如下范围:
scopes = {"api://a12b34cd-5e67-89f0-a12b-c3de456f78ab/.default": "access"}
对于
SecurityScopes
中的标量作用域;当作用域由用户处理、嵌入到令牌中或根据所需的作用域检查传入的作用域时,不提供描述性文本,并且需要迭代地检查作用域,因此作用域列表如最初预期的那样是适当和有用的。我还没有找到SecurityScopes
与OAuthFlow
中的作用域dict交互的任何地方。这是一个比我想象中简单得多的问题,但我认为这是一个示例,它演示了为什么内联文档 * 不是 * 反模式,正如我听说一些狂热分子现在所拥护的那样。
为了使代码独立,避免在指南中进行精细的跟踪,添加注解会有所帮助:
或者,现在,甚至:
:—)