Autore Topic: Gmail IMAP/SMPT con token OAuth da AccessManager  (Letto 1445 volte)

Offline monossido

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus S
  • Play Store ID:
    Lorenzo Braghetto
  • Sistema operativo:
    Gnu/Linux
Gmail IMAP/SMPT con token OAuth da AccessManager
« il: 04 Ottobre 2012, 10:32:47 CEST »
0
Ciao a tutti

Sto cercando di implementare un semplice client IMAP e SMTP interno alla mia applicazione che si connetta a gmail utilizzando il token ricevuto da AccountManager.getAuthToken(). Passandogli come parametro l'AUTH_TOKEN_TYPE = mail dovrebbe restituire infatti un token utile per effettuare l'autenticazione via OAuth2 https://developers.google.com/google-apps/gmail/oauth_overview

Google mette a disposizione questi esempi per utilizzare OAuth2 e IMAP/SMTP con java
JavaSampleCode -
 google-mail-oauth2-tools -
 
 Java sample code -
 Google Mail OAuth2 Tools - Google Project Hosting
 


riportati quasi pari pari dentro la mia applicazione android alcune classi relative a SASL non erano disponibili, così cercando ho trovato questo progetto

 asmack -
 
 
 Android build environment and patches for smack - Google Project Hosting
 

che mi ha fornito le giuste classi per compilare l'esempio di google

l'unico problema sembra che asmack utilizzi le classi org.apache.harmony.javax.security.* invece che javax.security.* come ci si aspettarebbe da java liscio, nei log infatti vedo:

Codice: [Seleziona]
10-04 10:05:44.715: I/System.out(1226): DEBUG: setDebug: JavaMail version 1.4.1
10-04 10:05:44.750: I/System.out(1226): DEBUG: mail.imap.fetchsize: 16384
10-04 10:05:44.750: I/System.out(1226): DEBUG: enable SASL
10-04 10:05:44.750: I/System.out(1226): DEBUG: SASL mechanisms allowed: XOAUTH2
10-04 10:05:46.137: I/System.out(1226): * OK Gimap ready for requests from 84.221.66.29 o42if871216eef.60
10-04 10:05:46.137: I/System.out(1226): A0 CAPABILITY
10-04 10:05:46.805: I/System.out(1226): * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2
10-04 10:05:46.805: I/System.out(1226): A0 OK Thats all she wrote! o42if871216eef.60
10-04 10:05:46.805: I/System.out(1226): IMAP DEBUG: AUTH: XOAUTH
10-04 10:05:46.805: I/System.out(1226): IMAP DEBUG: AUTH: XOAUTH2
10-04 10:05:46.813: I/System.out(1226): DEBUG: protocolConnect login, host=imap.gmail.com, user=xxx.xxx@gmail.com, password=<non-null>
10-04 10:05:46.813: I/dalvikvm(1226): Could not find method javax.security.sasl.Sasl.createSaslClient, referenced from method com.sun.mail.imap.protocol.IMAPSaslAuthenticator.authenticate
10-04 10:05:46.813: W/dalvikvm(1226): VFY: unable to resolve static method 44358: Ljavax/security/sasl/Sasl;.createSaslClient ([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljavax/security/auth/callback/CallbackHandler;)Ljavax/security/sasl/SaslClient;
10-04 10:05:46.813: D/dalvikvm(1226): VFY: replacing opcode 0x77 at 0x0050
10-04 10:05:46.813: W/dalvikvm(1226): VFY: unable to resolve exception class 5975 (Ljavax/security/sasl/SaslException;)
10-04 10:05:46.813: W/dalvikvm(1226): VFY: unable to find exception handler at addr 0x83
10-04 10:05:46.844: W/dalvikvm(1226): VFY:  rejected Lcom/sun/mail/imap/protocol/IMAPSaslAuthenticator;.authenticate ([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
10-04 10:05:46.844: W/dalvikvm(1226): VFY:  rejecting opcode 0x0d at 0x0083
10-04 10:05:46.844: W/dalvikvm(1226): VFY:  rejected Lcom/sun/mail/imap/protocol/IMAPSaslAuthenticator;.authenticate ([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
10-04 10:05:46.844: W/dalvikvm(1226): Verifier rejected class Lcom/sun/mail/imap/protocol/IMAPSaslAuthenticator;
10-04 10:05:46.844: I/System.out(1226): IMAP DEBUG: Can't load SASL authenticator: java.lang.ClassNotFoundException: com.sun.mail.imap.protocol.IMAPSaslAuthenticator
10-04 10:05:46.844: I/System.out(1226): A1 LOGIN xxx.xxx@gmail.com anonymous
10-04 10:05:48.137: I/System.out(1226): A1 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
10-04 10:05:48.164: W/System.err(1226): javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
10-04 10:05:48.176: W/System.err(1226):         at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:566)
10-04 10:05:48.176: W/System.err(1226):         at javax.mail.Service.connect(Service.java:288)
10-04 10:05:48.176: W/System.err(1226):         at xxx.xxx.xxx.OAuth2Authenticator.connectToImap(OAuth2Authenticator.java:111)
10-04 10:05:48.180: W/System.err(1226):         at xxx.xxx.xxx.OAuth2Authenticator.initialize(OAuth2Authenticator.java:60)
10-04 10:05:48.180: W/System.err(1226):         at xxx.xxx.xxx.TR_Incoming.onTimeout(TR_Incoming.java:106)
10-04 10:05:48.180: W/System.err(1226):         at xxx.xxx.xxx.AlarmThread$1.handleMessage(AlarmThread.java:80)
10-04 10:05:48.180: W/System.err(1226):         at android.os.Handler.dispatchMessage(Handler.java:99)
10-04 10:05:48.180: W/System.err(1226):         at android.os.Looper.loop(Looper.java:137)
10-04 10:05:48.180: W/System.err(1226):         at xxx.xxx.xxx.AlarmThread.run(AlarmThread.java:94)

(ho editato package e user)

sembra proprio che il sistema vada alla ricerca di javax.security.sasl.Sasl.createSaslClient invece che del mio createSaslClient preso dall'esempio Google

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Gmail IMAP/SMPT con token OAuth da AccessManager
« Risposta #1 il: 04 Ottobre 2012, 10:51:01 CEST »
0
Non sono esperto in materia, ma secondo me il problema fondamentale è che Android non è 100% compatibile con Java (mancano package e ci sono differenze in alcuni package comuni). Per questo motivo, secondo me il problema non è in asmack, ma nel "Java sample code", devi infatti cercare un "Android sample code".

In aggiunta a questo, ti riporto anche un link che magari ti può essere d'aiuto per altro https://github.com/koterpillar/android-sasl
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline monossido

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus S
  • Play Store ID:
    Lorenzo Braghetto
  • Sistema operativo:
    Gnu/Linux
Re:Gmail IMAP/SMPT con token OAuth da AccessManager
« Risposta #2 il: 04 Ottobre 2012, 10:55:23 CEST »
0
Infatti è probabile, ma l'argomento mi pare poco trattato e per ora non ho trovato molto.

Se guardi il post nel blog dell'autore della libreria che hai linkato te praticamente dice che è meglio o comunque va bene usare asmack

Offline crummosh

  • Nuovo arrivato
  • *
  • Post: 2
  • Respect: 0
    • Mostra profilo
Re:Gmail IMAP/SMPT con token OAuth da AccessManager
« Risposta #3 il: 12 Ottobre 2012, 14:04:45 CEST »
0
Ciao, sono riuscito ad usare SMTP senza usare asmak, disabilitando SASL e dando direttamente il comado AUTH XOAUTH2 + user + token

Così

Codice: [Seleziona]
public 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", "false");
               
                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 = null;
                transport.connect(host, port, userEmail, emptyPassword);
                byte[] response = String.format("user=%s\1auth=Bearer %s\1\1", userEmail,
                oauthToken).getBytes();
                response = BASE64EncoderStream.encode(response);
                transport.issueCommand("AUTH XOAUTH2 " + new String(response),
                235);
               
                return transport;
        }

Il token Oauth2 lo prendo dall'accountmanager dandogli come scope "oauth2:https://mail.google.com/"

Riesco a spedire mail senza problemi. Hai idea di come mandare comandi IMAP come ho fatto per SMTP? (transport.issueCommand("AUTH XOAUTH2 " + new String(response),235) ; ) Se lo sai fammi sapere che mi interessa.

Edit: occhio che final String emptyPassword = null; deve proprio essere null e non una stringa vuota come nell'esempio originale
Ciao

Offline crummosh

  • Nuovo arrivato
  • *
  • Post: 2
  • Respect: 0
    • Mostra profilo
Re:Gmail IMAP/SMPT con token OAuth da AccessManager
« Risposta #4 il: 12 Ottobre 2012, 16:09:02 CEST »
0
Mhh, mi sa che per IMAP c'è poco da fare. Si potrebbe provare a ricompilare JavaMail for Android usando asmak e cambiando gli import in IMAPSaslAuthenticator da

import javax.security.sasl.*;
import javax.security.auth.callback.*;

a

import org.apache.harmony.javax.security.sasl.*;
import org.apache.harmony.javax.security.auth.callback.*;

però boh.