使用 X-FACEBOOK-PLATFORM SASL 身份验证的 facebook 聊天身份验证

发布于 2024-11-09 06:32:37 字数 2032 浏览 0 评论 0原文

我正在使用 X-FACEBOOK-PLATFORM SASL 身份验证机制处理 facebook 聊天身份验证。

我正在按照 facebook 开发者论坛和 stackoverflow 问题中的说明形成用户和密码。

重点是,如果我使用 application_secret 作为密码,我可以登录,但根据 stackoverflow 问题(下面的链接),它应该是从旧的其余 api 方法 auth.promoteSession 生成的会话

我想使用旧的其余 api 方法,在为了避免在我们的桌面应用程序 jar 中分发 application_secret。

所以问题是,你是如何成功使用 auth.promoteSession 登录的???

我已阅读以下帖子,这些帖子非常有帮助:

http://community.igniterealtime.org /message/205739#205739
XMPP 与支持 X-FACEBOOK-PLATFORM 的 Java Asmack 库

我正在使用 SASLXFacebookPlatformMechanism.java 类,它来自 igniterealtime 帖子,并且注册正确。

我有xmpp_login和offline_access权限。我已经禁用了“删除不推荐使用的身份验证方法”,因此我可以调用旧的其余 api 方法,在本例中为: auth.promoteSession 我也在 Facebook 中使用客户端流身份验证。

因此,使用 application_secret 作为密码,我得到:

<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NEIxRUQzNTA5MTQ5MDQxRTE4N0QyNTA0NTUzNjBDQjc=</challenge>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

但如果我使用 auth.promoteSession 返回的值,我得到:

<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9MzhFQkUxOTUxNENGRUU4ODc2NzRDREQ0RjhBMUQ0QjI=</challenge>
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>

I'm dealing with the facebook chat authentication using the X-FACEBOOK-PLATFORM SASL authentication mechanism.

I'm forming the user and password as explained in the facebook developer forum and the stackoverflow question.

The point is if I use the application_secret as password I can login, but according to the stackoverflow question (link below) it should be a session generated from the old rest api method auth.promoteSession

I want to use the old rest api method, in order to avoid distributing the application_secret in our desktop application jars.

So the question is, how have you managed to login with the auth.promoteSession????

I have read the following posts which have been of great help:

http://community.igniterealtime.org/message/205739#205739
XMPP with Java Asmack library supporting X-FACEBOOK-PLATFORM

And I'm using the class SASLXFacebookPlatformMechanism.java which comes fromt the igniterealtime post and it is registered correclty.

I have the xmpp_login and offline_access permisions. And I have disabled the Remove Deprecated Auth Methods, so I can called the old rest api methods, in this case: auth.promoteSession
I'm using the client-side flow authentication into facebook as well.

So, using the application_secret as password I get:

<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NEIxRUQzNTA5MTQ5MDQxRTE4N0QyNTA0NTUzNjBDQjc=</challenge>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

But if I use the value returned by the auth.promoteSession I get:

<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9MzhFQkUxOTUxNENGRUU4ODc2NzRDREQ0RjhBMUQ0QjI=</challenge>
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何处潇湘 2024-11-16 06:32:37

我已经更改了 Android 版本,现在它适用于我

public class SASLXFacebookPlatformMechanism extends SASLMechanism {

    private 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 {
        getSASLAuthentication().send(new AuthMechanism(NAME, ""));
    }

    @Override
    public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
        if (apiKey == null || accessToken == null) {
            throw new IllegalArgumentException("Invalid parameters");
        }

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

            String composedResponse =
                "method=" + URLEncoder.encode(method, "utf-8") +
                        "&nonce=" + URLEncoder.encode(nonce, "utf-8") +
                        "&access_token=" + URLEncoder.encode(accessToken, "utf-8") +
                        "&api_key=" + URLEncoder.encode(apiKey, "utf-8") +
                        "&call_id=0" +
                        "&v=" + URLEncoder.encode(version, "utf-8");
            response = composedResponse.getBytes();
        }

        String authenticationText = "";

        if (response != null) {
            authenticationText = Base64.encodeBytes(response);
        }

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

这个版本只需要应用程序 ID 和访问令牌

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

try {
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
    mFbConnection.connect();
    mFbConnection.login(apiKey, accessToken, "Application");
} catch (XMPPException e) {
    mFbConnection.disconnect();
    e.printStackTrace();
}

我希望这会有所帮助。

I have changed the version for Android and it works for me now

public class SASLXFacebookPlatformMechanism extends SASLMechanism {

    private 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 {
        getSASLAuthentication().send(new AuthMechanism(NAME, ""));
    }

    @Override
    public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
        if (apiKey == null || accessToken == null) {
            throw new IllegalArgumentException("Invalid parameters");
        }

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

            String composedResponse =
                "method=" + URLEncoder.encode(method, "utf-8") +
                        "&nonce=" + URLEncoder.encode(nonce, "utf-8") +
                        "&access_token=" + URLEncoder.encode(accessToken, "utf-8") +
                        "&api_key=" + URLEncoder.encode(apiKey, "utf-8") +
                        "&call_id=0" +
                        "&v=" + URLEncoder.encode(version, "utf-8");
            response = composedResponse.getBytes();
        }

        String authenticationText = "";

        if (response != null) {
            authenticationText = Base64.encodeBytes(response);
        }

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

This version requires only application id and access token

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

try {
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
    mFbConnection.connect();
    mFbConnection.login(apiKey, accessToken, "Application");
} catch (XMPPException e) {
    mFbConnection.disconnect();
    e.printStackTrace();
}

I hope this will help.

妞丶爷亲个 2024-11-16 06:32:37

是的,在我看来,两者都需要。来自 XMPP 的代码,带有支持 X-FACEBOOK-PLATFORM 的 Java Asmack 库 需要调整以包含应用程序机密以及会话机密(作为密码)。

this.apiKey = keyArray[0];
    Log.d("API_KEY", apiKey);
    this.applicationSecret = "################################";
    Log.d("SECRET_KEY", applicationSecret);
    this.sessionKey = keyArray[1];
    Log.d("SESSION_KEY", sessionKey);

    this.authenticationId = sessionKey;
    this.password = applicationSecret;
    this.hostname = host;

将 ########################## 替换为您的 appSecret (在您的开发区域中找到)

这在文档或后 IMO 中尚不清楚。会话秘密是通过 FB.getSession() 获取的,但其他选项也可以。

Yes it apears to me, you need both. The code from XMPP with Java Asmack library supporting X-FACEBOOK-PLATFORM needed adjusting to include the application secret, as well as the session secret (as the password).

this.apiKey = keyArray[0];
    Log.d("API_KEY", apiKey);
    this.applicationSecret = "################################";
    Log.d("SECRET_KEY", applicationSecret);
    this.sessionKey = keyArray[1];
    Log.d("SESSION_KEY", sessionKey);

    this.authenticationId = sessionKey;
    this.password = applicationSecret;
    this.hostname = host;

swaping out the ######################## for your appSecret (found in your dev area)

This is not clear from the docs or the post IMO. Session secret was aquired through FB.getSession() but other options work too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文