Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

X-FACEBOOK-PLATFORM authentication with SMACK Java library using OAuth 2.0

First post here so please be gentle. I'm building a facebook chat client, using Smack library. I'm using X-FACEBOOK-PLATFORM method in order not to save any passwords. I had it working properly using oauth 1.0, and want to change it to 2.0, cause of the october 1st deadline ;p. From what I understand the only thing I'd have to do in order to migrate to 2.0 is removing "sig" and "session_key" parameters and adding an "access_token" parameter, but I'm getting an "SASL authentication X-FACEBOOK-PLATFORM failed: not-authorized:". I'm using this custom SASLMechanism class:

package smackresearching;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

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.util.Base64;

public class SASLXFacebookPlatformMechanism extends SASLMechanism {

    public static final String NAME = "X-FACEBOOK-PLATFORM";
    private String apiKey = "";
        private String accessToken = "";


    /**
     * Constructor.
     */
    public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) {
            super(saslAuthentication);
    }

    @Override
    protected void authenticate() throws IOException, XMPPException {
        // Send the authentication to the server
        getSASLAuthentication().send(new AuthMechanism(getName(), ""));
    }

    @Override
    public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
        this.apiKey = apiKey;
        this.accessToken = accessToken;
        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));
                    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 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(accessToken, "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));
    }

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

And this is the Main code:

ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",     5222);
config.setSASLAuthenticationEnabled(true);
//        config.setDebuggerEnabled(true);
XMPPConnection connection = new XMPPConnection(config);


try {
    //ESTA LINEA HACE QUE NO DE TIMEOUT
    SmackConfiguration.setPacketReplyTimeout(15000);
    XMPPConnection.DEBUG_ENABLED = true;
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
    connection.connect();
    String apiKey = "3290282390339";
    String accessToken = "ADSJGFGFKDKSJKSJD0-43DKJSDJKSDKJSD094JJSDKJSDKJDSNDSKJEWEWNSDLkljdkjs";
    connection.login(apiKey, accessToken);
...

Thanks in advance for any advice.

like image 286
alscu Avatar asked Sep 12 '11 23:09

alscu


People also ask

How do I login to Facebook using OAuth in Java?

Facebook OAuth Authentication Sequence Flow On access of an url or in welcome page the Facebook Login button is shown. The user will click the FB button to login into the Java web application. On click of that button a Facebook URL will be invoked.

How to secure your website with OAuth2 on Facebook?

If you refresh the page now, you’ll see that our site has been secured by a HTTP basic login form. Then, add application.yml to your project and add the oauth2 setting. This is Facebook specific setting, what you only need to provide is the clientID (or App ID) and clientSecret or your App secret key.

How to secure your Spring Boot site with OAuth2?

The first step is to add 2 dependencies. Spring Boot starter security and Oauth2 to pom.xml. If you refresh the page now, you’ll see that our site has been secured by a HTTP basic login form. Then, add application.yml to your project and add the oauth2 setting.

What is an example of OAuth2 authorization?

For example, if sign in and/or sign up with Facebook functionality needs to be implemented, the developer needs to visit the official docs page for the Facebook OAuth provider. In the OAuth2 authorization process, the program that sends requests to the authorization server is known as the client.


1 Answers

There is a missing ampersand for the access_token parameter in the composedResponse string. Is this a typo?

Could you post the authenticationText you are sending?

like image 56
Alexcode Avatar answered Oct 06 '22 05:10

Alexcode