2014-09-15 3 views
0

Я пытался войти в Google Talk, используя библиотеку asmack без успеха. Я действительно не знаю, что происходит за кулисами, просто собрал некоторые фрагменты кода отсюда и там. Это то, что я в настоящее время для андроида деятельности:Невозможно войти в google talk, используя библиотеку asmack для android

public class MainActivity extends Activity {               

    public static final String HOST = "talk.google.com";            
    public static final int PORT = 5222;                
    public static final String SERVICE = "gmail.com";             
    public static final String USER = "[email protected]"; 
    public static final String PASSWORD = "password"; 

    @Override                       
    public void onCreate(Bundle savedInstanceState) {             
     super.onCreate(savedInstanceState);               
     setContentView(R.layout.main);                 
     Context context = getApplicationContext();              
     SmackAndroid asmk = SmackAndroid.init(context);            
     SASLAuthentication.registerSASLMechanism("X-OAUTH2", SASLGoogleOAuth2Mechanism.class);   
     SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0);          
     ConnectionConfiguration connConfig = new ConnectionConfiguration(HOST, PORT, SERVICE);   
     connConfig.setSecurityMode(SecurityMode.enabled);            
     connConfig.setReconnectionAllowed(true);              

     XMPPTCPConnection connection = new XMPPTCPConnection(connConfig);        
     try {                       
      connection.connect();                  
      try {                      
       connection.login(USER, PASSWORD);       
      } catch (XMPPException ex) {                
       Log.w("XMPPChatDemoActivity", "Failed to log in");          
       Log.w("XMPPChatDemoActivity", ex.getMessage());     
      }                       
     } catch (...) {                 
      ... 
     } 
    } 
} 

и это SASLMechanism:

public class SASLGoogleOAuth2Mechanism extends SASLMechanism { 

    private static final Logger log = Logger.getLogger("XMPPChatDemoActivity"); 
    public static final String NAME = "X-OAUTH2"; 

    public SASLGoogleOAuth2Mechanism(SASLAuthentication saslAuthentication) { 
     super(saslAuthentication); 
     log.info("Creating SASL mechanism for GTalk (X-OAUTH2)"); 
    } 

    @Override 
    public void authenticate(String username, String host, String serviceName, String password) throws IOException, SaslException, NotConnectedException { 
     this.authenticationId = username; 
     this.hostname = host; 
     this.password = password; 

     String[] mechanisms = { "PLAIN" }; 
     Map<String, String> props = new HashMap<String, String>(); 
     this.sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this); 
     log.info("sc " + sc); 
     authenticate(); 
    } 

    @Override 
    public void authenticate(String host, CallbackHandler cbh) throws IOException, SaslException, NotConnectedException { 
     String[] mechanisms = { "PLAIN" }; 
     Map<String, String> props = new HashMap<String, String>(); 

     sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh); 
     authenticate(); 
    } 
    @Override 
    protected void authenticate() throws IOException, SaslException, NotConnectedException { 
     String authenticationText = null; 

     try { 
      if (sc.hasInitialResponse()) { 
       byte[] response = sc.evaluateChallenge(new byte[0]); 
       authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES); 
      } 
     } catch (SaslException e) { 
      throw new SaslException("SASL authentication failed", e); 
     } 

     // Send the authentication to the server 
     getSASLAuthentication().send(new GoogleOAuthMechanism(authenticationText)); 
    } 
    @Override 
    protected String getName() { 
     return NAME; 
    } 
    /** 
    * Initiating SASL authentication by select a mechanism. 
    */ 
    public static class GoogleOAuthMechanism extends Packet { 
     private final String authenticationText; 

     /** 
     * Create a GoogleOAuthMechanism. 
     * 
     * @param authenticationText the authentification token 
     * 
     */ 
     public GoogleOAuthMechanism(final String authenticationText) { 
      this.authenticationText = authenticationText; 
     } 

     @Override 
     public String toXML() { 

      StringBuilder stanza = new StringBuilder(); 
      stanza.append("<auth mechanism=\"").append(NAME); 
      stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " 
        + "auth:service=\"oauth2\" " 
        + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\">"); 
      if (authenticationText != null 
        && authenticationText.trim().length() > 0) { 
       stanza.append(authenticationText); 
      } 
      stanza.append("</auth>"); 
      return stanza.toString(); 
     } 
    } 
} 

код нормально и я не получаю исключение, но я получаю ответ <not-authorized> , Имя пользователя и пароль верны. Я не мог найти код ссылки для этой библиотеки. Любая помощь будет оценена.

ответ

0

После того, как вы несколько дней пытались изо всех сил пытаться найти все возможные фрагменты, которые я нашел в Интернете, я нашел решение, которое я рад поделиться с сообществом.

Похоже, что вместо передачи пароля методу XMPPTCPConnection.login() мы должны использовать маркер auth из Google. Я нашел a post, объясняющий способ создания такого токена. A similar question для моего существует, но он использует механизм X-GOOGLE-TOKEN также для аутентификации, что является другим подходом к использованию механизма X-OAUTH2 для аутентификации. Кроме того, все другие сообщения, которые я мог найти, связанные с проблемой аутентификации в google talk, используя OAUTH2, являются старыми. Я использую сборку asmack smack 4.0..

Таким образом, единственное изменение, необходимое для кода, показанного в этом вопросе к работе заключается в следующем:

AccountManager am = AccountManager.get(this); 
Account accounts[] = am.getAccountsByType("com.google"); 
conn.login(USER, amf.blockingGetAuthToken(accounts[0], GOOGLE_TOKEN_TYPE, true)); 

Как вы видите, я использовал учетную запись, хранящуюся на устройство в доказательство решения, но вы можете генерировать токен другими способами, как я уже говорил выше.

Наконец, поскольку я нашел решение методом проб и ошибок, я был бы признателен, если бы кто-нибудь объяснил, что происходит на самом деле, или какая-либо дезинформация, которую я мог бы дать, поэтому этот ответ может быть дополнительно улучшен.

 Смежные вопросы

  • Нет связанных вопросов^_^