Java实现MS Exchange邮件Modern Authentication升级求助
升级Java服务端实现MS Exchange邮件发送的Modern Authentication(OAuth2)
依赖准备
使用Maven引入JavaMail和MSAL4J(微软官方OAuth2客户端库):
<!-- JavaMail API --> <dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.6.2</version> </dependency> <!-- MSAL4J - 微软Azure AD OAuth2客户端库 --> <dependency> <groupId>com.microsoft.azure</groupId> <artifactId>msal4j</artifactId> <version>1.14.0</version> </dependency>
1. 获取OAuth2访问令牌(Client Credentials Flow)
服务端场景采用客户端凭证流获取令牌,替换代码中配置项为你的实际信息:
import com.microsoft.aad.msal4j.ClientCredentialFactory; import com.microsoft.aad.msal4j.ClientCredentialParameters; import com.microsoft.aad.msal4j.ConfidentialClientApplication; import com.microsoft.aad.msal4j.IAuthenticationResult; import java.util.Collections; import java.util.concurrent.CompletableFuture; public class OAuth2TokenProvider { // 替换为你的租户ID、客户端ID、客户端密钥 private static final String TENANT_ID = "your-tenant-id"; private static final String CLIENT_ID = "your-client-id"; private static final String CLIENT_SECRET = "your-client-secret"; // Exchange Online SMTP权限范围 private static final String EXCHANGE_SCOPE = "https://outlook.office365.com/.default"; public static String getAccessToken() throws Exception { ConfidentialClientApplication authApp = ConfidentialClientApplication.builder( CLIENT_ID, ClientCredentialFactory.createFromSecret(CLIENT_SECRET)) .authority("https://login.microsoftonline.com/" + TENANT_ID) .build(); ClientCredentialParameters params = ClientCredentialParameters.builder( Collections.singleton(EXCHANGE_SCOPE)) .build(); CompletableFuture<IAuthenticationResult> authFuture = authApp.acquireToken(params); IAuthenticationResult authResult = authFuture.get(); return authResult.accessToken(); } }
2. 配置JavaMail发送邮件(XOAUTH2认证)
通过JavaMail的XOAUTH2认证机制对接Exchange Online SMTP服务:
import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Properties; public class ExchangeOAuth2MailSender { public static void sendEmail(String accessToken, String senderEmail, String recipientEmail, String subject, String content) throws MessagingException { Properties mailProps = new Properties(); // Exchange Online SMTP基础配置 mailProps.put("mail.smtp.host", "smtp.office365.com"); mailProps.put("mail.smtp.port", "587"); mailProps.put("mail.smtp.starttls.enable", "true"); // 启用认证并指定XOAUTH2机制 mailProps.put("mail.smtp.auth", "true"); mailProps.put("mail.smtp.auth.mechanisms", "XOAUTH2"); // 构建带OAuth2认证的邮件会话 Session mailSession = Session.getInstance(mailProps, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { // 用户名填发件人邮箱,密码填OAuth2访问令牌 return new PasswordAuthentication(senderEmail, accessToken); } }); // 构建并发送邮件 MimeMessage message = new MimeMessage(mailSession); message.setFrom(new InternetAddress(senderEmail)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipientEmail)); message.setSubject(subject); message.setText(content); Transport.send(message); } // 测试入口 public static void main(String[] args) { try { String accessToken = OAuth2TokenProvider.getAccessToken(); sendEmail(accessToken, "sender@your-domain.com", "recipient@target-domain.com", "Modern Auth测试邮件", "这是通过OAuth2认证发送的Exchange邮件"); System.out.println("邮件发送成功"); } catch (Exception e) { e.printStackTrace(); } } }
关键注意事项
- Azure AD应用配置:必须为应用添加Exchange Online的SMTP.Send应用权限(非委托权限),并完成全局管理员同意。
- 令牌缓存:MSAL4J默认自动缓存访问令牌,生产环境无需重复调用令牌端点,避免触发限流。
- 权限验证:确保发件人邮箱属于你的租户,且应用权限已正确配置生效。
- 依赖兼容:若遇到依赖冲突,可调整JavaMail和MSAL4J的版本至兼容组合。
内容的提问来源于stack exchange,提问作者Disha Garg
相关产品推荐
相关产品推荐

