Ошибка потока общедоступного клиентского приложения Microsoft Azure

Я хочу загрузить несколько файлов с локального компьютера в свой OneDrive. В этом случае я использую библиотеку MSAL (Библиотека аутентификации Microsoft). В файле ms_graph.py есть небольшая проблема. Поток user_code не отвечает правильно. Как я могу решить эту проблему? В обычном случае код должен напечатать user_code для доступа к учетной записи OneDrive.

мс_граф.py:

import webbrowser
from datetime import datetime
import json
import os
import msal

GRAPH_API_ENDPOINT = 'https://graph.microsoft.com/v1.0'


def generate_access_token(app_id, scopes):
    # Save Session Token as a token file
    access_token_cache = msal.SerializableTokenCache()

    # read the token file
    if os.path.exists('ms_graph_api_token.json'):
        access_token_cache.deserialize(open("ms_graph_api_token.json", "r").read())
        token_detail = json.load(open('ms_graph_api_token.json', ))
        token_detail_key = list(token_detail['AccessToken'].keys())[0]
        token_expiration = datetime.fromtimestamp(int(token_detail['AccessToken'][token_detail_key]['expires_on']))
        if datetime.now() > token_expiration:
            os.remove('ms_graph_api_token.json')
            access_token_cache = msal.SerializableTokenCache()

    # assign a SerializableTokenCache object to the client instance
    client = msal.PublicClientApplication(client_id=app_id, token_cache=access_token_cache)

    accounts = client.get_accounts()
    if accounts:
        # load the session
        token_response = client.acquire_token_silent(scopes, accounts[0])
    else:
        # authetnicate your accoutn as usual
        flow = client.initiate_device_flow(scopes=scopes)
        print('user_code: ' + flow['user_code'])
        webbrowser.open('https://microsoft.com/devicelogin')
        token_response = client.acquire_token_by_device_flow(flow)

    with open('ms_graph_api_token.json', 'w') as _f:
        _f.write(access_token_cache.serialize())

    return token_response


if __name__ == '__main__':
    ...

основной.py:

import os
import requests
from ms_graph import generate_access_token, GRAPH_API_ENDPOINT

APP_ID = 'my_client_id'
SCOPES = ['Files.ReadWrite']

access_token = generate_access_token(APP_ID, SCOPES)
headers = {
    'Authorization': 'Bearer' + access_token['access_token']
}

file_path = r'C:\Users\user\OneDrive\Desktop\Fiyat-2\example_file.txt'
file_name = os.path.basename(file_path)

with open(file_path, 'rb') as upload:
    content = upload.read()

response = requests.put(
    GRAPH_API_ENDPOINT + f'me/drive/items/root:/{file_path}:/content',
    headers=headers,
    data=content
)
print(response.json())

Выход:

C:\Users\user\OneDrive\Desktop\Fiyat-2\venv\Scripts\python.exe C:\Users\user\OneDrive\Desktop\Fiyat-2\main.py 
Traceback (most recent call last):
  File "C:\Users\user\OneDrive\Desktop\Fiyat-2\main.py", line 8, in <module>
    access_token = generate_access_token(APP_ID, SCOPES)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\OneDrive\Desktop\Fiyat-2\ms_graph.py", line 34, in generate_access_token
    print('user_code: ' + flow['user_code'])
                          ~~~~^^^^^^^^^^^^^
KeyError: 'user_code'

Process finished with exit code 1
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обратите внимание: для потока кода устройства требуется взаимодействие с веб-браузером, пользователь должен ввести код, сгенерированный потоком, и войти в систему с учетной записью пользователя.

Чтобы загрузить файл в OneDrive, вы можете использовать приведенный ниже код:

# Microsoft Graph API endpoint
GRAPH_API_ENDPOINT = 'https://graph.microsoft.com/v1.0/'

# Configuration for Microsoft Authentication
config = {
    "client_id": "ClientID",
    "authority": "https://login.microsoftonline.com/TenantID",
    "scope": ["Files.ReadWrite"],
}

access_token_cache = msal.SerializableTokenCache()

# Load cached token if available
if os.path.exists('ms_graph_api_token.json'):
    access_token_cache.deserialize(open("ms_graph_api_token.json", "r").read())
    token_detail = json.load(open('ms_graph_api_token.json', ))
    token_detail_key = next(iter(token_detail.keys()), None)  # Get the first key in the dictionary
    if token_detail_key == 'AccessToken':
        token_expiration = datetime.fromtimestamp(int(token_detail['AccessToken']['expires_on']))
        if datetime.now() > token_expiration:
            os.remove('ms_graph_api_token.json')
            access_token_cache = msal.SerializableTokenCache()

app = msal.PublicClientApplication(
    config["client_id"],
    authority=config["authority"],
    token_cache=access_token_cache,
)

result = None

# First, try to get a token from the cache.
accounts = app.get_accounts()

if accounts:
    # Use the first account to acquire a token silently.
    result = app.acquire_token_silent(config["scope"], account=accounts[0])

if not result:
    # If a token is not available in the cache, use the device flow to acquire a new token.
    flow = app.initiate_device_flow(scopes=config["scope"])
    print(flow["message"])
    # Open the browser automatically
    webbrowser.open(flow["verification_uri"])
    result = app.acquire_token_by_device_flow(flow)

# Use the access token to call the Microsoft Graph API.
if "access_token" in result:
    access_token = result["access_token"]
    headers = {'Authorization': 'Bearer ' + access_token}
    
    # File upload parameters
    file_path = r'C:\Users\rukmini\Downloads\RukRoleAssignmentPs.txt'
    file_name = os.path.basename(file_path)

    with open(file_path, 'rb') as upload:
        content = upload.read()

    response = requests.put(
        GRAPH_API_ENDPOINT + f'me/drive/root:/{file_name}:/content',
        headers=headers,
        data=content
    )
    
    # Output response
    print(response.json())

else:
    error = result.get("error")
    if error == "invalid_client":
        print("Invalid client ID. Please check your Azure AD application configuration")
    else:
        print(error)

Приведенный выше код открывает веб-браузер, и пользователь должен ввести код и войти в систему:

Файл успешно загружен в OneDrive:

Портал OneDrive:

Чтобы решить проблему, измените ms_graph.py, как показано ниже:

if accounts:
        # load the session
        token_response = client.acquire_token_silent(scopes, accounts[0])
    else:
        # authetnicate your accoutn as usual
        flow = client.initiate_device_flow(scopes=scopes)
           webbrowser.open('https://microsoft.com/devicelogin')
        token_response = client.acquire_token_by_device_flow(flow)

    with open('ms_graph_api_token.json', 'w') as _f:
        _f.write(access_token_cache.serialize())

    return token_response


if __name__ == '__main__':
    ...

Это сработало! Спасибо за ответ. Я закрепил ваш ответ как решение.

Zephyrus 10.04.2024 16:41

Могу ли я спросить, после первого запуска я получаю это сообщение: Неверный идентификатор клиента. Проверьте конфигурацию приложения Azure AD. Но все в порядке. Я уверен, что указываю правильный идентификатор клиента.

Zephyrus 10.04.2024 17:13

Возможно, проблема была на секунду, если сейчас все работает нормально, то проблем нет.

Rukmini 10.04.2024 17:16

Да, с первого раза все получилось. Но примерно через 20 раз я попытался загрузить файл еще раз и получил тот же результат. В сети или cmd ошибок нет. Но печатает неверный идентификатор клиента.

Zephyrus 10.04.2024 17:19

Затем попробуйте удалить оператор печати для недействительного клиента, и я не столкнусь с этой проблемой.

Rukmini 10.04.2024 17:21

Но файл тоже не загружается в OneDrive. изображение о выпуске

Zephyrus 10.04.2024 17:25

Давайте продолжим обсуждение в чате.

Rukmini 10.04.2024 17:40

Другие вопросы по теме