连接到Facebook XMMP MD5-DIGEST的问题 [英] Problems with connecting to Facebook XMMP MD5-DIGEST

查看:98
本文介绍了连接到Facebook XMMP MD5-DIGEST的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试所有的东西来连接Facebook与XMPP,但我已经面临只有
一个错误,所有的时间是:_
SASL身份验证失败使用机制DIGEST-MD5
我正在执行以下方法来执行此任务:

I have tried all the things to connect Facebook with XMPP but i have faced only one error all the time which is :
SASL authentication failed using mechanism DIGEST-MD5
I am implementing following method to perform this task :

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("username@chat.facebook.com", "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

我搜索了所有博客并找到相同的东西,但我不知道我在这里做错了什么..

I searched all blog and find same thing but i dont know what am i doing wrong here..

如果有任何其他方式或解决方案来连接Facebook XMPP,那么请帮助我
ASAP

If is there any other way or solution to connect Facebook XMPP then please Help me ASAP

推荐答案

最后,由于no.good.at.coding代码和harism的建议,我已经能够连接到Facebook聊天。这个代码是Asmack库的机制(Android的Smack端口)。对于Smack库,需要使用no.good.at.coding机制。

Finally, thanks to the no.good.at.coding code and the suggestion of harism, I've been able to connect to the Facebook chat. This code is the Mechanism for the Asmack library (the Smack port for Android). For the Smack library is necessary to use the no.good.at.coding mechanism.

SASLXFacebookPlatformMechanism.java:

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是使用旧的REST API,方法auth.promoteSession获得的。要使用它,需要使一个Http得到这个URL:

apiKey is the API key given in the application settings page in Facebook. sessionKey is the second part of the access token. If the token is in this form, AAA|BBB|CCC, the BBB is the session key. sessionSecret is obtained using the old REST API with the method auth.promoteSession. To use it, it's needed to make a Http get to this url:

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

尽管的Facebook聊天文档说,需要使用您的应用程序密钥,只有当我使用返回的REST方法的密钥才能使其工作。要使该方法工作,您必须在应用程序设置的高级选项卡中禁用禁用不推荐的身份验证方法选项。

Despite of the Facebook Chat documentation says that it's needed to use your application secret key, only when I used the key that returned that REST method I was able to make it works. To make that method works, you have to disable the Disable Deprecated Auth Methods option in the Advance tab in your application settings.

这篇关于连接到Facebook XMMP MD5-DIGEST的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆