【问题标题】:facebook chat authentication using the X-FACEBOOK-PLATFORM SASL authentication使用 X-FACEBOOK-PLATFORM SASL 身份验证的 facebook 聊天身份验证
【发布时间】:2011-08-29 19:36:42
【问题描述】:

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

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

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

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

所以问题是,您是如何设法使用 auth.promoteSession 登录的????

我已阅读以下对我有很大帮助的帖子:

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

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

我有 xmpp_login 和 offline_access 权限。而且我已经禁用了 Remove Deprecated Auth Methods,所以我可以调用旧的 rest 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>

【问题讨论】:

    标签: java facebook xmpp chat smack


    【解决方案1】:

    我已经更改了 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();
    }
    

    我希望这会有所帮助。

    【讨论】:

    • @hleinone 我也在尝试在 ma android 应用程序中实现 facebook 聊天,但我没有导入 SASLMechanism 类。我们必须下载任何库或 jar 文件来导入它。如果请提供有效的下载链接..
    • 您需要使用Smack 库。
    【解决方案2】:

    对我来说是的,你需要两者。 XMPP with Java Asmack library supporting X-FACEBOOK-PLATFORM 的代码需要调整以包含应用程序密码以及会话密码(作为密码)。

    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() 获取的,但其他选项也可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-02
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      • 2017-08-12
      相关资源
      最近更新 更多