繁体   English   中英

微软图形 Api Python

[英]Microsoft Graph Api Python

我正在尝试执行 microsoft graph 请求为: "https://graph.microsoft.com/v1.0/me""https://graph.microsoft.com/v1.0/me/messages"等等在我的 python 脚本上

在使用此 web 接口https://developer.microsoft.com/fr-fr/graph/graph-explorer测试这些请求时,所有请求都有效

在我的脚本上,只有这个请求有效"https://graph.microsoft.com/v1.0/me" ,其他请求我得到错误

这是我的脚本:

import msal
import jwt
import json
import sys
import requests
from datetime import datetime
from msal_extensions import *
graphURI = 'https://graph.microsoft.com'
tenantID = 'my tenant id'
authority = 'https://login.microsoftonline.com/' + tenantID
clientID = 'my client id'
scope = ["email Files.ReadWrite.All", "Mail.Read", "Mail.Read.Shared", "Mail.ReadBasic", "Mail.ReadWrite", "Mail.ReadWrite.Shared Mail.Send Mail.Send.Shared MailboxSettings.Read MailboxSettings.ReadWrite openid profile Sites.ReadWrite.All User.Read User.ReadBasic.All"]
username = 'yourAADUsername' # i keep this one like this, i don't know what is my username
result = None
tokenExpiry = None
def msal_persistence(location, fallback_to_plaintext=False):
    if sys.platform.startswith('win'):
        return FilePersistenceWithDataProtection(location)
    if sys.platform.startswith('darwin'):
        return KeychainPersistence(location, "my_service_name", "my_account_name")
        return FilePersistence(location)
def msal_cache_accounts(clientID, authority):
# Accounts
    persistence = msal_persistence("token_cache.bin")
    print("Is this MSAL persistence cache encrypted?", persistence.is_encrypted)
    cache = PersistedTokenCache(persistence)
    app = msal.PublicClientApplication(
    client_id=clientID, authority=authority, token_cache=cache)
    accounts = app.get_accounts()
    print(accounts)
    return accounts
def msal_delegated_refresh(clientID, scope, authority, account):
    persistence = msal_persistence("token_cache.bin")
    cache = PersistedTokenCache(persistence)
    app = msal.PublicClientApplication(
    client_id=clientID, authority=authority, token_cache=cache)
    result = app.acquire_token_silent_with_error(
    scopes=scope, account=account)
    return result
def msal_delegated_refresh_force(clientID, scope, authority, account):
    persistence = msal_persistence("token_cache.bin")
    cache = PersistedTokenCache(persistence)
    app = msal.PublicClientApplication(
    client_id=clientID, authority=authority, token_cache=cache)
    result = app.acquire_token_silent_with_error(
    scopes=scope, account=account, force_refresh=True)
    return result
def msal_delegated_device_flow(clientID, scope, authority):
    print("Initiate Device Code Flow to get an AAD Access Token.")
    print("Open a browser window and paste in the URL below and then enter the Code. CTRL+C to cancel.")
    persistence = msal_persistence("token_cache.bin")
    cache = PersistedTokenCache(persistence)
    app = msal.PublicClientApplication(client_id=clientID, authority=authority, token_cache=cache)
    flow = app.initiate_device_flow(scopes=scope)
    if "user_code" not in flow:
        raise ValueError("Fail to create device flow. Err: %s" % json.dumps(flow, indent=4))
    print(flow["message"])
    sys.stdout.flush()
    result = app.acquire_token_by_device_flow(flow)
    return result
def msal_jwt_expiry(accessToken):
    decodedAccessToken = jwt.decode(accessToken, verify=False)
    accessTokenFormatted = json.dumps(decodedAccessToken, indent=2)
    # Token Expiry
    tokenExpiry = datetime.fromtimestamp(int(decodedAccessToken['exp']))
    print("Token Expires at: " + str(tokenExpiry))
    return tokenExpiry
def msgraph_request(resource, requestHeaders):
    # Request
    results = requests.get(resource, headers=requestHeaders).json()
    return results
accounts = msal_cache_accounts(clientID, authority)
if accounts:
    for account in accounts:
        if account['username'] == username:
            myAccount = account
            print("Found account in MSAL Cache: " + account['username'])
            print("Obtaining a new Access Token using the Refresh Token")
            result = msal_delegated_refresh(clientID, scope, authority, myAccount)
print(result)
if result is None:
    # Get a new Access Token using the Device Code Flow
    result = msal_delegated_device_flow(clientID, scope, authority)
    print(result)
else:
    if result["access_token"]:
        msal_jwt_expiry(result["access_token"])
    else:
        # Get a new Access Token using the Device Code Flow
        result = msal_delegated_device_flow(clientID, scope, authority)
if result["access_token"]:
    msal_jwt_expiry(result["access_token"])
    # Query AAD Users based on voice query using DisplayName
    print(graphURI + "/v1.0/me")

requestHeaders = {'Authorization': 'Bearer ' + result["access_token"],'Content-Type': 'application/json'}
queryResults = msgraph_request(graphURI + "/v1.0/me",requestHeaders)
print(json.dumps(queryResults, indent=2))

所以当我执行这个查询时: queryResults = msgraph_request(graphURI + "/v1.0/me",requestHeaders)

output 是:

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "businessPhones": [],
  "displayName": "Joe Coral",
  "givenName": "Joe",
  "jobTitle": null,
  "mail": null,
  "mobilePhone": null,
  "officeLocation": null,
  "preferredLanguage": "en",
  "surname": "Coral",
  "userPrincipalName": "joe-coral-hotmail.fr#EXT#@joecoralhotmail.onmicrosoft.com",
  "id": "82a2ef56-dbb7-45a4-bc9c-c533fd2c5908"
}

但是当我使用这个查询时: queryResults = msgraph_request(graphURI + "/v1.0/me/messages",requestHeaders)

output 是:

{
  "error": {
    "code": "ResourceNotFound",
    "message": "Resource could not be discovered.",
    "innerError": {
      "date": "2021-06-08T15:03:31",
      "request-id": "fa8dc282-0c8d-4be4-a195-4488c4f86e23",
      "client-request-id": "fa8dc282-0c8d-4be4-a195-4488c4f86e23"
    }
  }
}

在我的 ADD 申请中,我授予了所有权限:

权限

根据您的/v1.0/me请求结果,我可以看到该用户是个人 Microsoft 帐户,并且已作为来宾添加到此 AAD 租户中。

当您使用此用户登录https://developer.microsoft.com/fr-fr/graph/graph-explorer时,它实际上将您的帐户视为个人 Microsoft 帐户,而不是来宾用户。

这是因为 Microsoft Graph Explorer 使用common终结点进行身份验证。 (请参阅我以前的答案中的详细信息)

但是在您的代码中,我看到您输入了authority = 'https://login.microsoftonline.com/' + tenantID ,这意味着它将您的帐户视为该租户中的来宾用户。

在这种情况下,当您调用/v1.0/me/messages时,它会尝试从 Exchange Online 中托管的 O365 邮箱中获取消息。 但来宾用户没有 Exchange Online 许可证,也没有托管在 Exchange Online 中。 这就是您收到ResourceNotFound错误的原因。

因此,根据您的描述,我认为您正试图以个人 Microsoft 帐户而不是来宾用户的身份为用户获取消息。

请修改authority = 'https://login.microsoftonline.com/' + tenantIDauthority = 'https://login.microsoftonline.com/common' 这应该可以解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM