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

Java使用OAuth2认证连接Microsoft Exchange邮箱的实现步骤咨询

基于Azure OAuth2认证的Java Mail连接Exchange实操步骤

1. 补全Azure侧剩余配置

你已经完成应用创建、API权限添加的基础操作,还需完成以下配置:

  • 配置平台重定向URI:后台服务场景选「Web」平台,重定向URI填https://login.microsoftonline.com/common/oauth2/nativeclient;交互客户端场景填自身业务回调地址即可。
  • 开启公共客户端流:进入应用「认证」菜单,找到高级设置下的「允许公共客户端流」选项,选择「是」后保存。
  • 校验权限配置:确认添加的是Office 365 Exchange Online分组下的应用程序权限(后台服务场景)或委托权限(用户自主登录场景),对应权限为IMAP.AccessAsApp、POP.AccessAsApp、SMTP.SendAsApp(应用权限)/IMAP.AccessAsUser.All、POP.AccessAsUser.All、SMTP.Send(委托权限),添加完成后点击同页面的「授予管理员同意」按钮,等待权限状态显示为已授权。
  • 记录核心参数:保存好应用(客户端)ID、租户ID、新建的客户端密钥值(密钥创建后仅展示一次,丢失需重建)。
  • 后台服务场景额外配置:连接Exchange Online PowerShell执行访问策略授权,命令为New-ApplicationAccessPolicy -AppId 你的应用客户端ID -PolicyScopeGroupId 目标邮箱地址 -AccessRight RestrictAccess -Description "邮件应用访问授权",执行后等待15分钟待策略生效。

2. 引入项目依赖

需引入支持XOAUTH2认证的Java Mail版本,以及微软官方MSAL4J认证库用于获取令牌,Maven依赖示例如下:

<!-- Java Mail核心依赖,1.6.0及以上版本原生支持XOAUTH2 -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
<!-- 微软官方认证库,用于获取Azure AD颁发的OAuth2令牌 -->
<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>msal4j</artifactId>
    <version>1.14.0</version>
</dependency>

如果使用Jakarta EE体系的Jakarta Mail,替换对应依赖坐标为jakarta.mail:jakarta.mail-api:2.0.1+org.eclipse.angus:angus-mail:2.0.1即可,代码逻辑无差异。

3. 编写令牌获取逻辑

获取令牌时的资源范围固定为https://outlook.office365.com/.default,不要误用Graph API的范围。后台服务场景(客户端凭证流)的令牌获取代码示例:

import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import java.util.Collections;
import java.util.Set;

public class ExchangeOAuthUtil {
    // 替换为你自己Azure应用的参数
    private static final String CLIENT_ID = "你的Azure应用客户端ID";
    private static final String TENANT_ID = "你的Azure租户ID";
    private static final String CLIENT_SECRET = "你创建的客户端密钥值";
    private static final String AUTHORITY = "https://login.microsoftonline.com/" + TENANT_ID;
    private static final Set<String> MAIL_SCOPES = Collections.singleton("https://outlook.office365.com/.default");

    public static String getAccessToken() throws Exception {
        ConfidentialClientApplication clientApp = ConfidentialClientApplication.builder(
                CLIENT_ID,
                ClientCredentialFactory.createFromSecret(CLIENT_SECRET)
        ).authority(AUTHORITY).build();

        ClientCredentialParameters authParams = ClientCredentialParameters.builder(MAIL_SCOPES).build();
        return clientApp.acquireToken(authParams).get().accessToken();
    }
}

如果是委托权限的用户交互场景,将ConfidentialClientApplication替换为PublicClientApplication,走交互式登录流程获取令牌即可,范围参数无需修改。

4. 编写邮件连接读取代码

连接IMAP服务时固定使用服务器地址outlook.office365.com、端口993,开启SSL,指定认证机制为XOAUTH2,连接时密码参数传入获取到的OAuth2令牌即可,代码示例:

import javax.mail.*;
import java.util.Properties;

public class ImapMailReader {
    public static void main(String[] args) throws Exception {
        String targetMail = "要访问的目标邮箱地址";
        String accessToken = ExchangeOAuthUtil.getAccessToken();

        Properties props = new Properties();
        // IMAP基础配置
        props.put("mail.imap.host", "outlook.office365.com");
        props.put("mail.imap.port", "993");
        props.put("mail.imap.ssl.enable", "true");
        props.put("mail.imap.auth.mechanisms", "XOAUTH2");
        // POP3配置参考:把上述imap替换为pop3,端口改为995,其余配置一致
        // SMTP发信配置参考:host填smtp.office365.com,端口587,开启starttls,auth.mechanisms同样设为XOAUTH2

        Session session = Session.getInstance(props);
        // 排错时可设为true查看详细通信日志
        session.setDebug(false);

        try (Store store = session.getStore("imap")) {
            // 用户名填完整邮箱地址,密码传OAuth2访问令牌
            store.connect(targetMail, accessToken);
            // 以只读模式打开收件箱
            Folder inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_ONLY);

            // 读取最新10封邮件示例
            int totalCount = inbox.getMessageCount();
            int startIndex = Math.max(1, totalCount - 9);
            Message[] recentMessages = inbox.getMessages(startIndex, totalCount);
            for (Message msg : recentMessages) {
                System.out.println("邮件主题:" + msg.getSubject());
                System.out.println("发件人:" + msg.getFrom()[0]);
            }

            inbox.close(false);
        }
    }
}

常见问题排查

  • 获取令牌报403:检查是否已授予管理员同意、客户端密钥是否在有效期、权限类型是否和认证流匹配(客户端凭证流不能用委托权限)、scope是否填写正确。
  • 连接邮箱报认证失败:检查令牌是否为outlook.office365.com资源颁发(不要用Graph API的令牌)、目标邮箱是否开启IMAP/POP/SMTP功能、Exchange访问策略是否已生效。
  • 连接超时:检查服务器出站规则是否放开993(IMAP)、995(POP)、587(SMTP)端口,是否存在到Office 365服务器的网络拦截。
  • SMTP发信失败:额外添加配置mail.smtp.starttls.enable=true,不要使用25端口发信。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:45:47