Problems with connecting to Facebook XMMP MD5-DIGEST

Hi,

I am getting following error

java.lang.NullPointerException

at org.jivesoftware.smack.sasl.SASLMechanism.authenticate(SASLMechanism.java:117)

at MySASLDigestMD5Mechanism.authenticate(MySASLDigestMD5Mechanism.java:43)

at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java: 308)

at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)

at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)

my code is

SASLAuthentication.registerSASLMechanism(“DIGEST-MD5”,

MySASLDigestMD5Mechanism. class);

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

config.setSASLAuthenticationEnabled(true);

config.setRosterLoadedAtLogin (true);

XMPPConnection connection = new XMPPConnection(config);

connection.connect();

System.out.println(connection.getServiceName());

connection.login(“xxxxxxxxx”, “xxxxxx”);

How to do it, Please explain, Its urgent…

SASL authentication DIGEST-MD5 failed: not-authorized:

hi, I’m trying to using your file. but : SASL authentication DIGEST-MD5 failed: not-authorized.

my code:

SASLAuthentication.registerSASLMechanism(“DIGEST-MD5”, MySASLDigestMD5Mechanism1.class);

SASLAuthentication.supportSASLMechanism(“DIGEST-MD5”, 0);

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

config.setSASLAuthenticationEnabled(true);

config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);

config.setSendPresence(false);

config.setSocketFactory(proxy.getSocketFactory());

//

conn = new XMPPConnection(config);

try {

System.out.println(“connect…”);

conn.connect();

conn.addConnectionListener(this);

System.out.println(“connected…”);

conn.login(username, pd, “leolee.com”);

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

thank you.

Hi there!!

I’m quite new at this. I downloaded your file and I am get an error with your las sentence:

getSASLAuthentication().send(stanza.toString());

It’s all the time saying that the method send is not applicable for the type String. What is wrong with this???

I just want to try and connect with FB and I see that many of those who have used your file now can connect properly.

Thanks in advance.

I used your code but it no longer worked so I patched it at little and am returning it to the community. It works like a charm for facebook.

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

//getSASLAuthentication().send(stanza.toString());

getSASLAuthentication().send(responseStanza);

}

}

It is then called thus from the 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);

}

Hello, I’m just an amateur with smack api, and I’m trying hard to connect to facebook chat using x-facebook platform.

I am using the custom SASL mechanism class for facebook authentication described above. But getting errors, actually I do not know exactly how to perform this.

public class SASLXFacebookPlatformMechanism extends SASLMechanism {
    public static final String NAME = "X-FACEBOOK-PLATFORM";     private String apiKey = "";
    private String applicationSecret = "";
    private String sessionKey = "";     /**
     * Constructor.
     */
    public SASLXFacebookPlatformMechanism1(SASLAuthentication saslAuthentication) {
        super(saslAuthentication);
    }     @Override
    protected void authenticate() throws IOException, XMPPException {
        StringBuilder stanza = new StringBuilder();
        stanza.append("<auth mechanism=\"").append(getName());
        stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
        stanza.append("</auth>");         // Send the authentication to the server
        getSASLAuthentication().send(stanza.toString());
    }     @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 {
        StringBuilder stanza = new StringBuilder();
        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() / 1000L;             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);         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());
    }     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();
    }
}

So now I have this class, but I don’t know where I am doing wrong, may be I’m calling it in wrong manner, here is how I made use of this class.

ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
config.setDebuggerEnabled(true); SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME, SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0); XMPPConnection connection = new XMPPConnection(config);
try {
    connection.connect();
} catch (XMPPException ex) {
    Logger.getLogger(FB.class.getName()).log(Level.SEVERE, null, ex);
}
SASLXFacebookPlatformMechanism1 mech=new SASLXFacebookPlatformMechanism1(connection.getSASLAuthentication());
try {
    mech.authenticate();
} catch (IOException ex) {
    Logger.getLogger(FB.class.getName()).log(Level.SEVERE, null, ex);
} catch (XMPPException ex) {
    Logger.getLogger(FB.class.getName()).log(Level.SEVERE, null, ex);
}

When I execute this code, I get a NullPointerException

java.lang.NullPointerException
    at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthentication.java:514)
    at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:296)
    at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:43)
    at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70)

Thanks a lot Jerry. You are a saviour.

Look here’s a complete code snippet with the MD5 class.Hope this helps: http://fbserver.99k.org/Facebook.rar

U must not bother about this class.If you have smack properly installed in your classpath then this snippet will be enough to get u started. http://fbserver.99k.org/Facebook.rar

One important thing is the rar file is shipped with MD5…class too that you must put in your classes directory(where all your sources get compiled to .class files)

Hope this helps

Regards

Here’s a complete code for facebook with MD5…class http://fbserver.99k.org/Facebook.rar

U need this class if u need to connect to facebook.I dont think otherwise is possible.

Thanks

Here’s my complete solution for newbies.Both google & facebook implementation.Implemented using Thread.Also includes the MD5 checksum class.So I think it’s pretty much to get someone started.

http://fbserver.99k.org/smack_google_facebook.rar

Regards-

Dibosh

Thanks for your reply. I have got my program working now, but I have problem in getting the correct access key for a user.

Although I haven’t built any program for authorizing my app. Presently I am just trying to authenticate my app by feeding in some codes provided on http://developers.facebook.com/docs/authentication/ in the address bar of my browser.

I am facing following problems:

Firstly, I cannot understand that I am building a native desktop app, not a web app so why do I need to give a canvas page, the code to authenticate given in facebook documentation in link given above also require a redirect link to a canvas page. Although, I have created a simple html page and hosted on a server to get proceeded but can you tell me is it necessary or there is any other way around for a native app that do not require a canvas page.

Secondly, I proceed as given below, i enter these in address bar and proceed:

  1. https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_UR L&scope=email,read_stream

  2. After user presses allow then this appears in my address bar

http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER

  1. But when I use this CODE in following link

https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&redirect_uri =YOUR_URL&client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE

I get this error:

{ "error": { "type": "OAuthException", "message": "Error validating verification code." } }

instead of getting a access token. Can you please tell me what is the problem?

As far as I told if you use smack & java for your desktop app then

there’s no need to do this on your own.All these authentication is

already done inside the smack api.So why do you bother about writing

native codes?I just understand this!And I have given a snippet already

That’s enough.You just need to dive into smack API more & start

handling your UI to respond as a chat program.

Would be very grateful for a look at your code here. I’m really struggling with this. Keep getting 503 issues (I have all necessary permissions). tried using the code here: http://stackoverflow.com/questions/5317329/xmpp-with-java-asmack-library-support ing-x-facebook-platform

But the client factory in org.apache.harmony.javax.security.sasl.Sasl is the last place I can trace to problem to.

Tried using the app secret and the session secret and the name. Both return 503

Hi,

after using the code that you have posted up; i’ve got an error message

SASL authentication DIGEST-MD5 failed: not-authorized:

at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java: 337)

at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)

at org.jivesoftware.smack.Connection.login(Connection.java:348)

at Facebook.login(Facebook.java:46)

at Facebook.main(Facebook.java:16)

any help !!!

I just ran that code again & found everything fine.Did you added the class successfully?If you have problem with the class try to include this Jar in your classpath instead: http://fbserver.99k.org/SASL.jar

Hi

now i’ve got this error message :

connected to facebook

Exception in thread “Smack Packet Reader (0)” java.lang.NoSuchMethodError: org.jivesoftware.smack.SASLAuthentication.send(Ljava/lang/String;)V

at MySASLDigestMD5Mechanism.challengeReceived(MySASLDigestMD5Mechanism.java:80)

at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthentication. java:514)

at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:296)

at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:43)

at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70)

No response from the server.:

at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication .java:73)

at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java: 352)

at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)

at org.jivesoftware.smack.Connection.login(Connection.java:348)

at Facebook.login(Facebook.java:45)

at Facebook.main(Facebook.java:15)

**here is my code **

import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.SASLAuthentication;

import org.jivesoftware.smack.XMPPConnection;

import org.jivesoftware.smack.XMPPException;

public class Facebook {

/**

  • @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

try {

        login("user@yahoo.com", "pass");

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public static void login(String userName, String password) throws XMPPException

{

SASLAuthentication.registerSASLMechanism(“DIGEST-MD5”,MySASLDigestMD5Mechanism. class);

//((SASLAuthentication) ss).registerSASLMechanism(“DIGEST-MD5”,MySASLDigestMD5Mechanism.class);

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

config.setSASLAuthenticationEnabled(true);

config.setRosterLoadedAtLogin (true);

XMPPConnection connection = new XMPPConnection(config);

connection.connect();

System.out.print(“connected to facebook\n”);

connection.login(userName, password);

System.out.print(“logged to facebook\n”);

}

}

nb: in your Zip file a “chatFrame” class is missing , that’s why i 've rewrite it without this class

thnx

u r trying to enter facebook so why there is user@yahoo.com???I forgot

to tell one thing you can not enter facebook from smack using your

mail id.You must have an username in facebook.If you dont have create

one from your facebook account section.And enter the username in ur

app;this time it must run!

And one thing sometimes smack fails to connect in that case re-run ur app.

event

hi wvwn i am new to samck api

and trying to connect to facebook and followed your steps mentioned above but got the following error

connected to facebook

Exception in thread “Smack Packet Reader (0)” java.lang.NoSuchMethodError: org.j

ivesoftware.smack.SASLAuthentication.send(Ljava/lang/String;)V

at MySASLDigestMD5Mechanism.challengeReceived(MySASLDigestMD5Mechanism.j

ava:80)

at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthe

ntication.java:514)

at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:29

at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:43)

at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70)

No response from the server.:

at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuth

entication.java:73)

at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentica

tion.java:352)

at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)

at org.jivesoftware.smack.Connection.login(Connection.java:348)

at Facebook.login(Facebook.java:93)

at Facebook.main(Facebook.java:33)

D:\try fb>

my code is

import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.SASLAuthentication;

import org.jivesoftware.smack.XMPPConnection;

import org.jivesoftware.smack.XMPPException;

public class Facebook {

/**

  • @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

try {

login(“facebokusername”, “fbpasword”);

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public static void login(String userName, String password) throws XMPPException

{

SASLAuthentication.registerSASLMechanism(“DIGEST-MD5”,MySASLDigestMD5Mechanism. class);

//((SASLAuthentication) ss).registerSASLMechanism(“DIGEST-MD5”,MySASLDigestMD5Mechanism.class);

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

config.setSASLAuthenticationEnabled(true);

config.setRosterLoadedAtLogin (true);

XMPPConnection connection = new XMPPConnection(config);

connection.connect();

System.out.print(“connected to facebook\n”);

connection.login(userName, password);

System.out.print(“logged to facebook\n”);

}

}

i have used the facebook username and the password for the same but could not log in to accoutn and ended up with the above error

evne i tried your zip files but have the same error for them, after removing the chatframe code fragment

please help…

Hi alexryd and everyone,

Since this post was made, it seems Facebook have changed their API somewhat; this thread, and your post in particular, have been very helpful for me in getting things to work, so I’m contributing back an updated solution which works for me.

The attached source is a new version of the SASL Mechanism for Facebook Platform; it is simpler than the earlier version, as the sig is no longer required.

The usage is similar to the previous version, but again simpler: You don’t need the session key. The one thing that is slightly more complex is that, instead of the application secret, you now use an access token that you need to get from Facebook (see http://developers.facebook.com/docs/authentication/). Facebook (in https://developers.facebook.com/docs/chat/) recommend you use the client flow to get the token, and that’s what I did; the server flow is supposed to yield a similar token, so it should work just as well.

The new usage code looks like:

SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME, SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0); ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222); XMPPConnection connection = new XMPPConnection(config);
connection.connect();
connection.login(apiKey, accessToken, "Client Name"); // Client name optional

Hope this helps,

Shai.
SASLXFacebookPlatformMechanism.java.zip (1576 Bytes)

1 Like

So to reply to the ORIGINAL discussion at hand, for those who are NOT trying to do X-Facebook, but just DIGEST-MD5, if you seemingly tried EVERYTHING you’ve found online without any luck like I did for hours while banging my head into the keyboard, I did finally get facebook chat working with asmack.

If you’re getting a failed not authorized for DIGEST-MD5 and are using the asmack library try the following: go to facebook.com/username, make sure you have a username chosen first, then LOGOUT and log back in using ONLY your username and password. If you’re like me, and hate facebook, but somehow found themselves coding a chat client, you might have had an old account when they used to be based on purely email addresses, so technically before doing the above steps, my userid was xxx@email.com@chat.facebook.com which is retarded on facebooks part.

I’m logged into facebook now from my client using only the asmack lib, no custom mysaslmechanism classes or anything.

Hope that helps some of your frustrated devs out there.