MSAL成功获取Bearer令牌,但调用Microsoft Graph提示权限不足
问题:使用Microsoft Graph访问邮箱时出现权限不足错误
背景
- 原通过
exchangelib库以Basic Auth方式访问组织邮箱,因微软不再支持Basic Auth,改用Microsoft Graph开发Python应用,需求为读取并转发指定邮箱someuser@myorganization.com的邮件。 - 组织已在Microsoft身份平台注册名为“Email Service App”的应用,提供的权限截图显示已授予相关权限(本人无Graph控制台访问权限)。

代码实现(参考MSAL示例)
初始化配置与应用实例
config_data = { "authority": "https://login.microsoftonline.com/<secret value>", "client_id": "<secret value>", "scope": ["https://graph.microsoft.com/.default"], "secret": "<secret value>", "endpoint": "https://graph.microsoft.com/v1.0/users" } # Optional logging logging.basicConfig(level=logging.DEBUG) # Enable DEBUG log for entire script logging.getLogger("msal").setLevel(logging.INFO) # Optionally disable MSAL DEBUG logs config = json.loads(config_data) # Create a preferably long-lived app instance which maintains a token cache. app = msal.ConfidentialClientApplication( config["client_id"], authority=config["authority"], client_credential=config["secret"], )
初始化阶段日志输出
DEBUG:urllib3.util.retry:Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None) DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): login.microsoftonline.com:443 DEBUG:urllib3.connectionpool:https://login.microsoftonline.com:443 "GET /<secret>/v2.0/.well-known/openid-configuration HTTP/1.1" 200 1753
尝试从缓存获取令牌
# The pattern to acquire a token looks like this. result = None # Firstly, looks up a token from cache # Since we are looking for token for the current app, NOT for an end user, # notice we give account parameter as None. result = app.acquire_token_silent(config["scope"], account=None)
缓存查询阶段日志输出
INFO:root:No suitable token exists in cache. Let's get a new one from AAD. DEBUG:urllib3.connectionpool:https://login.microsoftonline.com:443 "POST /<secret>/oauth2/v2.0/token HTTP/1.1" 200 1589
获取新令牌
if not result: logging.info("No suitable token exists in cache. Let's get a new one from AAD.") result = app.acquire_token_for_client(scopes=config["scope"])
获取新令牌阶段日志输出
INFO:root:No suitable token exists in cache. Let's get a new one from AAD. DEBUG:urllib3.connectionpool:https://login.microsoftonline.com:443 "POST /<secret>/oauth2/v2.0/token HTTP/1.1" 200 1589
令牌输出(已成功获取)
{'token_type': 'Bearer', 'expires_in': 3599, 'ext_expires_in': 3599, 'access_token': <removed, was successful>}
调用Microsoft Graph API
if "access_token" in result: # Calling graph using the access token graph_data = requests.get( # Use token to call downstream service config["endpoint"], headers={'Authorization': 'Bearer ' + result['access_token']},).json() print("Graph API call result: %s" % json.dumps(graph_data, indent=2)) else: print(result.get("error")) print(result.get("error_description")) print(result.get("correlation_id")) # You may need this when reporting a bug
API调用阶段日志输出
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): graph.microsoft.com:443 DEBUG:urllib3.connectionpool:https://graph.microsoft.com:443 "GET /v1.0/users HTTP/1.1" 403 None Graph API call result: { "error": { "code": "Authorization_RequestDenied", "message": "Insufficient privileges to complete the operation.", "innerError": { "date": "2022-11-06T13:07:13", "request-id": "13a2593f-e9c9-4844-aca5-7c362a7f83b8", "client-request-id": "13a2593f-e9c9-4844-aca5-7c362a7f83b8" } } }
疑问
已成功获取Bearer令牌,但调用Graph API时返回权限不足错误,而权限截图显示已授予相关权限。请问问题出在代码实现、组织的Microsoft Graph配置,还是其他原因?
内容的提问来源于stack exchange,提问作者dmmfll
相关产品推荐
相关产品推荐

