You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure应用连接OneDrive身份验证异常:非管理员用户触发MFA要求

问题描述

通过编程方式连接OneDrive并下载文件,当前代码管理员用户可正常运行,但租户内非管理员用户使用时会收到「必须使用MFA」的提示。疑问:该问题是因为管理员身份差异导致,还是注册的应用权限存在问题?(注:租户MFA设置不可修改)

代码示例
import logging
import requests
import json
import msal
import requests

CLIENT_ID = ''
TENANT_ID = ''
AUTHORITY_URL = 'https://login.microsoftonline.com/{}'.format(TENANT_ID)
RESOURCE_URL = 'https://graph.microsoft.com/'
API_VERSION = 'v1.0'
USERNAME = '' # Office365 user's account username
PASSWORD = ''
SCOPES = ['Sites.ReadWrite.All','Files.ReadWrite.All'] # Add other scopes/permissions as needed.

# Creating a public client app, Acquire a access token for the user and set the header for API calls
cognos_to_onedrive = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY_URL)
token = cognos_to_onedrive.acquire_token_by_username_password(USERNAME,PASSWORD,SCOPES)
headers = {'Authorization': 'Bearer {}'.format(token['access_token'])}
r = requests.get('https://graph.microsoft.com/v1.0/me/drives/{drive_id}/root:/DropFileOut', headers=headers).json()
print(r)
问题分析与解决方案

核心原因

这不是应用权限的问题,而是认证方式与租户MFA策略的冲突:

  • 你当前使用的是用户名密码流(ROPC),该认证方式本身不支持MFA验证。
  • 租户大概率对非管理员用户启用了强制MFA登录策略,而管理员账号被排除在该策略之外(很多组织为避免管理员账号锁死,会单独配置MFA规则或暂时豁免),所以管理员用ROPC流能正常获取令牌,非管理员用户触发MFA要求后,ROPC无法处理就报错。

可行解决方案(因MFA设置不可修改)

1. 切换为授权码流(推荐)

授权码流是微软官方推荐的用户交互型认证方式,天然支持MFA,流程如下:

  • 用户通过浏览器跳转至微软登录页,完成MFA验证后授权应用访问资源。
  • 应用获取授权码,兑换为访问令牌和刷新令牌,后续可用刷新令牌自动获取新的访问令牌,无需重复登录。

调整后的代码示例:

import msal
import requests

CLIENT_ID = ''
TENANT_ID = ''
AUTHORITY_URL = f'https://login.microsoftonline.com/{TENANT_ID}'
SCOPES = ['Sites.ReadWrite.All', 'Files.ReadWrite.All']

# 初始化公共客户端应用
app = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY_URL)

# 生成授权URL
auth_url = app.get_authorization_request_url(SCOPES)
print(f"请访问以下URL完成授权:{auth_url}")
authorization_code = input("请输入授权码:")

# 用授权码兑换令牌
result = app.acquire_token_by_authorization_code(authorization_code, SCOPES)

if 'access_token' in result:
    headers = {'Authorization': f'Bearer {result["access_token"]}'}
    r = requests.get('https://graph.microsoft.com/v1.0/me/drives/{drive_id}/root:/DropFileOut', headers=headers).json()
    print(r)
else:
    print(f"获取令牌失败:{result.get('error_description')}")

2. 后台服务场景:客户端凭证流(无用户交互)

如果你的应用是后台服务,无法进行用户交互,可改用客户端凭证流:

  • 需在Azure AD中为应用配置应用权限(而非当前的委托权限),比如Files.ReadWrite.All(应用权限)。
  • 该方式无需用户参与,应用直接用自身身份获取令牌,访问租户内被授权的资源(注意:不能用/me端点,需通过用户ID或驱动器ID指定具体资源)。

内容的提问来源于stack exchange,提问作者Abhishek Rai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:31:50