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

Google停用低安全应用后javax.mail IMAP读取邮件认证失败问题

问题说明

Google已于2022年5月30日正式停用「低安全性应用访问」功能,使用javax.mail组件通过IMAP协议读取Gmail邮箱邮件时会出现认证失败,无法正常获取邮件内容。

触发的报错信息

internal.qaauto.framework.exceptions.EmailDriverException: 
  javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
    at internal.qaauto.framework.drivers.email.ImapsEmailDriver.connect(ImapsEmailDriver.java:55)
    at certainwebapptests.CreateSubAccount.setUp(CreateSubAccount.java:53)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:514)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:215)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:178)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:782)
    at org.testng.TestRunner.run(TestRunner.java:632)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
    at org.testng.SuiteRunner.run(SuiteRunner.java:268)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
    at org.testng.TestNG.run(TestNG.java:1064)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:661)
    at javax.mail.Service.connect(Service.java:295)
    at internal.qaauto.framework.drivers.email.ImapsEmailDriver.connect(ImapsEmailDriver.java:45)
    ... 24 more

原有实现代码

try {
    Properties connectionProperties = new Properties();

    // Set IMAPS as store protocol
    connectionProperties.put("mail.store.protocol", "imaps");
    connectionProperties.put("mail.imaps.ssl.checkserveridentity", "false");

    // Create a session with mail server
    session = Session.getDefaultInstance(connectionProperties);

    // Get the Store, which is JavaMail name for the entity that holds the mails.
    store = session.getStore("imaps");

    // Connect the recently created Store
    reporter.debug("Connecting to " + MAIL_HOSTNAME + ":" + IMAP_PORT + " using " + MAIL_USER + "/" + MAIL_PASSWORD);
    store.connect(MAIL_HOSTNAME, IMAP_PORT, MAIL_USER, MAIL_PASSWORD);

    // Check that connection was successful
    checkConnection();

    // Select Inbox folder
    selectFolder("Inbox");
} catch (MessagingException e) {
    reporter.error(
        "Unable to connect to mail server " + MAIL_HOSTNAME + " through port " + IMAP_PORT +
        ". Using " + MAIL_USER + "/" + MAIL_PASSWORD + ". Reason: " + e.getMessage()
    );
    throw new RuntimeException(e);
}
合规接入方案

原账号明文密码直连IMAP的方式已被Google拦截,目前有两种官方认可的合规接入方式:

方案一:应用专用密码(改动最小,适合测试/个人临时场景)

  • 前置条件:对应Gmail账号已开启两步验证
  • 操作流程:进入Google账号安全设置页,找到应用专用密码生成入口,选择「邮件」应用和对应的使用设备,生成16位长度的应用专用密码
  • 代码改动:无需调整原有连接逻辑,仅将代码中MAIL_PASSWORD变量的值从原账号登录密码替换为刚生成的16位应用专用密码即可,Gmail IMAP连接地址固定为imap.gmail.com,端口993,保持原有SSL配置即可正常连接。

方案二:OAuth2.0认证(官方推荐,适合生产/长期自动化场景)

该方案是Google当前主推的标准认证方式,无需依赖账号两步验证,权限管控粒度更细,安全性更高。

  • 前置准备:在Google云控制台创建对应项目,开启Gmail API权限,给目标邮箱账号授权IMAP访问范围,拿到对应的访问令牌(access_token)和刷新令牌(refresh_token)
  • 代码改动:调整连接配置,启用XOAUTH2认证机制,替换原有明文密码为OAuth2认证凭证,修改后的核心连接代码如下:
try {
    Properties connectionProperties = new Properties();
    connectionProperties.put("mail.store.protocol", "imaps");
    connectionProperties.put("mail.imaps.ssl.checkserveridentity", "false");
    // 新增OAuth2相关SASL配置
    connectionProperties.put("mail.imaps.sasl.enable", "true");
    connectionProperties.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
    connectionProperties.put("mail.imaps.auth.login.disable", "true");
    connectionProperties.put("mail.imaps.auth.plain.disable", "true");

    // 注意不要用getDefaultInstance,避免和其他邮件配置冲突
    session = Session.getInstance(connectionProperties);
    store = session.getStore("imaps");

    // 拼接XOAUTH2认证串,格式固定
    String oauth2Credential = String.format("user=%s\u0001auth=Bearer %s\u0001\u0001", MAIL_USER, accessToken);
    store.connect(MAIL_HOSTNAME, IMAP_PORT, MAIL_USER, oauth2Credential);

    checkConnection();
    selectFolder("Inbox");
} catch (MessagingException e) {
    reporter.error(
        "Unable to connect to mail server " + MAIL_HOSTNAME + " through port " + IMAP_PORT +
        ". Using " + MAIL_USER + ". Reason: " + e.getMessage()
    );
    throw new RuntimeException(e);
}
  • 注意事项:access_token有效期通常为1小时,需要通过refresh_token定期刷新,避免认证过期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:31:04