2011-12-16 80 views
3

我嘗試過所有的事情來連接Facebook與XMPP,但我只面臨 一個錯誤始終是:
SASL身份驗證失敗使用機制DIGEST-MD5
我是執行下面的方法來執行此任務:連接到Facebook的問題XMMP MD5-DIGEST

public class MySASLDigestMD5Mechanism extends SASLMechanism { 

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

protected void authenticate() throws IOException, XMPPException { 
    String[] mechanisms = { getName() }; 
    Map<String, String> props = new HashMap<String, String>(); 
    sc = Sasl.createSaslClient(mechanisms, null, "xmpp", hostname, props, this); 

    super.authenticate(); 
} 

public void authenticate(String username, String host, String password) throws IOException, XMPPException { 
    this.authenticationId = username; 
    this.password = password; 
    this.hostname = host; 

    String[] mechanisms = { getName() }; 
    Map<String,String> props = new HashMap<String,String>(); 
    sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this); 
    super.authenticate(); 
} 

public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException { 
    String[] mechanisms = { getName() }; 
    Map<String,String> props = new HashMap<String,String>(); 
    sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, (org.apache.harmony.javax.security.auth.callback.CallbackHandler) cbh); 
    super.authenticate(); 
} 

protected String getName() { 
    return "DIGEST-MD5"; 
} 

/*public void challengeReceived1(String challenge) throws IOException { 
    // Build the challenge response stanza encoding the response text 
    StringBuilder stanza = new StringBuilder(); 

    byte response[]; 
    if (challenge != null) { 
     response = sc.evaluateChallenge(Base64.decode(challenge)); 
    } else { 
     response = sc.evaluateChallenge(null); 
    } 

    String authenticationText=""; 

    if (response != null) { // fix from 3.1.1 
     authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES); 
     if (authenticationText.equals("")) { 
      authenticationText = "="; 
     } 
    } 

    stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 
    stanza.append(authenticationText); 
    stanza.append("</response>"); 

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

public void challengeReceived(String challenge) 
throws IOException { 

byte response[]; 

if (challenge != null) { 
    response = sc.evaluateChallenge(Base64.decode(challenge)); 
} else { 
    response = sc.evaluateChallenge(new byte[0]); 
} 

Packet responseStanza; 

if (response == null) { 
    responseStanza = new Response(); 
} else { 
    responseStanza = new Response(Base64.encodeBytes(response, Base64.DONT_BREAK_LINES)); 
} 

getSASLAuthentication().send(responseStanza); 

} 

} 

和連接功能是:

 try{ 
     SASLAuthentication.registerSASLMechanism("DIGEST-MD5",MySASLDigestMD5Mechanism. class); 

     ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222); 



     config.setSASLAuthenticationEnabled(true); 

     config.setRosterLoadedAtLogin (true); 



     connection = new XMPPConnection(config); 

     connection.connect(); 
     Log.d("Connect...", "Afetr Connect"); 
     connection.login("[email protected]", "password"); 
     Log.d("done","XMPP client logged in"); 
    } 
    catch(XMPPException ex) 
    { 
     Log.d("not done","in catchhhhhhhhh"); 
     System.out.println(ex.getMessage()); 
     connection.disconnect(); 
    } 

} 
but "After connect" it gone to the ctach and give me error like : 

    SASL authentication failed using mechanism DIGEST-MD5 

我找遍了所有的博客,並發現同樣的事情,但我不知道我是什麼我做錯了..

如果有任何其他方式或解決方案與Facebook的XMPP,請您幫助我儘快

+0

同樣的問題在這裏..請幫助任何一個 – 2011-12-19 06:31:58

回答

5

最後,感謝no.good.at.coding代碼和harism的建議,我已經能夠連接到Facebook聊天。此代碼是Asmack庫(Android的Smack端口)的機制。對於Smack庫來說,使用no.good.at.coding機制是必要的。

SASLXFacebookPlatformMechanism.java:

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.net.URLEncoder; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.GregorianCalendar; 
import java.util.HashMap; 
import java.util.Map; 
import org.apache.harmony.javax.security.auth.callback.CallbackHandler; 
import org.apache.harmony.javax.security.sasl.Sasl; 
import org.jivesoftware.smack.SASLAuthentication; 
import org.jivesoftware.smack.XMPPException; 
import org.jivesoftware.smack.sasl.SASLMechanism; 
import org.jivesoftware.smack.util.Base64; 

public class SASLXFacebookPlatformMechanism extends SASLMechanism 
{  
    private static final String NAME    = "X-FACEBOOK-PLATFORM";  
    private String    apiKey   = "";  
    private String    applicationSecret = "";  
    private String    sessionKey  = "";  
    /**  * Constructor.  */  
    public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)  
    {   
     super(saslAuthentication);  
    }  
    @Override  
    protected void authenticate() throws IOException, XMPPException  
    {   
     getSASLAuthentication().send(new AuthMechanism(NAME, ""));  
    }  
    @Override  
    public void authenticate(String apiKeyAndSessionKey, String host,    String applicationSecret) throws IOException, XMPPException  
    {   
     if (apiKeyAndSessionKey == null || applicationSecret == null)   
     {    
      throw new IllegalArgumentException("Invalid parameters");   
     }   
     String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);   
     if (keyArray.length < 2)   
     {    
      throw new IllegalArgumentException(     "API key or session key is not present");   }   
      this.apiKey = keyArray[0];   
      this.applicationSecret = applicationSecret;   
      this.sessionKey = keyArray[1];   
      this.authenticationId = sessionKey;   
      this.password = applicationSecret;   
      this.hostname = host;   
      String[] mechanisms = { "DIGEST-MD5" };   

      Map<String, String> props = new HashMap<String, String>();   
      this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,this);   
      authenticate(); 
     }  
     @Override  
     public void authenticate(String username, String host, CallbackHandler cbh)throws IOException, XMPPException  
     {   
      String[] mechanisms = { "DIGEST-MD5" };   
      Map<String, String> props = new HashMap<String, String>();   
      this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,cbh);   
      authenticate(); 
     }  @Override  protected String getName() 

     {   
      return NAME;  
     }  
     @Override  
     public void challengeReceived(String challenge) throws IOException  
     {   
      byte[] response = null;   
      if (challenge != null)   
      {    
       String decodedChallenge = new String(Base64.decode(challenge));    
       Map<String, String> parameters = getQueryMap(decodedChallenge);    
       String version = "1.0";    
       String nonce = parameters.get("nonce");    
       String method = parameters.get("method");    
       long callId = new GregorianCalendar().getTimeInMillis();    
       String sig = "api_key=" + apiKey + "call_id=" + callId + "method=" + method + "nonce=" + nonce + "session_key=" + sessionKey + "v=" + version + applicationSecret; 
       try    
       {     
        sig = md5(sig);    
       } 
       catch (NoSuchAlgorithmException e)    
       {     
        throw new IllegalStateException(e);    
       }    
       String composedResponse = "api_key=" + URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId + "&method="+ URLEncoder.encode(method, "utf-8") + "&nonce="+ URLEncoder.encode(nonce, "utf-8")+ "&session_key="+ URLEncoder.encode(sessionKey, "utf-8") + "&v="+ URLEncoder.encode(version, "utf-8") + "&sig="+ URLEncoder.encode(sig, "utf-8");response = composedResponse.getBytes("utf-8"); 
       }   
       String authenticationText = "";   
       if (response != null)   
       {    
        authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);   
       }   

       // Send the authentication to the server   
       getSASLAuthentication().send(new Response(authenticationText));  
       }  
     private Map<String, String> getQueryMap(String query)  
     {   
      Map<String, String> map = new HashMap<String, String>();   
      String[] params = query.split("\\&");   
      for (String param : params)   
      {    
       String[] fields = param.split("=", 2);    
       map.put(fields[0], (fields.length > 1 ? fields[1] : null));   
      }   
      return map;  
      }  
     private String md5(String text) throws NoSuchAlgorithmException,UnsupportedEncodingException  
     {   
      MessageDigest md = MessageDigest.getInstance("MD5");   
      md.update(text.getBytes("utf-8"), 0, text.length());   
      return convertToHex(md.digest());  
     }  
     private String convertToHex(byte[] data)  
     {   
      StringBuilder buf = new StringBuilder();   
      int len = data.length;   
      for (int i = 0; i < len; i++)   
      {    
       int halfByte = (data[i] >>> 4) & 0xF;    
       int twoHalfs = 0;    
       do    
       {     
        if (0 <= halfByte && halfByte <= 9)     
        {      
         buf.append((char) ('0' + halfByte));     
        }     
        else     
        {      
         buf.append((char) ('a' + halfByte - 10));     
        }     
        halfByte = data[i] & 0xF;    
       } 
       while (twoHalfs++ < 1);   
      }   
      return buf.toString();  
      } 
     } 

要使用它:

ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222); 
config.setSASLAuthenticationEnabled(true); 
XMPPConnection xmpp = new XMPPConnection(config); 
try 
{  
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);  
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);  
    xmpp.connect();  
    xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application"); 
} 
catch (XMPPException e) 
{  
    xmpp.disconnect();  
    e.printStackTrace(); 
} 

apiKey是Facebook在應用程序設置頁面給出的API密鑰。 sessionKey是訪問令牌的第二部分。如果令牌是這種形式,AAA | BBB | CCC,則BBB是會話密鑰。 sessionSecret通過auth.promoteSession方法使用舊的REST API獲取。要使用它,它需要做出一個HTTP GET到這個網址:

https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken

儘管Facebook的聊天文件說,這是需要使用你的應用程序的密鑰,只有當我使用了返回的關鍵REST方法我能夠使其工作。要使該方法有效,您必須在應用程序設置的「高級」選項卡中禁用「禁用已棄用的身份驗證方法」選項。

+0

我得到`java.security.KeyStoreException:KeyStore jks實現未找到' 和 `SASL身份驗證失敗使用機制X-FACEBOOK-PLATFORM:` – 2012-10-18 06:33:08

3

我解決了這個問題。我找到的解決方案,http://community.igniterealtime.org/thread/41080

傑裏馬吉爾寫了這...

import java.io.IOException; 
import java.util.HashMap; 
import javax.security.auth.callback.CallbackHandler; 
import javax.security.sasl.Sasl; 
import org.jivesoftware.smack.SASLAuthentication; 
import org.jivesoftware.smack.XMPPException; 
import org.jivesoftware.smack.sasl.SASLMechanism; 
import org.jivesoftware.smack.packet.Packet; 
import org.jivesoftware.smack.util.Base64; 

public class MySASLDigestMD5Mechanism extends SASLMechanism 
{ 
    public MySASLDigestMD5Mechanism(SASLAuthentication saslAuthentication) 
    { 
     super(saslAuthentication); 
    } 

    protected void authenticate() 
     throws IOException, XMPPException 
    { 
     String mechanisms[] = { 
      getName() 
     }; 
     java.util.Map props = new HashMap(); 
     sc = Sasl.createSaslClient(mechanisms, null, "xmpp", hostname, props, this); 
     super.authenticate(); 
    } 

    public void authenticate(String username, String host, String password) 
    throws IOException, XMPPException 
    { 
     authenticationId = username; 
     this.password = password; 
     hostname = host; 
     String mechanisms[] = { 
      getName() 
     }; 
     java.util.Map props = new HashMap(); 
     sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this); 
     super.authenticate(); 
    } 

    public void authenticate(String username, String host, CallbackHandler cbh) 
     throws IOException, XMPPException 
    { 
     String mechanisms[] = { 
      getName() 
     }; 
     java.util.Map props = new HashMap(); 
     sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh); 
     super.authenticate(); 
    } 

    protected String getName() 
    { 
     return "DIGEST-MD5"; 
    } 

    public void challengeReceived(String challenge) 
     throws IOException 
    { 
     //StringBuilder stanza = new StringBuilder(); 
     byte response[]; 
     if(challenge != null) 
      response = sc.evaluateChallenge(Base64.decode(challenge)); 
     else 
      //response = sc.evaluateChallenge(null); 
      response = sc.evaluateChallenge(new byte[0]); 
     //String authenticationText = ""; 
     Packet responseStanza; 
     //if(response != null) 
     //{ 
      //authenticationText = Base64.encodeBytes(response, 8); 
      //if(authenticationText.equals("")) 
       //authenticationText = "="; 

     if (response == null){ 
      responseStanza = new Response(); 
     } else { 
      responseStanza = new Response(Base64.encodeBytes(response,Base64.DONT_BREAK_LINES)); 
     } 
     //} 
     //stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 
     //stanza.append(authenticationText); 
     //stanza.append("</response>"); 
     //getSASLAuthentication().send(stanza.toString()); 
     getSASLAuthentication().send(responseStanza); 
    } 
} 

它,然後從JabberSmackAPI因此被稱爲:

public void login(String userName, String password) throws XMPPException 
{  
    SASLAuthentication.registerSASLMechanism("DIGEST-MD5",MySASLDigestMD5Mechanism. class); 
    ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222); 

    config.setSASLAuthenticationEnabled(true); 
    config.setRosterLoadedAtLogin (true); 

    connection = new XMPPConnection(config); 
    connection.connect(); 
    connection.login(userName, password); 
}