1

我试图为在 OAuth 身份验证后访问用户邮件的应用程序创建模型。我打算使用以下代码片段检索邮件基于此处的示例:http ://code.google.com/p/google-mail-oauth2-tools/source/browse/trunk/java/com/google/code /samples/oauth2/OAuth2Authenticator.java

/**
 * Performs OAuth2 authentication.
 *
 * <p>Before using this class, you must call {@code initialize} to install the
 * OAuth2 SASL provider.
 */
public class OAuth2Authenticator {
  private static final Logger logger =
      Logger.getLogger(OAuth2Authenticator.class.getName());

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

  /**
   * Installs the OAuth2 SASL provider. This must be called exactly once before
   * calling other methods on this class.
   */
  public static void initialize() {
    Security.addProvider(new OAuth2Provider());
  }

  /**
   * Connects and authenticates to an IMAP server with OAuth2. You must have
   * called {@code initialize}.
   *
   * @param host Hostname of the imap server, for example {@code
   *     imap.googlemail.com}.
   * @param port Port of the imap server, for example 993.
   * @param userEmail Email address of the user to authenticate, for example
   *     {@code oauth@gmail.com}.
   * @param oauthToken The user's OAuth token.
   * @param debug Whether to enable debug logging on the IMAP connection.
   *
   * @return An authenticated IMAPStore that can be used for IMAP operations.
   */
  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;
  }

  /**
   * Connects and authenticates to an SMTP server with OAuth2. You must have
   * called {@code initialize}.
   *
   * @param host Hostname of the smtp server, for example {@code
   *     smtp.googlemail.com}.
   * @param port Port of the smtp server, for example 587.
   * @param userEmail Email address of the user to authenticate, for example
   *     {@code oauth@gmail.com}.
   * @param oauthToken The user's OAuth token.
   * @param debug Whether to enable debug logging on the connection.
   *
   * @return An authenticated SMTPTransport that can be used for SMTP
   *     operations.
   */
  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);
    Session session = Session.getInstance(props);
    session.setDebug(debug);

    final URLName unusedUrlName = null;
    SMTPTransport transport = new SMTPTransport(session, unusedUrlName);
    // If the password is non-null, SMTP tries to do AUTH LOGIN.
    final String emptyPassword = "";
    transport.connect(host, port, userEmail, emptyPassword);

    return transport;
  }

  /**
   * Authenticates to IMAP with parameters passed in on the commandline.
   */
  public static void main(String args[]) throws Exception {
    /*if (args.length != 2) {
      System.err.println(
          "Usage: OAuth2Authenticator <email> <oauthToken>");
      return;
    }*/
    String email = "myusername@gmail.com";//hard coded 
    String oauthToken = "4/ipdG328T75Z1RO-oU1ZpVx07-UY-.Mv7XkFpsg9USEnp6UAPFm0EIgurXgQI";// hard coded

    initialize();

    IMAPStore imapStore = connectToImap("imap.gmail.com",
                                        993,
                                        email,
                                        oauthToken,
                                        true);
    System.out.println("Successfully authenticated to IMAP.\n");
    SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com",
                                                587,
                                                email,
                                                oauthToken,
                                                true);
    System.out.println("Successfully authenticated to SMTP.");
  }

我试图使用类似于此页面 http://ocpsoft.org/java/setting-up-google-oauth2-with-java/ 的网页来获取 OAuth 令牌,方法是显式打印出

request.getParameter("code")//value used for OAuth token in above code 

这应该是 OAuth 令牌。

但是当我尝试运行上述程序时,我收到一条错误消息Invalid Credentials

这是详细的堆栈跟踪:

    DEBUG: setDebug: JavaMail version 1.5.0
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: enable SASL
DEBUG: SASL mechanisms allowed: XOAUTH2
DEBUG: trying to connect to host "imap.gmail.com", port 993, isSSL true
* OK Gimap ready for requests from 174.26.139.84 av9if2076257pac.214
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! av9if2076257pac.214
DEBUG IMAP: AUTH: XOAUTH
DEBUG IMAP: AUTH: XOAUTH2
DEBUG IMAP: AUTH: PLAIN
DEBUG IMAP: AUTH: PLAIN-CLIENTTOKEN
DEBUG: protocolConnect login, host=imap.gmail.com, user=vivekmahadevan.v@gmail.com, password=<non-null>
IMAP SASL DEBUG: Mechanisms: XOAUTH2
IMAP SASL DEBUG: SASL client XOAUTH2
A1 AUTHENTICATE XOAUTH2
+ 
IMAP SASL DEBUG: challenge:  :
IMAP SASL DEBUG: callback length: 1
IMAP SASL DEBUG: callback 0: javax.security.auth.callback.NameCallback@57799932
IMAP SASL DEBUG: response: user=vivekmahadevan.v@gmail.comauth=Bearer 4/ipdG328T75Z1RO-oU1ZpVx07-UY-.Mv7XkFpsg9USEnp6UAPFm0EIgurXgQI :
dXNlcj12aXZla21haGFkZXZhbi52QGdtYWlsLmNvbQFhdXRoPUJlYXJlciA0L2lwZEczMjhUNzVaMVJPLW9VMVpwVngwNy1VWS0uTXY3WGtGcHNnOVVTRW5wNlVBUEZtMEVJZ3VyWGdRSQEB
+ eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==
IMAP SASL DEBUG: no response

A1 NO [ALERT] Invalid credentials (Failure)
Exception in thread "main" javax.mail.AuthenticationFailedException: [ALERT] Invalid credentials (Failure)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:660)
    at javax.mail.Service.connect(Service.java:345)
    at com.test.OAuth2Authenticator.connectToImap(OAuth2Authenticator.java:73)
    at com.test.OAuth2Authenticator.main(OAuth2Authenticator.java:129)

任何见解将不胜感激。谢谢!

4

1 回答 1

2

您要返回的内容(身份验证码)必须与谷歌交换以获得访问令牌。
在您开始的同一个项目中,oauth2.py 是获取令牌进行测试的最简单方法。如果你想在 java 中进行令牌交换,你可以从这个库开始: http ://code.google.com/p/google-oauth-java-client/

final GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(CALLBACK_URI).execute();

String accessToken = response.getAccessToken();

这有点恶心。但它有效。

于 2013-11-07T17:09:55.170 回答