我试图实现使用来自Android的的AccountManager接受,而不是使用用户名和密码的令牌的IMAP Gmail客户端。
谷歌提供IMAP的这个例子用的oauth2 http://code.google.com/p/google-mail-oauth2-tools/source/browse/#svn%2Ftrunk%2Fjava%2Fcom%2Fgoogle%2Fcode%2Fsamples%2Foauth2 HTTP: //code.google.com/p/google-mail-oauth2-tools/wiki/JavaSampleCode
public static IMAPStore connectToImap(String host,
int port,
String userEmail,
String oauthToken,
boolean debug) throws Exception {
Properties props = new Properties();
props.put("mail.imaps.sasl.enable", "true");
props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken);
Session session = Session.getInstance(props);
session.setDebug(debug);
final URLName unusedUrlName = null;
IMAPSSLStore store = new IMAPSSLStore(session, unusedUrlName);
final String emptyPassword = "";
store.connect(host, port, userEmail, emptyPassword);
return store;
}
public static void main(String args[]) throws Exception {
if (args.length != 2) {
System.err.println(
"Usage: OAuth2Authenticator <email> <oauthToken>");
return;
}
String email = args[0];
String oauthToken = args[1];
initialize();
IMAPStore imapStore = connectToImap("imap.gmail.com",
993,
email,
oauthToken,
true);
System.out.println("Successfully authenticated to IMAP.\n");
}
但是,当我运行上面的代码,我得到“空用户名或密码”的一个例外。 有人能告诉我如何使用IMAP与xoauth2访问Gmail? 谢谢。
更新2013年2月20日,下面来调试日志
02-19 17:27:20.098 1905: 1905 I/System.out : setDebug: JavaMail version 1.4.1
02-19 17:27:20.098 1905: 1905 I/System.out : mail.imap.fetchsize: 16384
02-19 17:27:20.106 1905: 1905 I/System.out : enable SASL
02-19 17:27:20.106 1905: 1905 I/System.out : SASL mechanisms allowed: XOAUTH2
02-19 17:27:21.340 1905: 1905 I/System.out : * OK Gimap ready for requests from 36.224.98.49 z8if14713202igb.53
02-19 17:27:21.348 1905: 1905 I/System.out : A0 CAPABILITY
02-19 17:27:21.598 1905: 1905 I/System.out : * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2
02-19 17:27:21.598 1905: 1905 I/System.out : A0 OK Thats all she wrote! z8if14713202igb.53
02-19 17:27:21.614 1905: 1905 I/System.out : IMAP DEBUG: AUTH: XOAUTH
02-19 17:27:21.614 1905: 1905 I/System.out : IMAP DEBUG: AUTH: XOAUTH2
02-19 17:27:21.614 1905: 1905 I/System.out : DEBUG: protocolConnect login, host=imap.gmail.com, user=2104176@gmail.com, password=<non-null>
02-19 17:27:21.622 1905: 1905 I/System.out : IMAP SASL DEBUG: Mechanisms: XOAUTH2
02-19 17:27:21.817 1905: 1905 I/System.out : IMAP SASL DEBUG: Failed to create SASL client: myjavax.security.sasl.SaslException: Cannot instantiate class com.research.oauth.OAuth2SaslClientFactory [Caused by java.lang.InstantiationException: can't instantiate class com.research.oauth.OAuth2SaslClientFactory]
02-19 17:27:21.817 1905: 1905 I/System.out : A1 LOGIN 2104176@gmail.com ""
02-19 17:27:22.036 1905: 1905 I/System.out : A1 NO Empty username or password. z8if14713202igb.53
02-19 17:27:22.044 1905: 1905 D/test : javax.mail.AuthenticationFailedException: Empty username or password. z8if14713202igb.53
我用侑的mail.jar和我的应用程序无法创建SASL客户端:myjavax.security.sasl.SaslException:无法实例类com.research.oauth.OAuth2SaslClientFactory,然后应用程序使用空密码登录的Gmail。 请帮我找出问题,谢谢!
你记住在OAuth2Provider改变你的包叫什么名字? 我忘了,当我在做与该代码的测试。
public static final class OAuth2Provider extends Provider {
private static final long serialVersionUID = 1L;
public OAuth2Provider() {
super("Google OAuth2 Provider", 1.0,
"Provides the XOAUTH2 SASL Mechanism");
put("SaslClientFactory.XOAUTH2",
"com.example.testjavamail.OAuth2SaslClientFactory");
}
}
正如我在另一个答案说,我只测试了连接,但它为我工作。
UPDATE
下面是我使用的代码,它基本上示例代码,真正改变了在Java邮件SASL支持的移植。
public class OAuth2Authenticator {
private static final Logger logger = Logger
.getLogger(OAuth2Authenticator.class.getName());
private static Session mSession;
public static final class OAuth2Provider extends Provider {
private static final long serialVersionUID = 1L;
public OAuth2Provider() {
super("Google OAuth2 Provider", 1.0,
"Provides the XOAUTH2 SASL Mechanism");
put("SaslClientFactory.XOAUTH2",
"com.example.testjavamail.OAuth2SaslClientFactory");
}
}
public static void initialize() {
Security.addProvider(new OAuth2Provider());
}
public static IMAPStore connectToImap(String host, int port,
String userEmail, String oauthToken, boolean debug)
throws Exception {
Properties props = new Properties();
props.put("mail.imaps.sasl.enable", "true");
props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken);
Session session = Session.getInstance(props);
session.setDebug(debug);
final URLName unusedUrlName = null;
IMAPSSLStore store = new IMAPSSLStore(session, unusedUrlName);
final String emptyPassword = "";
store.connect(host, port, userEmail, emptyPassword);
return store;
}
public static SMTPTransport connectToSmtp(String host, int port,
String userEmail, String oauthToken, boolean debug)
throws Exception {
Properties props = new Properties();
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
props.put("mail.smtp.sasl.enable", "true");
props.put("mail.smtp.sasl.mechanisms", "XOAUTH2");
props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken);
mSession = Session.getInstance(props);
mSession.setDebug(debug);
final URLName unusedUrlName = null;
SMTPTransport transport = new SMTPTransport(mSession, unusedUrlName);
// If the password is non-null, SMTP tries to do AUTH LOGIN.
final String emptyPassword = null;
transport.connect(host, port, userEmail, emptyPassword);
return transport;
}
public synchronized void testImap(String user, String oauthToken) {
try {
initialize();
IMAPStore imapStore = connectToImap("imap.gmail.com", 993, user,
oauthToken, true);
} catch (Exception e) {
Log.d("test", e.toString());
}
}
public class ByteArrayDataSource implements DataSource {
private byte[] data;
private String type;
public ByteArrayDataSource(byte[] data, String type) {
super();
this.data = data;
this.type = type;
}
public ByteArrayDataSource(byte[] data) {
super();
this.data = data;
}
public void setType(String type) {
this.type = type;
}
public String getContentType() {
if (type == null)
return "application/octet-stream";
else
return type;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data);
}
public String getName() {
return "ByteArrayDataSource";
}
public OutputStream getOutputStream() throws IOException {
throw new IOException("Not Supported");
}
}
}
下面是从Java邮件调试。 顺便说一句,发布您的调试日志,它应该在undertanding什么错帮助
02-06 10:18:11.805: I/System.out(7434): DEBUG: setDebug: JavaMail version 1.4.1
02-06 10:18:11.905: I/System.out(7434): DEBUG: mail.imap.fetchsize: 16384
02-06 10:18:12.025: I/System.out(7434): DEBUG: enable SASL
02-06 10:18:12.040: I/System.out(7434): DEBUG: SASL mechanisms allowed: XOAUTH2
02-06 10:18:12.600: I/System.out(7434): * OK Gimap ready for requests from 2.233.xxx.xxx 2if1471965eej.3
02-06 10:18:12.605: I/System.out(7434): A0 CAPABILITY
02-06 10:18:12.635: I/System.out(7434): * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2
02-06 10:18:12.635: I/System.out(7434): A0 OK Thats all she wrote! 2if1471965eej.3
02-06 10:18:12.645: I/System.out(7434): IMAP DEBUG: AUTH: XOAUTH
02-06 10:18:12.645: I/System.out(7434): IMAP DEBUG: AUTH: XOAUTH2
02-06 10:18:12.645: I/System.out(7434): DEBUG: protocolConnect login, host=imap.gmail.com, user=xxx@gmail.com, password=<non-null>
02-06 10:18:12.650: I/System.out(7434): IMAP SASL DEBUG: Mechanisms: XOAUTH2
02-06 10:18:12.695: I/System.out(7434): IMAP SASL DEBUG: SASL client XOAUTH2
02-06 10:18:12.695: I/System.out(7434): A1 AUTHENTICATE XOAUTH2
02-06 10:18:12.720: I/System.out(7434): +
02-06 10:18:12.720: I/System.out(7434): IMAP SASL DEBUG: challenge: :
02-06 10:18:12.730: I/System.out(7434): IMAP SASL DEBUG: callback length: 1
02-06 10:18:12.730: I/System.out(7434): IMAP SASL DEBUG: callback 0: myjavax.security.auth.callback.NameCallback@41760f78
02-06 10:18:12.730: I/System.out(7434): IMAP SASL DEBUG: response: user=xxx@gmail.comauth=Bearer ya29.... :
02-06 10:18:12.735: I/System.out(7434): dXNlcj1hbGVhbGVtYXp6b3R0aUBnbWFpbC5jb20BYXV0aD1CZWFyZXIgeWEyOS5BSEVTNlpRYklPeU8xU09sR01WSEo3X2tqVzlVdzNYY1RvODBtQ0hyWFVacjRsYlhIdwEB
02-06 10:18:12.870: I/System.out(7434): * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE
02-06 10:18:12.870: I/System.out(7434): A1 OK xxx@gmail.com My NAME authenticated (Success)
02-06 10:18:12.870: I/System.out(7434): A2 CAPABILITY
02-06 10:18:13.160: I/System.out(7434): * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE
02-06 10:18:13.160: I/System.out(7434): A2 OK Success
我所做的解决同样的问题,重新编译Java邮件包的源,取代javax.security的呼叫在IMAPSaslAuthenticator文件asmack。 在IMAP连接可以顺利通过,
11-29 15:51:46.921: D/11.28(2759): --> the token is ya29.1.
11-29 15:51:46.937: I/System.out(2759): DEBUG: setDebug: JavaMail version ${mail.version}
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: mail.imap.fetchsize: 16384
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: mail.imap.ignorebodystructuresize: false
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: mail.imap.statuscachetimeout: 1000
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: mail.imap.appendbuffersize: -1
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: mail.imap.minidletime: 10
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: enable SASL
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: SASL mechanisms allowed: XOAUTH2
11-29 15:51:46.937: I/System.out(2759): DEBUG IMAPS: trying to connect to host "imap.gmail.com", port 993, isSSL true
11-29 15:51:47.085: D/dalvikvm(2759): GC_CONCURRENT freed 410K, 53% free 8847K/18503K, paused 3ms+6ms, total 38ms
11-29 15:51:47.085: I/System.out(2759): A4 LOGOUT
11-29 15:51:47.093: I/System.out(2759): DEBUG IMAPS: IMAPStore connection dead
11-29 15:51:47.093: I/System.out(2759): DEBUG IMAPS: IMAPStore cleanup, force true
11-29 15:51:47.093: I/System.out(2759): DEBUG IMAPS: IMAPStore cleanup done
11-29 15:51:47.093: D/AbsListView(2759): [unregisterDoubleTapMotionListener]
11-29 15:51:47.093: I/MotionRecognitionManager(2759): .unregisterListener : / listener count = 0->0, listener=android.widget.AbsListView$4@41d9a1b0
11-29 15:51:47.093: I/System.out(2759): A4 LOGOUT
11-29 15:51:47.132: I/System.out(2759): * BYE LOGOUT Requested
11-29 15:51:47.140: I/System.out(2759): A4 OK 73 good day (Success)
11-29 15:51:47.140: I/System.out(2759): DEBUG IMAPS: IMAPStore connection dead
11-29 15:51:47.140: I/System.out(2759): DEBUG IMAPS: IMAPStore cleanup, force false
11-29 15:51:47.140: I/System.out(2759): DEBUG IMAPS: IMAPStore cleanup done
11-29 15:51:47.140: D/AbsListView(2759): [unregisterDoubleTapMotionListener]
11-29 15:51:47.140: I/MotionRecognitionManager(2759): .unregisterListener : / listener count = 0->0, listener=android.widget.AbsListView$4@41de2ba0
11-29 15:51:47.171: I/System.out(2759): * OK Gimap ready for requests from 216.16.246.195 q6if13300240veb.40
11-29 15:51:47.171: I/System.out(2759): A0 CAPABILITY
11-29 15:51:47.218: I/System.out(2759): * 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
11-29 15:51:47.218: I/System.out(2759): A0 OK Thats all she wrote! q6if13300240veb.40
11-29 15:51:47.218: I/System.out(2759): DEBUG IMAPS: AUTH: XOAUTH
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: AUTH: XOAUTH2
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: AUTH: PLAIN
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: AUTH: PLAIN-CLIENTTOKEN
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: protocolConnect login, host=imap.gmail.com, user=xxxx@gmail.com, password=<non-null>
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: SASL authentication command trace suppressed
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: SASL Mechanisms:
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS: XOAUTH2
11-29 15:51:47.226: I/System.out(2759): DEBUG IMAPS:
11-29 15:51:47.233: I/System.out(2759): DEBUG IMAPS: SASL client XOAUTH2
11-29 15:51:47.272: I/System.out(2759): DEBUG IMAPS: SASL challenge: :
11-29 15:51:47.272: I/System.out(2759): DEBUG IMAPS: SASL callback length: 1
11-29 15:51:47.272: I/System.out(2759): DEBUG IMAPS: SASL callback 0: org.apache.harmony.javax.security.auth.callback.NameCallback@41e082c8
11-29 15:51:47.272: I/System.out(2759): DEBUG IMAPS: SASL response: user=xxxx@gmail.comauth=Bearer ya29.1...UhhyFDen9bUwcd5I :
11-29 15:51:48.101: I/System.out(2759): DEBUG IMAPS: SASL authentication succeeded
11-29 15:51:48.101: I/System.out(2759): A2 CAPABILITY
11-29 15:51:48.272: I/System.out(2759): * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
11-29 15:51:48.272: I/System.out(2759): A2 OK Success
11-29 15:51:48.280: I/System.out(2759): A3 NAMESPACE
11-29 15:51:48.452: I/System.out(2759): * NAMESPACE (("" "/")) NIL NIL
11-29 15:51:48.452: I/System.out(2759): A3 OK Success
我下载的软件包
- JavaMail的-1.5.0-SRC
- asmack-Android的8-0.8.9.jar
- 的activation.jar
我没有用的包
- 的mail.jar
- additionnal.jar
这个工作对我来说,如果我运行main方法的testcode,但GlassFish服务器我有其他问题上部署此。 下面从代码http://code.google.com/p/google-mail-oauth2-tools/
下面这个异常被触发,然后,我开始认为这是关系到一个错误或其它问题,但无法找出原因。 是回调需要一些ULR在谷歌API控制台? 或者为什么当在GlassFish中部署它在本地,但无法正常工作。 java.lang.IllegalStateException:WEB9031:WebappClassLoader无法加载资源[com.google.code.samples.oauth2.OAuth2SaslClientFactory],因为它尚未启动,或者已经停止
又看了如果这个错误是与此有关: https://groups.google.com/forum/#!msg/google-appengine/OK3FuIPuA1I/dgov_VRffVgJ