我在非Android环境下使用JavaMail连接GMail时遇到问题。我正在获得OAuth2访问令牌,我认为这是正确的。但是当我尝试使用此访问令牌进行连接时,我得到一个例外:
javax.mail.AuthenticationFailedException:[AUTHENTICATIONFAILED]凭据无效(失败)
对我来说,看起来像Java SASL代码期望有两个返回值(用户名和密码回调?),但只有一个。
我已将问题归结为此代码:
import java.io.IOException;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
public class TestImap {
private String userId;
private String accessToken;
public TestImap(String[] args) {
userId = args[0];
accessToken = args[1];
}
public void connectImap()
throws MessagingException
{
System.out.println("Connecting to gmail with IMAP and OAUTH2.");
Properties props = new Properties();
props.put("mail.imaps.ssl.enable", "true");
props.put("mail.imaps.sasl.enable", "true");
props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
props.put("mail.imaps.auth.login.disable", "true");
props.put("mail.imaps.auth.plain.disable", "true");
props.put("mail.debug.auth", "true");
/*
props.put("mail.imaps.sasl.mechanisms.oauth2.oauthToken",
accessToken);
*/
System.out.println("Creating session...");
Session session = Session.getInstance(props);
session.setDebug(true);
System.out.println("Creating store...");
Store store = session.getStore("imaps");
System.out.println("Connecting store...");
store.connect("imap.gmail.com", 993, userId, accessToken);
System.out.println("Store connected. If we get here, things work.");
}
public static void main(String[] args) {
TestImap test = new TestImap(args);
try {
test.connectImap();
} catch (Throwable e) {
System.out.println("Died throwing an exception: ");
e.printStackTrace();
}
}
}
运行时,会给出以下输出:
Connecting to gmail with IMAP and OAUTH2.
Creating session...
DEBUG: setDebug: JavaMail version 1.5.3
Creating store...
DEBUG: getProvider() returning javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle]
DEBUG IMAPS: mail.imap.fetchsize: 16384
DEBUG IMAPS: mail.imap.ignorebodystructuresize: false
DEBUG IMAPS: mail.imap.statuscachetimeout: 1000
DEBUG IMAPS: mail.imap.appendbuffersize: -1
DEBUG IMAPS: mail.imap.minidletime: 10
DEBUG IMAPS: disable AUTH=LOGIN
DEBUG IMAPS: disable AUTH=PLAIN
DEBUG IMAPS: enable SASL
DEBUG IMAPS: SASL mechanisms allowed: XOAUTH2
DEBUG IMAPS: closeFoldersOnStoreFailure
Connecting store...
DEBUG IMAPS: trying to connect to host "imap.gmail.com", port 993, isSSL true
* OK Gimap ready for requests from 162.243.86.176 d92mb281521696qgf
A0 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN
A0 OK Thats all she wrote! d92mb281521696qgf
DEBUG IMAPS: AUTH: XOAUTH
DEBUG IMAPS: AUTH: XOAUTH2
DEBUG IMAPS: AUTH: PLAIN
DEBUG IMAPS: AUTH: PLAIN-CLIENTTOKEN
DEBUG IMAPS: protocolConnect login, host=imap.gmail.com, user=bhurt42@gmail.com, password=<non-null>
DEBUG IMAPS: SASL Mechanisms:
DEBUG IMAPS: XOAUTH2
DEBUG IMAPS:
DEBUG IMAPS: SASL client XOAUTH2
DEBUG IMAPS: SASL callback length: 2
DEBUG IMAPS: SASL callback 0: javax.security.auth.callback.NameCallback@268d5581
DEBUG IMAPS: SASL callback 1: javax.security.auth.callback.PasswordCallback@8e89bed
A1 AUTHENTICATE XOAUTH2 dXNlcj1iaHVydDQyQGdtYWlsLmNvbQFhdXRoPUJlYXJlciB5YTI5LldBRjY1ZGZZT3YyWEdTdkozOWdTUEswN2ZHeWhCdFNjeWp0WFlGTHliN2NobHAyemlFa0MtNFo2UWdmMG9UQWR4b2NiZXpHX2ZPdW91dwEB
+ eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==
DEBUG IMAPS: SASL no response
A1 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
Died throwing an exception:
javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:722)
at javax.mail.Service.connect(Service.java:364)
at TestImap.connectImap(TestImap.java:38)
at TestImap.main(TestImap.java:45)
这是JavaMail 1.5.3。我用谷歌搜索了这个问题,到目前为止我发现的大部分答案已经足够陈旧,我很确定它们早于JavaMail支持google本地化。
非常感谢任何帮助。感谢。