10

I'm trying to make a Facebook Chat on Android with the Smack library. I've read the Chat API from Facebook, but I cannot understand how I have to authenticate with Facebook using this library.

Can anyone point me how to accomplish this?

Update: According to the no.good.at.coding answer, I have this code adapted to the Asmack library. All works fine except I receive as response to the login: not-authorized. Here is the code I use:

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];
        Log.d("API_KEY", apiKey);
        this.applicationSecret = applicationSecret;
        Log.d("SECRET_KEY", applicationSecret);
        this.sessionKey = keyArray[1];
        Log.d("SESSION_KEY", sessionKey);

        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
    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));
            Log.d("DECODED", decodedChallenge);
            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() / 1000L;

            String sig =
                    "api_key=" + apiKey + "call_id=" + callId + "method="
                            + method + "nonce=" + nonce + "session_key="
                            + sessionKey + "v=" + version + applicationSecret;

            try
            {
                sig = md5(sig);
                sig = sig.toUpperCase();
            } 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");

            Log.d("COMPOSED", composedResponse);

            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();
    }
}

And this, is the communication with the server with the sent and received messages:

PM SENT (1132418216): <stream:stream to="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">


PM RCV  (1132418216): <?xml version="1.0"?><stream:stream id="C62D0F43" from="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xml:lang="en"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>


PM SENT (1132418216): <auth mechanism="X-FACEBOOK-PLATFORM" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>


PM RCV  (1132418216): <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NzFGNkQ3Rjc5QkIyREJCQ0YxQTkwMzA0QTg3OTlBMzM=</challenge>


PM SENT (1132418216): <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YXBpX2tleT0zMWYzYjg1ZjBjODYwNjQ3NThiZTZhOTQyNjVjZmNjMCZjYWxsX2lkPTEzMDA0NTYxMzUmbWV0aG9kPWF1dGgueG1wcF9sb2dpbiZub25jZT03MUY2RDdGNzlCQjJEQkJDRjFBOTAzMDRBODc5OUEzMyZzZXNzaW9uX2tleT0yNjUzMTg4ODNkYWJhOGRlOTRiYTk4ZDYtMTAwMDAwNTAyNjc2Nzc4JnY9MS4wJnNpZz04RkRDRjRGRTgzMENGOEQ3QjgwNjdERUQyOEE2RERFQw==</response>


PM RCV  (1132418216): <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>

As read in the developers Facebook forum, it is needed to disable the "Disable Deprecated Auth Methods" setting from the Facebook settings page of your app. But, even doing that, I can't login. And the session key is the second part of the OAuth token in the form AAA|BBB|CCC, I mean, BBB.

Adrian
  • 722
  • 2
  • 11
  • 34

5 Answers5

14

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:

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();
    }
}

To use it:

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 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

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.

Adrian
  • 722
  • 2
  • 11
  • 34
  • Thank you for your response. Which access_token are you referring to? My access token, obtained using the Facebook Graph SDK for Android, doesn't have any pipes in it, so I'm not sure how to obtain the session key. I tried using the whole access_token, but I get an XMPP exception that I'm not authenticated. – Matt Wear Jun 15 '11 at 16:51
  • I don't know how looks like your access token, but try to use URLDecoder.decode(access_token). Maybe now you can see the pipes. – Adrian Jun 15 '11 at 18:38
  • 1
    Alright, I'm pretty sure I got it working. All I had to do was this: xmpp.login(, sessionSecret, "Application"); Thank you so much! Great code, up vote! – Matt Wear Jun 15 '11 at 19:32
  • I misinterpreted what I was doing yesterday. It actually doesn't appear to work. Although, I'm not getting the same XMMPException from asmack; now I'm getting "service-unavailable(503)". I wish there was a more robust XMPP library on Android than asmack, like some of the ones for iOS. – Matt Wear Jun 16 '11 at 16:50
  • 1
    I don't know why are you getting that error, but my chat works fine. The library works well, if you have used my code, it is suppose to enter the api key + session key separated by a pipe as the first parameter in the login method of XMPPConnection. – Adrian Jun 16 '11 at 16:59
  • How are you obtaining your access_token? Are you getting it from the Android Graph SDK? My access_token doesn't have pipes and isn't url encoded. It does have .'s, so AAA.BBB.CCC, but when I take the BBB it doesn't authenticate correctly so I suspect it's not the sessionKey. Is there a way to get the sessionKey a different way, maybe through the REST API like we're getting the sessionSecret? – Matt Wear Jun 16 '11 at 18:12
  • I sincerely apologize. I had mixed up my auth_token with my access_token. I'm able to make a request to the REST API with my Graph auth_token and get my access_token to get the sessionKey. Your code works perfectly now as it always had. Thank you! – Matt Wear Jun 16 '11 at 18:37
  • @adrian which asmack library you are using.I am using asamck15.jar which gives me error in android JKS implementation not found. than connection is establish but gives me SASL authentication exception. – Apekshit Jun 21 '11 at 07:54
  • @Anderson I'm using this version: [link](http://code.google.com/p/asmack/downloads/detail?name=asmack-issue15.jar&can=2&q=) I suppose that is the same version. The JKS error always is thrown because Android doesn't support JKS, but the library works without it. The SASL exception is thrown due to another error, but without more information I can't tell you the reason. I suggest you to open a new question. – Adrian Jun 21 '11 at 14:39
  • Thanks @Adrian for all of your help. Do you know if the sessionSecret needs to be retrieved form auth.promoteSession every time you log in to chat or just once? – Matt Wear Jun 27 '11 at 17:04
  • 1
    @MattWear One time is enough. But, every time the access token changes, you should get a new sessionSecret. – Adrian Jun 27 '11 at 19:46
  • 1
    its very helpful code. I modified it a little to only use apiKey and accessToken with no applicationSecret and sessionKey as the current chat API only take access_token and apiKey. – Amal Feb 07 '12 at 16:15
  • Amal, what do you modified for using only apiKey/acessToken? – Yura Shinkarev Mar 31 '12 at 08:31
  • @Amal can you help me on this, i used same code from the above answer but still i'm getting error on this. i facing problem on getting Api key and session key. i was posted one question on this with my error details check it : http://stackoverflow.com/questions/11045241/how-to-create-xmpp-chat-client-for-facebook/11045268#11045268 – RajaReddy PolamReddy Jun 15 '12 at 07:27
  • @MattWear how can i get apiKey, sessionKey, sessionSecret from my AccessToken..check this Question --http://stackoverflow.com/questions/11045241/how-to-create-xmpp-chat-client-for-facebook – RajaReddy PolamReddy Jun 25 '12 at 12:20
  • java.security.KeyStoreException: KeyStore jks implementation not found – Bhavesh Hirpara Oct 18 '12 at 05:29
4

I'd used this about 6 months ago with Smack (not asmack) so I'm not sure how it'll hold up now but here goes, hope it helps!

I found an implementation of Facebook's X-FACEBOOK-PLATFORM authentication mechanism on the Ignite Realtime Smack forum where someone got it from the fbgc project. You'll find the a ZIP with the SASLXFacebookPlatformMechanism.java source in the answer I linked to. You can use it as follows:

public void login() throws XMPPException
{
    SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME,
            SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0);

    ConnectionConfiguration connConfig = new ConnectionConfiguration(host, port);

    XMPPConnection connection = new XMPPConnection(connConfig);
    connection.connect();
    log.info("XMPP client connected");

    connection.login(Utils.FB_APP_ID + "|" + this.user.sessionId, Utils.FB_APP_SECRET, "app_name");
    log.info("XMPP client logged in");
}

I was doing this on the server without an SDK. I don't remember the details (and the Facebook documentation isn't very good) but from what I can tell from my code, after getting the user to authorize the app, I get a callback request from Facebook with a code parameter. I open a URLConnection to https://graph.facebook.com/oauth/access_token?client_id=<app_id>&redirect_uri=http://myserver/context/path/&client_secret=<app_secret>&code=<code>. The response should be the access token where the session id is the part after the | - something of the form XXX|<sessionId>.

no.good.at.coding
  • 19,647
  • 1
  • 57
  • 51
3

Here's code I've been using successfully for authentication. Maybe this helps even though this is not related to Smack in any way. You can get sessionKey from access token received from FB, and for getting sessionSecret I've been using oldish REST API;

http://developers.facebook.com/docs/reference/rest/auth.promoteSession/

private final void processChallenge(XmlPullParser parser, Writer writer,
        String sessionKey, String sessionSecret) throws IOException,
        NoSuchAlgorithmException, XmlPullParserException {

    parser.require(XmlPullParser.START_TAG, null, "challenge");
    String challenge = new String(Base64.decode(parser.nextText(),
            Base64.DEFAULT));

    String params[] = challenge.split("&");
    HashMap<String, String> paramMap = new HashMap<String, String>();
    for (int i = 0; i < params.length; ++i) {
        String p[] = params[i].split("=");
        p[0] = URLDecoder.decode(p[0]);
        p[1] = URLDecoder.decode(p[1]);
        paramMap.put(p[0], p[1]);
    }

    String api_key = "YOUR_API_KEY";
    String call_id = "" + System.currentTimeMillis();
    String method = paramMap.get("method");
    String nonce = paramMap.get("nonce");
    String v = "1.0";

    StringBuffer sigBuffer = new StringBuffer();
    sigBuffer.append("api_key=" + api_key);
    sigBuffer.append("call_id=" + call_id);
    sigBuffer.append("method=" + method);
    sigBuffer.append("nonce=" + nonce);
    sigBuffer.append("session_key=" + sessionKey);
    sigBuffer.append("v=" + v);
    sigBuffer.append(sessionSecret);

    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(sigBuffer.toString().getBytes());
    byte[] digest = md.digest();

    StringBuffer sig = new StringBuffer();
    for (int i = 0; i < digest.length; ++i) {
        sig.append(Integer.toHexString(0xFF & digest[i]));
    }

    StringBuffer response = new StringBuffer();
    response.append("api_key=" + URLEncoder.encode(api_key));
    response.append("&call_id=" + URLEncoder.encode(call_id));
    response.append("&method=" + URLEncoder.encode(method));
    response.append("&nonce=" + URLEncoder.encode(nonce));
    response.append("&session_key=" + URLEncoder.encode(sessionKey));
    response.append("&v=" + URLEncoder.encode(v));
    response.append("&sig=" + URLEncoder.encode(sig.toString()));

    StringBuilder out = new StringBuilder();
    out.append("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>");
    out.append(Base64.encodeToString(response.toString().getBytes(),
            Base64.NO_WRAP));
    out.append("</response>");

    writer.write(out.toString());
    writer.flush();
}
harism
  • 5,721
  • 1
  • 33
  • 30
  • Thank you!! That REST method did the trick! I was using the secret key that I have in my application settings page but when I tried the result of that method instead the session key all started to work. As I'm going to put the code that works with the Asmack/Smack library, I won't mark your answer as accepted, but I've voted up it. I really thank you for your tip. – Adrian Apr 30 '11 at 17:58
1

I'm sorry to make new answer but I had to include the new code @YShinkarev sorry for being late
By modifying @Adrian answer to make challengeReceived we can use APIKey and accessToken all I modified was the composedResponse

@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 composedResponse = "api_key="
                + URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
                + "&method=" + URLEncoder.encode(method, "utf-8")
                + "&nonce=" + URLEncoder.encode(nonce, "utf-8")
                + "&access_token="
                + URLEncoder.encode(access_token, "utf-8") + "&v="
                + URLEncoder.encode(version, "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));
}
Amal
  • 971
  • 8
  • 25
0

What do you want to do?

If you just want to login on FB chat, you connect to FB just like any other XMPP server.

I would look at and use "Authenticating with Username/Password" from Chat API, wich is supported by Smack. Unless I would like to write an FaceBook-application. Then I would try to login in with "Authenticating with Facebook Platform".

So, just use Smack to connect to FB chat as you would do with your ordinary Jabber client.

  1. For the username, use your Facebook username. (see http://www.facebook.com/username/ )
  2. For the domain, use: chat.facebook.com
  3. For the password, use your Facebook password
  4. Turn off SSL and TSL
  5. Set connect port to: 5222 (which is the default for XMPP)
  6. Set connect server to chat.facebook.com
Anders
  • 390
  • 1
  • 8
  • Thanks for your reply. The Facebook Chat API says that if your application (I'm programming a Facebook client) has a Facebook Application ID, you must use the other chat authentication (X-FACEBOOK-PLATFORM). That's the reason I don't use the DIGEST-MD5 mechanism. Do you know how to support the X-FACEBOOK-PLATFORM in Smack? – Adrian Mar 16 '11 at 11:43
  • 1
    Sorry, I'm more of an XMPP client programmer :) So I have not tried that. But as you wrote, if you write a FB client you should use `X-FACEBOOK-PLATFORM` as your users shouldn't need to log in one more time from the web page when using your application. There are a new version of Smack on the way out that is updated and should fix some bugs which _might_ be a problem for you. Some of those has been fixed by asmack. Would look into 'no.goog.at.coding's sollution, as he got it working at one point. ;-) – Anders Apr 12 '11 at 15:31