使用带有 accountmanager 令牌的 imap 访问 gmail

Access gmail using imap with accountmanager token(使用带有 accountmanager 令牌的 imap 访问 gmail)

本文介绍了使用带有 accountmanager 令牌的 imap 访问 gmail的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用从 Android 的 AccountManager 收到的令牌而不是使用用户名和密码来实现 IMAP gmail 客户端.

I'm trying to implement a IMAP gmail client using the token received from the Android's AccountManager instead of using username and password.

Google 提供了这个带有 oauth2 的 IMAP 示例 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

Google provides this example of IMAP with 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.
");

}

但是,当我运行上面的代码时,我得到了空用户名或密码"的异常.有人可以告诉我如何使用 imap 和 xoauth2 访问 gmail 吗?谢谢.

But, when I run the code above, I get an exception of "Empty username or password". Could someone tell me how to access gmail using imap with xoauth2? Thanks.

2013/02/20 更新,以下是调试日志

Update 2013/02/20, below comes debug log

 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.请帮我解决问题,谢谢!

I use yor mail.jar and my app Failed to create SASL client: myjavax.security.sasl.SaslException: Cannot instantiate class com.research.oauth.OAuth2SaslClientFactory, then app use Empty password to login gmail. Please help me to figure out the problem, Thank you!

推荐答案

你记得在 OAuth2Provider 中更改了你的包名吗?我在用该代码进行测试时忘记了它.

Did you remeber to change your package name in OAuth2Provider? I forgot it when I was doing tests with that code.

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");
}

}

正如我在另一个答案中所说,我只测试了连接,但它对我有用.

As I said in another answer, I only tested the connection, but it's working for me.

更新

这是我使用的代码,基本上是示例代码,真正改变了 Java Mail 中 SASL 支持的移植.

Here's the code I used, it's basically the example code, what really changed the porting of SASL support in Java Mail.

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 Mail 的调试.顺便说一句,发布您的调试日志,它应该有助于了解发生了什么问题

And here's the debug from Java Mail. Btw, post your debug log, it should help in undertanding what's going wrong

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

这篇关于使用带有 accountmanager 令牌的 imap 访问 gmail的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:使用带有 accountmanager 令牌的 imap 访问 gmail

基础教程推荐