azure - Azure - 获取用户刷新令牌失败
问题描述
我整天坐在上面,也许我需要刷新我的眼睛,但我无法使用Azure OAuth2指南获取用户刷新令牌。
我将解释我的场景:
- 我有使用 react 的客户端页面,我调用
/authorize
API 来获取code
以下范围:"email", "openid", "offline_access", "profile"
. 同意窗口正在打开,我同意这些条款。
(我可能不需要所有这些,但在我的会话期间我遇到了错误并决定去大规模权限只是为了让它工作) code
正在发送到我的服务器,在那里我调用API/token
时使用我在客户端中声明的相同范围/authorize
和相同的重定向 URI。
基本 URLhttps://login.microsoftonline.com/common
用于上述调用
现在我收到 BAD_REQUEST 的原因如下:
{
"error": "invalid_grant",
"error_description": "AADSTS65001: The user or administrator has not consented to use the application
with ID <CLIENT_ID> named <APP_NAME>. Send an interactive authorization request for this user and resource.\r\nTrace ID: <ID1>\r\nCorrelation ID: <ID2>\r\nTimestamp: 2020-10-02 19:48:18Z",
"error_codes": [
65001
],
"timestamp": "2020-10-02 19:48:18Z",
"trace_id": <ID1>,
"correlation_id": <ID2>,
"suberror": "consent_required"
}
在应用注册时,我授予了应用在上述范围内的权限,并且所有这些都来自同一组 API:
当我转到我的 Microsoft 帐户查看应用程序时,我可以看到下面的权限,这似乎至少我错过了电子邮件:
我阅读了有关此事的几篇文章,重要的是要说我正在尝试从不同的 Microsoft 帐户登录,我去了该帐户的管理页面并设置启用的用户同意上述权限,但仍然没有用。
每个请求添加流的代码片段:
我有一个 React 应用程序 - 使用库
react-ms-login
,它使用https://login.microsoftonline.com/common/oauth2/v2.0/authorize
API 来获取授权代码,它会打开同意窗口,一旦关闭它就会将其发送到我的服务器。
该组件如下所示:<ReactLoginMS clientId={MICROSOFT_CLIENT_ID} redirectUri="https://localhost:3000/msComplete" scopes={["email", "openid", "offline_access", "profile"]} responseType="code" handleLogin={(data) => login(data)} />
Flask Application 获取授权码并执行以下操作:
def get_refresh_token(code): headers = { 'Content-Type': 'application/x-www-form-urlencoded' } data = { 'client_id': MICROSOFT_CLIENT_ID, 'scope': ["email", "openid", "offline_access", "profile"], 'code': code, 'redirect_uri': 'https://localhost:3000/msComplete', 'grant_type': 'authorization_code', 'client_secret': MICROSOFT_CLIENT_SECRET } response = requests.post('https://login.microsoftonline.com/common/oauth2/v2.0/token', headers=headers, data=data) response.raise_for_status() # getting 400 with the mentioned error return response.json()
我有什么遗漏/做错了吗?
希望得到任何帮助,因为这是我第四次删除应用程序注册并重新开始:) 谢谢
解决方案
尽管错误消息不是很清楚,但您的问题是如何构建令牌请求正文。
如果您将数组作为 POST 请求数据中的值之一传递:
data = { 'foo': ['a', 'b', 'c'] }
requests.post('https://example.com', data=data)
requests库将按如下方式对其进行编码:
foo=a&foo=b&foo=c
因此,在您的代码中,您包含一个字符串数组作为scope
令牌请求的值:
'scope': ["email", "openid", "offline_access", "profile"],
您导致生成的请求scope
在正文中有多个单独的参数:
...&scope=email&scope=openid&scope=offline_access&scope=profile&...
相反,您需要的是单个scope
参数,每个范围值用空格分隔:
'scope': 'openid email offline_access profile',
这将被编码为:
...&scope=openid%20email%20offline_access%20profile&...
这是构建令牌请求正文的更正代码:
data = {
'client_id': MICROSOFT_CLIENT_ID,
'scope': "email openid offline_access profile",
'code': code,
'redirect_uri': 'https://localhost:3000/msComplete',
'grant_type': 'authorization_code',
'client_secret': MICROSOFT_CLIENT_SECRET
}
推荐阅读
- c# - 插入检查电子邮件是否存在之前的 MySQL 触发器
- python - 如何在熊猫中使用 groupby 计算过去 14 天的平均值
- python - k-means 质心标签在同一程序的运行中发生变化?
- python-3.x - 如何从图表中删除框架-pyplot -matplotlib
- mediawiki - 防止用户对其个人脚本进行不必要的更改
- spring - 客户在 EUREKA 中使用 AWS 私有 IP 注册
- flutter - 如何从 Flutter 中的另一个文件访问用户定义的函数
- javascript - 如何根据 Redux 状态动态更改 React Navigation 标签栏的标签和图标
- git - (master) 写在命令行后面的目录
- oracle - PL/SQL 如何假脱机多个文件?