离线访问获取刷新令牌:“error_description”:“AADSTS65001:用户或管理员尚未同意使用具有ID的应用程序

问题描述 投票:0回答:1

我正在设计一个 Python 脚本,可以通过 Microsoft Dynamics CRM API 提取和查询信息和数据。

我希望得到一个刷新令牌,这样我就可以在不频繁登录的情况下长时间获得访问令牌。

def login(): 
    authorization_url = (
        f"https://login.microsoftonline.com/{tenant}/oauth2/authorize"
        "?response_type=code"
        f"&client_id={client_id}"
        f"&redirect_uri={redirect_uri}"
        "&response_mode=query&prompt=consent"
        f"&scope={scope}%2f.default openid profile offline_access"
        # f"&scope={scope}"
        # f"&scope={scope}"
        "&state=12345&sso_reload=true"
        f"&code_challenge={code_challenge}"
        "&code_challenge_method=S256"
        f"&nonce={nonce}"
        "&client_info=1"
        )
    
   return render_template("login.html", version=__version__, auth_uri = authorization_url)

登录成功后,url跳转到Azure Ad中已经添加的重定向路径。从请求中获取authorization_code并将其带入发布请求刷新代码。

@app.route(app_config.REDIRECT_PATH)
def auth_response():
    authorization_code = request.args.get('code')
    refresh_token = _get_refresh_token(tenant,
                                       client_id,
                                       client_secret,
                                       authorization_code,
                                       redirect_uri
                                       )

但是,当请求发布刷新令牌时,范围携带offline_access并收到错误请求响应。

scope = 'https://<myid>.api.crm3.dynamics.com/user_impersonation'
data = {
    'client_id': client_id,
    'scope': f'{scope}%2f.default openid profile offline_access',
    'code': authorization_code,
    'redirect_uri': redirect_uri,
    'grant_type': 'authorization_code',
    'client_secret': client_secret,
    'code_verifier': code_verifier,
}
response = requests.post(token_endpoint, data=data)

无法获得offline_access的授权来获取刷新令牌:“error_description”:“AADSTS65001:用户或管理员尚未同意使用具有ID的应用程序。

从响应中收到错误文本:

'{"error":"invalid_grant","error_description":"AADSTS65001: 用户或管理员尚未同意使用 ID 为 '320ae26a-b04b-49c6-aa2e-dfc77e734f01' 且名为 'PowerAppAPI' 的应用程序。发送交互此用户和资源的授权请求。跟踪 ID:ecfc933e-e5ae-4675-927e-bbfc16980700 相关 ID:017df973-0078-4c54-8258-163a0fd3705d 时间戳:2023-12-14 21:18:57Z","error_codes": [65001],“时间戳”:“2023-12-14 21:18:57Z”,“trace_id”:“ecfc933e-e5ae-4675-927e-bbfc16980700”,“correlation_id”:“017df973-0078-4c54-8258- 163a0fd3705d","子错误":"consent_required"}'

我已在 Azure AD 的应用程序管理中添加了动态 CRM 和 Microsoft Graph 的权限并授予了我自己。

事实上,当作用域没有声明offline_access时,就可以获取并使用访问令牌。

我是否错过了 Azure AD 中应用程序管理中的任何设置?如何使用访问令牌获取权限?谢谢您的回答

期望请求能够响应并返回当前 Dynamic CRM 或 Microsoft Graph 范围的刷新令牌。

python-3.x azure azure-active-directory microsoft-graph-api refresh-token
1个回答
0
投票

在授权请求和令牌请求中,您正在使用以下方式构建

scope
参数:

f'{scope}%2f.default openid profile offline_access'

scope
变量为
https://<myid>.api.crm3.dynamics.com/user_impersonation
时,结果是:

https://<myid>.api.crm3.dynamics.com/user_impersonation%2f.default openid profile offline_access

它由

requests.post()
进行表单编码(最终在
%2f
上进行第二次编码),并发送到 Microsoft Entra ID:

scope=https%3a%2f%2forgca5a56ca.api.crm3.dynamics.com%2fuser_impersonation%252f.default+openid+profile+offline_access

在您的 token 请求中,第一个

scope
值被 Microsoft Entra ID 解释为“资源
user_impersonation%2f.default
处的委派权限
https://<myid>.api.crm3.dynamics.com
”。由于未授予名为
user_impersonation%2f.default
的委派权限,因此此操作失败。

授权请求(首先出现)没有失败的原因是您将该请求发送到 Microsoft Entra ID 的 v1.0 端点,这是较旧的(甚至不再记录)端点。在该端点上:

  • scope
    参数中唯一重要的值是
    openid
    ,它仅用于识别应用程序需要ID令牌。任何其他值都将被完全忽略(包括 
    email
    offline_access
    profile
     以及格式错误的 CRM 参数)。
  • 请求的资源 (API) 在
  • resource
     参数中标识。如果未提供该参数,则假定为 Azure AD Graph(
    https://graph.windows.net
    ,已弃用)。
那么,回顾一下这些问题以及如何解决它们:

  1. 问题:您正在使用 v2.0 端点的参数构建授权请求,但实际上是将其发送到 v1.0 端点:

    *

    解决方案:将您的授权请求发送到 v2.0 端点,如文档所述

    https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
    
    
  2. 问题*:在您的令牌请求中,您请求 Dynamics CRM 委派权限 user_impersonation%2f.default

    ,但该权限不存在且未被授予。

    解决方案:请求 Dynamics CRM 委派权限 user_impersonation

    ,该权限确实存在。在您的授权请求和令牌请求中:

    f"&scope={scope} openid profile offline_access"
    
    
© www.soinside.com 2019 - 2024. All rights reserved.