IMAP Gmail身份验证:凭据无效

时间:2014-08-21 14:46:27

标签: java android oauth-2.0 javamail imap

我的Android应用必须使用OAAP2通过IMAP访问Gmail,而无需用户密码。 我已经实现了这个例子: https://java.net/projects/javamail/pages/OAuth2 根据需要添加提供程序(首次使用SASL支持时,SASL XOAUTH2提供程序将添加到Java安全配置中)

这是我的代码:

  1. 获取访问令牌

    public void getAndUseAuthTokenBlocking() throws JSONException 
    {           
       String token = "";
       try 
       {
            // Retrieve a token for the given account and scope. It will always return either
            // a non-empty String or throw an exception.
    
        String scope = "oauth2:https://mail.google.com/"; 
        Log.i("Access TOKEN account",accountName);
    
        token = GoogleAuthUtil.getToken(activity.getApplicationContext(), accountName, scope);
    
        // Do work with token.
        URL url = new URL("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token="+ token);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        int serverCode = con.getResponseCode();
    
        if (serverCode == 200)
        {
            access_token = token;
            return;
        //bad token, invalidate and get a new one
        } 
        else if (serverCode == 401)
        {
          // invalidate the token that we found is bad so that GoogleAuthUtil won't
          // return it next time (it may have cached it)
          GoogleAuthUtil.invalidateToken(activity.getApplicationContext(), token);
          // consider retrying getAndUseTokenBlocking() once more
          Log.w("Access TOKEN","INVALIDATO");   
          getAndUseAuthTokenBlocking();
        }
        else 
        {
            Log.e("SERVER CODE","Server returned the following error code: " + serverCode);
            return;
        }
    
        return;
     } 
     catch (GooglePlayServicesAvailabilityException playEx) 
     {
     Dialog alert = GooglePlayServicesUtil.getErrorDialog(
         playEx.getConnectionStatusCode(),
         activity,1);
     } 
     catch (UserRecoverableAuthException userAuthEx) 
     {
      // Start the user recoverable action using the intent returned by
      // getIntent()
      activity.startActivityForResult(
              userAuthEx.getIntent(),
              1);
      return;
     } 
     catch (IOException ioEx) 
     {
      // network or server error, the call is expected to succeed if you try again later.
      // Don't attempt to call again immediately - the request is likely to
      // fail, you'll hit quotas or back-off.
    
       Log.e("IOException", "transient error encountered: " + ioEx.getMessage());
      return;
     } 
     catch (GoogleAuthException authEx) 
     {
      // Failure. The call is not expected to ever succeed so it should not be
      // retried.
       Log.e("GoogleAuthException", "Unrecoverable authentication exception: " + authEx.getMessage(), authEx);
      return;
     }
    } 
    
  2. 创建提供者(OAuthFactory e OAuthClient类取自https://code.google.com/p/google-mail-oauth2-tools/source/browse/trunk/java/#java%2Fcom%2Fgoogle%2Fcode%2Fsamples%2Foauth2

    public static final class OAuthProvider extends Provider {
    private static final long serialVersionUID = 1L;
    
    public OAuthProvider() {
        super("Google OAuth2 Provider", 1.0,
              "Provides the XOAUTH2 SASL Mechanism");
        String className = OAuthFactory.class.getName();
        put("SaslClientFactory.XOAUTH2", className);
      }
    }
    
  3. IMAP连接

    protected String doInBackground(String... params)
    {
    Log.i("account",accountName);
    
    try {
        getAndUseAuthTokenBlocking();
    } catch (JSONException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    
    Log.i("access token",access_token);       
    
    initialize();
    
    Properties props = new Properties();
    props.put("mail.imap.ssl.enable", "true"); // required for Gmail
    props.put("mail.imap.sasl.enable", "true");
    props.put("mail.imap.sasl.mechanisms", "XOAUTH2");
    props.put("mail.imap.auth.login.disable", "true");
    props.put("mail.imap.auth.plain.disable", "true");
    Session session = Session.getInstance(props);
    
    session.setDebug(true);
    
    Store store;
    
    try {
        store = session.getStore("imaps");
         store.connect("imap.gmail.com", accountName, access_token);        
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (MessagingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    return null;
    }
    
  4. 但此代码提供了 [AUTHENTICATIONFAILED]无效凭据(失败)错误

    08-21 16:14:43.100: I/System.out(7346): DEBUG: setDebug: JavaMail version 1.5.2
    08-21 16:14:43.100: I/System.out(7346): DEBUG: getProvider() returning javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle,1.5.2]
    08-21 16:14:43.100: W/dalvikvm(7346): method Lcom/sun/mail/imap/IMAPStore;.getSession incorrectly overrides package-private method with same name in Ljavax/mail/Service;
    08-21 16:14:43.104: I/System.out(7346): DEBUG IMAPS: mail.imap.fetchsize: 16384
    08-21 16:14:43.104: I/System.out(7346): DEBUG IMAPS: mail.imap.ignorebodystructuresize: false
    08-21 16:14:43.104: I/System.out(7346): DEBUG IMAPS: mail.imap.statuscachetimeout: 1000
    08-21 16:14:43.104: I/System.out(7346): DEBUG IMAPS: mail.imap.appendbuffersize: -1
    08-21 16:14:43.104: I/System.out(7346): DEBUG IMAPS: mail.imap.minidletime: 10
    08-21 16:14:43.108: I/System.out(7346): DEBUG IMAPS: trying to connect to host "imap.gmail.com", port 993, isSSL true
    08-21 16:14:48.408: I/System.out(7346): * OK Gimap ready for requests from 82.57.18.250 z47mb29911677eep
    08-21 16:14:48.408: I/System.out(7346): A0 CAPABILITY
    08-21 16:14:48.468: I/System.out(7346): * 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
    08-21 16:14:48.468: I/System.out(7346): A0 OK Thats all she wrote! z47mb29911677eep
    08-21 16:14:48.468: I/System.out(7346): DEBUG IMAPS: AUTH: XOAUTH
    08-21 16:14:48.468: I/System.out(7346): DEBUG IMAPS: AUTH: XOAUTH2
    08-21 16:14:48.468: I/System.out(7346): DEBUG IMAPS: AUTH: PLAIN
    08-21 16:14:48.468: I/System.out(7346): DEBUG IMAPS: AUTH: PLAIN-CLIENTTOKEN
    08-21 16:14:48.472: I/System.out(7346): DEBUG IMAPS: protocolConnect login, host=imap.gmail.com, user=myemail@gmail.com, password=<non-null>
    08-21 16:14:48.472: I/System.out(7346): DEBUG IMAPS: AUTHENTICATE PLAIN command trace suppressed
    08-21 16:14:49.488: I/System.out(7346): DEBUG IMAPS: AUTHENTICATE PLAIN command result: A1 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
    08-21 16:14:49.488: W/System.err(7346): javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
    08-21 16:14:49.492: W/System.err(7346):     at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:715)
    08-21 16:14:49.492: W/System.err(7346):     at javax.mail.Service.connect(Service.java:364)
    08-21 16:14:49.492: W/System.err(7346):     at javax.mail.Service.connect(Service.java:245)
    08-21 16:14:49.492: W/System.err(7346):     at com.example.tickets.Reader2.doInBackground(Reader2.java:113)
    08-21 16:14:49.492: W/System.err(7346):     at com.example.tickets.Reader2.doInBackground(Reader2.java:1)
    08-21 16:14:49.492: W/System.err(7346):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
    08-21 16:14:49.492: W/System.err(7346):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
    08-21 16:14:49.492: W/System.err(7346):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    08-21 16:14:49.492: W/System.err(7346):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    08-21 16:14:49.500: W/System.err(7346):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    08-21 16:14:49.500: W/System.err(7346):     at java.lang.Thread.run(Thread.java:841)
    

    我不明白问题是IMAP连接还是访问令牌;为了获取访问令牌,我也尝试了oauth.py,但结果是一样的。

    感谢您的回复。

1 个答案:

答案 0 :(得分:0)

enter image description here

您可能需要跟随图片,输入您的gmail帐户设置