2011-09-09 32 views
8

Câu hỏi này cũng tương tự như: Authenticate to Google Talk (XMPP, Smack) using an authTokenCách xác thực với Google Talk bằng mã xác thực của AccountManager bằng API Smack?

  1. Tôi có lớp android.accounts.AccountManager và phương pháp của nó để nhận mã thông báo xác thực cho tài khoản Google:

    public AccountManagerFuture<Bundle> getAuthToken (Account account, 
         String authTokenType, Bundle options, Activity activity, 
         AccountManagerCallback<Bundle> callback, Handler handler) 
    
  2. tôi biết làm thế nào để chuẩn bị xác thực XML :

    jidAndToken ="\0" + UTF8([email protected]) + "\0" + Auth 
    

    (trong đó "\ 0" được dự định là một octet có giá trị bằng 0). Sử dụng điều này trong auth SASL ban đầu:

    <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' 
         mechanism='X-GOOGLE-TOKEN'>Base64(jidAndToken)</auth> 
    


Nhưng tôi thất bại trong việc tích hợp nó với Smack API như ai đó đã làm cho facebook trò chuyện ở đây: XMPP with Java Asmack library supporting X-FACEBOOK-PLATFORM

Ai đó có thể giúp tôi?

+0

Tôi đã xem xét điều này trước đây, nhưng chưa bao giờ thực sự thử nó. Bạn có nhớ đăng mã của bạn để tôi có thể cố gắng làm điều đó bản thân mình và có lẽ tôi sẽ tìm một giải pháp. Cảm ơn – Guillaume

Trả lời

1

Tôi biết chủ đề này hơi cũ, nhưng tôi nghĩ tôi sẽ giúp ... Đây là lớp học của tôi dường như làm việc với smack kết nối với Gtalk bằng cách sử dụng cơ chế mã thông báo. trung thực, tôi muốn đi với oauth2 .. nhưng điều này dường như làm việc ok. Chắc chắn xem tên của bạn là như và nó cũng làm việc:

public class GoogleTalkAuthentication extends SASLMechanism 
{ 
    static 
    { 
     SASLAuthentication.registerSASLMechanism("X-GOOGLE-TOKEN", GoogleTalkAuthentication.class); 
     SASLAuthentication.supportSASLMechanism("X-GOOGLE-TOKEN", 0); 
    } 

    public GoogleTalkAuthentication(SASLAuthentication saslAuthentication) 
    { 
     super(saslAuthentication); 
    } 

    @Override 
    protected String getName() 
    { 
     return "X-GOOGLE-TOKEN"; 
    } 

    @Override 
    public void authenticate(String username, String host, String password) throws IOException, XMPPException 
    { 
     super.authenticate(username, host, password); 
    } 

    @Override 
    protected void authenticate() throws IOException, XMPPException 
    { 
     String authCode = getAuthCode(authenticationId, password); 
     String jidAndToken = "\0" + URLEncoder.encode(authenticationId, "utf-8") + "\0" + authCode; 

     StringBuilder stanza = new StringBuilder(); 
     stanza.append("<auth mechanism=\"").append(getName()); 
     stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 
     stanza.append(Base64.encode(jidAndToken.getBytes("UTF-8"))); 

     stanza.append("</auth>"); 

     // Send the authentication to the server 
     getSASLAuthentication().send(stanza.toString()); 
    } 

    public static String getAuthCode(String username, String password) throws IOException 
    { 
     StringBuilder urlToRead = new StringBuilder(); 
     urlToRead.append("https://www.google.com/accounts/ClientLogin?accountType=GOOGLE&service=mail&"); 
     urlToRead.append("Email=" + username + "&"); 
     urlToRead.append("Passwd=" + password); 

     URL url = new URL(urlToRead.toString()); 
     HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
     conn.setRequestMethod("GET"); 

     BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 

     try 
     { 
      String line; 
      while ((line = rd.readLine()) != null) 
      { 
       if (line.startsWith("Auth=")) 
        return line.substring(5); 
      } 

      return null; 
     } 
     finally 
     { 
      rd.close(); 
     } 
    } 

    public static void main(String[] args) throws IOException 
    { 
     String username = ""; 
     String password = ""; 

     String authCode = getAuthCode(username, password); 
     String jidAndToken = "\0" + URLEncoder.encode(username, "utf-8") + "\0" + authCode; 

     System.err.println(authCode); 
     System.err.println("Code:" + jidAndToken); 
    } 
} 

Chúc may mắn.

8

Vijay,

Mã của bạn đã giúp tôi rất nhiều! Tôi đăng bài ở đây để cung cấp giải pháp cho vấn đề sử dụng AccountManager để đăng nhập vào Google talk. Cho đến nay tôi đã không tìm thấy một giải pháp đầy đủ trên mạng, nhưng tôi đã phát triển mỏ dựa trên mã trên và sửa một vài dòng không hoạt động.

Có hai phần của giải pháp. Việc đầu tiên được dựa trên ý tưởng và mã trên. Đó là tạo một lớp con của SASLMechanism:

import java.io.IOException; 
import java.net.URLEncoder; 

import org.jivesoftware.smack.SASLAuthentication; 
import org.jivesoftware.smack.XMPPException; 
import org.jivesoftware.smack.packet.Packet; 
import org.jivesoftware.smack.sasl.SASLMechanism; 

import android.util.Base64; 
import android.util.Log; 

public class GTalkOAuth2 extends SASLMechanism { 
public static final String NAME="X-GOOGLE-TOKEN"; 


public GTalkOAuth2(SASLAuthentication saslAuthentication) { 
    super(saslAuthentication); 
} 

@Override 
protected String getName() { 
    return NAME; 
} 

static void enable() { } 

@Override 
protected void authenticate() throws IOException, XMPPException 
{ 
    String authCode = password; 
    String jidAndToken = "\0" + URLEncoder.encode(authenticationId, "utf-8") + "\0" + authCode; 

    StringBuilder stanza = new StringBuilder(); 
    stanza.append("<auth mechanism=\"").append(getName()); 
    stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 
    stanza.append(new String(Base64.encode(jidAndToken.getBytes("UTF-8"), Base64.DEFAULT))); 

    stanza.append("</auth>"); 

    Log.v("BlueTalk", "Authentication text is "+stanza); 
    // Send the authentication to the server 
    getSASLAuthentication().send(new Auth2Mechanism(stanza.toString())); 
} 

public class Auth2Mechanism extends Packet { 
    String stanza; 
    public Auth2Mechanism(String txt) { 
     stanza = txt; 
    } 
    public String toXML() { 
     return stanza; 
    } 
} 

/** 
* Initiating SASL authentication by select a mechanism. 
*/ 
public class AuthMechanism extends Packet { 
    final private String name; 
    final private String authenticationText; 

    public AuthMechanism(String name, String authenticationText) { 
     if (name == null) { 
      throw new NullPointerException("SASL mechanism name shouldn't be null."); 
     } 
     this.name = name; 
     this.authenticationText = authenticationText; 
    } 

    public String toXML() { 
     StringBuilder stanza = new StringBuilder(); 
     stanza.append("<auth mechanism=\"").append(name); 
     stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 
     if (authenticationText != null && 
       authenticationText.trim().length() > 0) { 
      stanza.append(authenticationText); 
     } 
     stanza.append("</auth>"); 
     return stanza.toString(); 
    } 
    } 
} 

Phần thứ hai là việc sử dụng nó. Điều quan trọng mà không có ví dụ nào khác cho tôi là khi nhận được mã thông báo từ hệ thống AccountManager, loại mã thông báo không phải là "ah" nhưng "thư". Ý tưởng được đưa ra ở đó trong các ví dụ thực hiện giao tiếp trực tiếp với các máy chủ của Google để nhận mã thông báo nhưng không yêu cầu nó từ Trình quản lý tài khoản. Đặt chúng lại với nhau cho rằng bạn cần phải làm như sau trong mã trình điều khiển của bạn. Tạo một chức năng để có mã thông báo:

public String getAuthToken(String name) 
{ 
    Context context = getApplicationContext(); 
    Activity activity = this; 
    String retVal = ""; 
    Account account = new Account(name, "com.google"); 
    AccountManagerFuture<Bundle> accFut = AccountManager.get(context).getAuthToken(account, "mail", null, activity, null, null); 
    try 
    { 
     Bundle authTokenBundle = accFut.getResult(); 
     retVal = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString(); 
    } 
    catch (OperationCanceledException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    catch (AuthenticatorException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return retVal; 
} 

Và sau đó gọi nó là sau khi đảm bảo các hệ thống SASL đúng sẽ được sử dụng:

SASLAuthentication.registerSASLMechanism(GTalkOAuth2.NAME, GTalkOAuth2.class); 
SASLAuthentication.supportSASLMechanism(GTalkOAuth2.NAME, 0); 
config.setSASLAuthenticationEnabled(true); 

String saslAuthString = getAuthToken(acct.name); 
connection = new XMPPConnection(config); 
try { 
    connection.connect(); 
    connection.login(name, saslAuthString); 
} catch (XMPPException e) { 
    // Most likely an expired token 
    // Invalidate the token and start over. There are example of this available 
} 

Chúc mừng Google Talking!

+0

Tôi đang sử dụng mã này nhưng không thành công để giải quyết vấn đề của mình. tôi vẫn không nhận được phản hồi từ máy chủ. –

Các vấn đề liên quan