使用 Python、Flask、MSAL 和 auth_code_flow 访问个人 OneDrive 文件时出现问题

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

尝试通过 Flask 应用程序访问

"https://graph.microsoft.com/v1.0/me/drive"
端点会产生以下响应:

{
"error": {
"code": "HostNotFound",
"innerError": {
"client-request-id": "{xxx}",
"date": "2024-04-02T15:47:03",
"request-id": "{yyy}"
},
"message": "Target '{zzz}-my.sharepoint.com' is not found."
}
  1. 我可以使用 Graph Explorer
  2. 通过我的个人帐户检索数据
  3. 我在 Azure 中分配了正确的权限。
print(token["scope"])
# openid profile email https://graph.microsoft.com/Application.Read.All https://graph.microsoft.com/Files.Read https://graph.microsoft.com/Files.Read.All https://graph.microsoft.com/Files.ReadWrite.All https://graph.microsoft.com/Sites.Read.All https://graph.microsoft.com/Sites.ReadWrite.All https://graph.microsoft.com/User.Export.All https://graph.microsoft.com/User.Read https://graph.microsoft.com/.default
  1. 我正在使用 auth 代码流,并且可以成功从 Microsoft Graph 的其他端点检索数据,例如
    "https://graph.microsoft.com/v1.0/applications"
    "https://graph.microsoft.com/v1.0/me"
    因此,我认为代币生成不是问题。

由于我仍然试图首先获得工作访问权限,因此令牌当前通过会话传递,装饰器在附加授权标头后执行最终请求。这不是我打算长期使用/实施的。 我很高兴收到任何建议/行业标准,以及如何正确处理和纳入这一点。然而,这个问题的焦点主要是为什么我无法通过 Microsoft Graph API 访问我的个人 OneDrive 文件。

app.py

import json
from functools import wraps

import msal
import requests
from flask import Flask, session, request, redirect, make_response, url_for

app = Flask(__name__)

with open("delegated_config.json") as file:
    config = json.load(file)

app.config.update(config)

client_instance = msal.ConfidentialClientApplication(
    client_id=app.config["application_id"],
    client_credential=app.config["client_secret"],
    authority=app.config["authority_url"]
)


def initiate_auth_flow():
    """Authentication with Access Token"""
    if not session.get("auth_flow"):
        authorization = client_instance.initiate_auth_code_flow(
            app.config["scope"], redirect_uri=app.config["redirect_uri"]
        )
        session["auth_flow"] = authorization

    authorization = session.get("auth_flow")
    # Will redirect to "generate_token()"
    return make_response(redirect(authorization["auth_uri"]))


def get_token(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if not session.get("access_token"):
            session["execute_func"] = func.__name__
            return initiate_auth_flow()
        else:
            url = func(*args, **kwargs)
            return requests.get(
                url, headers={"Authorization": f"Bearer {session['access_token']}"}).json()

    return wrapper


# Redirect route after logging in and confirming permissions
@app.route("/generate_token")
def generate_token():
    query_string = request.args
    token = client_instance.acquire_token_by_auth_code_flow(session["auth_flow"],
                                                            auth_response=query_string)
    session["access_token"] = token["access_token"]
    return redirect(url_for(session["execute_func"]))



# WORKS
@app.route("/me")
@get_token
def me():
    return "https://graph.microsoft.com/v1.0/me"



# WORKS
@app.route("/all_applications")
@get_token
def all_applications():
    return "https://graph.microsoft.com/v1.0/applications"



# DOES NOT WORK, ERROR AT BEGINNING OF QUESTION
@app.route("/all_drives")
@get_token
def all_drives():
    return "https://graph.microsoft.com/v1.0/me/drive"



# DOES NOT WORK
@app.route("/private_drive")
@get_token
def private_drive():
    return "https://api.onedrive.com/v1.0/me/drive"
# {"error": {"code": "invalidRequest", "message": "Invalid API or resource"}}

delegate_config.json

{
  "SECRET_KEY": "{xxx}",
  "application_id": "{yyy}",
  "client_secret": "{zzz}",
  "authority_url": "https://login.microsoftonline.com/{tenant_id}",
  "scope": [ "https://graph.microsoft.com/.default" ],
  "redirect_uri": "http://localhost:6123/generate_token"
}
python flask onedrive azure-ad-msal
1个回答
0
投票

最终我自己弄清楚了。我所要做的就是将我的租户的特定authority_url传递给

ConfidentialClientApplication
,所以即

client_instance = msal.ConfidentialClientApplication(
    client_id=app.config["application_id"],
    client_credential=app.config["client_secret"]
)

...这将导致使用默认的

authority_url
,即
https://login.microsoftonline.com/common

事后想想,也有道理。初始错误代码表明 Microsoft Graph 无法在租户中为我的用户找到 OneDrive/Sharepoint。然而,由于我想访问我的个人 OneDrive 的数据(该数据不包含在我的组织中),因此在使用应用程序对自己进行身份验证后,我只需使用

/common
端点即可访问它。

© www.soinside.com 2019 - 2024. All rights reserved.