【问题标题】:Failed to use auth code flow with python MSAL无法通过 python MSAL 使用身份验证代码流
【发布时间】:2021-04-06 21:07:18
【问题描述】:

使用 MSAL 文档中给出的基本示例,我根本无法从 MSAL 包中获取 acquire_token_by_auth_code_flow() 在烧瓶应用程序之外工作。

我认为问题来自使用错误的身份验证响应,根据文档,该响应必须是“从身份验证服务器收到的查询字符串的字典”。在烧瓶应用程序中,我可以简单地使用request.args,我不太确定如何在烧瓶之外使用。

我已经尝试过使用requests.requesturlsplit。设备流程工作正常,并且使用 Java 中的 MSAL 包并通过 R 连接。所以应用程序似乎设置正确。

下面 MSAL 应用程序的基本示例代码会产生错误:

状态不匹配:XXXXXXXXXXXX 与无

(所以auth_response 是错误的)。
有什么想法吗?

import requests
import msal

CLIENT_ID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Application (client) ID of app registration
CLIENT_SECRET = "XX-XXXXXXXX-XXXXXXXX.XX~XXXXX~XXXX" # Placeholder - for use ONLY during testing.
AUTHORITY = "https://login.microsoftonline.com/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX"
REDIRECT_PATH = "/getAToken"  # Used for forming an absolute URL to your redirect URI.
                              # The absolute URL must match the redirect URI you set
                              # in the app's registration in the Azure portal.
ENDPOINT = 'https://graph.microsoft.com/v1.0/me'  
SCOPE = ["https://graph.microsoft.com/.default"]

# Cache
cache = msal.SerializableTokenCache()

# Build msal app
app = msal.ConfidentialClientApplication(
        CLIENT_ID, authority=AUTHORITY,
        client_credential=CLIENT_SECRET, token_cache=cache)

# Initiate auth code flow
session = requests.Session()
session.flow = app.initiate_auth_code_flow(scopes=SCOPE, redirect_uri=REDIRECT_PATH)

# Aquire token
result = app.acquire_token_by_auth_code_flow(auth_code_flow=session.flow, auth_response = dict(parse.parse_qsl(parse.urlsplit(REDIRECT_PATH).query)))

flask 应用程序中最后一位的等效代码如下所示:REDIRECT_PATH = "/getAToken"

@app.route(app_config.REDIRECT_PATH)  # Its absolute URL must match your app's redirect_uri set in AAD
def authorized():
    result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
        session.get("flow", {}), request.args)
    return redirect(url_for("index"))

【问题讨论】:

    标签: python flask oauth-2.0 azure-active-directory msal


    【解决方案1】:

    auth_response 必须是根据当前 HTTP 请求查询参数构建的字典。

    如果这是一个桌面应用程序,您必须切换到 PublicClientApplication。您可以找到示例here

    【讨论】:

    • 我不确定我是否理解您的第一条评论。当前的 HTTP 请求查询是什么?这是一个网络应用程序。此外,使用机密而不是公共客户端应用程序不应该有所作为,因为身份验证代码流是这两者之间的共享方法。所以错误仍然是切换到 public :(
    • @ZhuoHan 如果它的网络应用很棒的话。我没有做太多 python 但你需要传递请求查询参数。在您的代码案例中,我猜它可能类似于 requests.request.query 或 requests.request.queryparams。由于不需要手动代码/令牌交换,身份验证代码流实现与本机应用程序相似但不同。如果它不是 Web 应用程序,建议使用它。对请求和响应进行提琴手跟踪,以查看作为状态发送和返回的值。
    • 我尝试使用 PublicClientApplication 运行您提供的示例(也在 Azure 中设置开关以允许公共客户端流)。不幸的是,我发现另一个错误对于 PublicClientApp 非常奇怪(不应该需要客户端密码?):invalid_client AADSTS7000218:请求正文必须包含以下参数:'client_assertion' 或 'client_secret'。
    • @ZhuoHan 让我们回到正确的机密客户端。你能在github上分享你的代码吗?
    【解决方案2】:

    根据文档,获取令牌需要很少的请求。为此,您需要在导航到 Microsoft 登录页面之前创建流程并将其存储在会话中。

    session["flow"] = _build_auth_code_flow(authority=app_config.AUTHORITY, scopes=app_config.SCOPE)
    

    导航回您的应用程序后,您应该像在示例中那样使用此流对象

    result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
            session.get("flow", {}), request.args)
    

    确保您没有创建两次。在这种情况下,错误将类似,但状态不匹配:XXXXXXXXXXXX vs XXXXXXXXXXXX。如果你路由调用了两次,可能会发生这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-03
      • 2021-07-08
      • 2023-02-17
      • 1970-01-01
      • 2022-10-04
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      相关资源
      最近更新 更多