通过IMAP连接Office365提示过多登录失败:基本认证与现代认证适配问题
PHP 实现 Office 365 IMAP 现代身份认证(OAuth2)连接方案
为什么原有方案失效
微软自2022年10月起已全面停用Exchange Online的基础身份认证机制,IMAP、POP、SMTP等协议不再支持直接用账号密码的方式登录,因此你之前所有调整基础认证参数的操作都无法生效。
前置配置(Azure AD 应用注册)
你需要先在Azure Active Directory中注册应用,获取OAuth2认证所需的凭证:
- 登录Azure门户,进入Azure Active Directory模块,选择「应用注册」-「新注册」
- 填写应用名称,账号支持类型选择「仅限组织目录中的账户」,重定向URI按你的实际业务回调地址填写,完成注册
- 记录应用的 客户端ID(应用程序ID)、租户ID,再进入「证书和密码」页面新建客户端密码,记录客户端密钥值
- 进入「API权限」页面,点击「添加权限」,选择「Office 365 Exchange Online」-「委托权限」,勾选
IMAP.AccessAsUser.All,完成后点击「授予管理员同意」完成权限授权
代码实现示例
第一步:获取OAuth2访问令牌
// 替换为你自己的配置 $tenantId = '你的租户ID'; $clientId = '你的客户端ID'; $clientSecret = '你的客户端密钥'; $userEmail = '要连接的邮箱账号'; $redirectUri = '你注册时填的重定向URI'; // 首次授权需要引导用户跳转微软登录页获取authorization_code,后续可以用刷新令牌免登录获取令牌 $code = '用户登录后回调带回的authorization_code'; $tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"; $postData = [ 'client_id' => $clientId, 'client_secret' => $clientSecret, 'grant_type' => 'authorization_code', 'code' => $code, 'redirect_uri' => $redirectUri, 'scope' => 'https://outlook.office.com/IMAP.AccessAsUser.All offline_access' ]; $ch = curl_init($tokenUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); $response = curl_exec($ch); curl_close($ch); $tokenInfo = json_decode($response, true); $accessToken = $tokenInfo['access_token']; // 记得持久化存储refresh_token,后续可以用grant_type=refresh_token刷新访问令牌,不需要用户重新登录
第二步:用访问令牌通过IMAP连接邮箱
$user = $userEmail; // 拼接XOAuth2认证字符串 $authStr = base64_encode("user=$user\1auth=Bearer $accessToken\1\1"); $hostname = '{outlook.office365.com:993/ssl}INBOX'; // 开启XOAuth2认证,禁用其他不需要的认证方式 $m = imap_open( $hostname, $user, $authStr, null, 1, [ 'DISABLE_AUTHENTICATOR' => 'GSSAPI', 'AUTHENTICATE' => 'XOAUTH2' ] ); // 验证连接结果 if ($m) { echo '连接成功'; // 后续正常调用imap系列函数操作邮箱即可 imap_close($m); } else { echo '连接失败:' . imap_last_error(); }
注意事项
- 访问令牌默认有效期为1小时,过期后需要用保存的刷新令牌请求新的访问令牌,不需要用户重新授权
- 客户端密钥、刷新令牌属于敏感信息,禁止硬编码到代码中,建议存入环境变量或者专用的加密配置存储
- 如果是无用户交互的后台守护进程场景,可以改用客户端凭证流获取令牌,对应权限需要配置应用权限下的
IMAP.AccessAsApp,同时需要在Exchange Online中给应用授予对应邮箱的访问权限
内容的提问来源于stack exchange,提问作者harri
相关产品推荐
相关产品推荐

