我试图在python脚本上执行microsoft graph请求,如:"https://graph.microsoft.com/v1.0/me"
、"https://graph.microsoft.com/v1.0/me/messages"
等等
在使用此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)
输出为:
{
"@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)
输出为:
{
"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
端点进行身份验证。(详情请参阅mypervious answer)但是在您的代码中,我看到您放置了
authority = 'https://login.microsoftonline.com/' + tenantID
,这意味着它会将您的帐户视为此租户中的来宾用户在这种情况下,当您调用
/v1.0/me/messages
时,它将尝试从Exchange Online中托管的O365邮箱获取邮件。但是来宾用户没有Exchange Online许可证,也不在Exchange Online中托管。这就是为什么会出现ResourceNotFound
错误因此,根据您的描述,我认为您正在尝试以个人Microsoft帐户而不是来宾用户的身份为用户获取消息
请将
authority = 'https://login.microsoftonline.com/' + tenantID
修改为authority = 'https://login.microsoftonline.com/common'
。这应该可以解决问题相关问题 更多 >
编程相关推荐