Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
支持X-FACEBOOK-PLATFORM的带Java Asmack库的XMPP_Java_Android_Facebook_Xmpp_Smack - Fatal编程技术网

支持X-FACEBOOK-PLATFORM的带Java Asmack库的XMPP

支持X-FACEBOOK-PLATFORM的带Java Asmack库的XMPP,java,android,facebook,xmpp,smack,Java,Android,Facebook,Xmpp,Smack,我正试图在Android上与Smack库进行Facebook聊天。我已经阅读了Facebook上的内容,但我不明白如何使用该库通过Facebook的身份验证 有人能告诉我如何做到这一点吗 更新:根据no.good.at.coding答案,我将此代码改编为Asmack库。所有工作正常,但我收到的登录响应:未授权。以下是我使用的代码: public class SASLXFacebookPlatformMechanism extends SASLMechanism { private st

我正试图在Android上与Smack库进行Facebook聊天。我已经阅读了Facebook上的内容,但我不明白如何使用该库通过Facebook的身份验证

有人能告诉我如何做到这一点吗

更新:根据no.good.at.coding答案,我将此代码改编为Asmack库。所有工作正常,但我收到的登录响应:未授权。以下是我使用的代码:

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();
    }
}
公共类SASLXFacebookPlatformMechanism扩展了SASLMechanism
{
私有静态最终字符串NAME=“X-FACEBOOK-PLATFORM”;
私有字符串apiKey=“”;
私有字符串应用程序secret=“”;
私有字符串sessionKey=“”;
/**
*构造器。
*/
公共SASLXFacebookPlatformMechanism(SASLAuthentication SASLAuthentication)
{
超级(saslAuthentication);
}
@凌驾
受保护的void authenticate()引发IOException,xmppeException
{
getSASLAuthentication().send(新的身份验证机制(名称“”);
}
@凌驾
public void身份验证(字符串apiKeyAndSessionKey、字符串主机、,
字符串应用程序加密)抛出IOException、XMPPException
{
if(apiKeyAndSessionKey==null | | applicationSecret==null)
{
抛出新的IllegalArgumentException(“无效参数”);
}
String[]keyArray=apiKeyAndSessionKey.split(“\\\\”,2);
如果(keyArray.length<2)
{
抛出新的IllegalArgumentException(
“API密钥或会话密钥不存在”);
}
this.apiKey=keyArray[0];
Log.d(“API_键”,apiKey);
this.applicationSecret=applicationSecret;
Log.d(“机密密钥”,应用程序机密);
this.sessionKey=keyArray[1];
Log.d(“会话密钥”,会话密钥);
this.authenticationId=会话密钥;
this.password=applicationSecret;
this.hostname=host;
字符串[]机制={“摘要-MD5”};
Map props=newhashmap();
本网站=
createSaslClient(机制,空,“xmpp”,主机,道具,
这),;
验证();
}
@凌驾
受保护的字符串getName()
{
返回名称;
}
@凌驾
public void challengeReceived(字符串质询)引发IOException
{
字节[]响应=null;
if(质询!=null)
{
String decodedChallenge=新字符串(Base64.decode(challenge));
Log.d(“解码”,解码挑战);
映射参数=getQueryMap(decodedChallenge);
字符串version=“1.0”;
字符串nonce=parameters.get(“nonce”);
String方法=parameters.get(“方法”);
long callId=new gregorianalendar().getTimeInMillis()/1000L;
串信号=
“api_key=“+apiKey+”call_id=“+callId+”方法=”
+方法+“nonce=“+nonce+”会话密钥=”
+sessionKey+“v=“+版本+应用程序机密;
尝试
{
sig=md5(sig);
sig=sig.toUpperCase();
}捕获(无算法异常)
{
抛出新的非法状态异常(e);
}
字符串组合响应=
“api_key=“+urlcoder.encode(apiKey,“utf-8”)
+“&call_id=“+callId+”&method=”
+encode(方法“utf-8”)+“&nonce=”
+URLEncoder.encode(nonce,“utf-8”)
+“&会话密钥=”
+encode(sessionKey,“utf-8”)+“&v=”
+urlcoder.encode(版本,“utf-8”)+“&sig=”
+编码(sig,“utf-8”);
Log.d(“组合”,组合响应);
response=composedResponse.getBytes(“utf-8”);
}
字符串authenticationText=“”;
if(响应!=null)
{
认证文本=
Base64.encodeBytes(响应,Base64.don_BREAK_行);
}
//将身份验证发送到服务器
getSASLAuthentication().send(新响应(authenticationText));
}
私有映射getQueryMap(字符串查询)
{
Map Map=newhashmap();
字符串[]params=query.split(“\\&”);
for(字符串参数:params)
{
字符串[]字段=参数拆分(“=”,2);
map.put(字段[0],(fields.length>1?字段[1]:null));
}
返回图;
}
私有字符串md5(字符串文本)抛出NoSuchAlgorithmException,
不支持的编码异常
{
MessageDigest md=MessageDigest.getInstance(“MD5”);
md.update(text.getBytes(“utf-8”),0,text.length();
返回convertToHex(md.digest());
}
私有字符串convertToHex(字节[]数据)
{
StringBuilder buf=新的StringBuilder();
int len=data.length;
对于(int i=0;i>>4)&0xF;
int twoHalfs=0;
做
{

如果(0你想做什么

如果您只想登录FB聊天,您可以像其他任何XMPP服务器一样连接到FB

我会查看并使用聊天API中的“使用用户名/密码进行身份验证”,这是Smack支持的。除非我想编写FaceBook应用程序。然后我会尝试使用“使用FaceBook平台进行身份验证”登录

所以,只需使用Smack连接到FB聊天,就像使用普通的Jabber客户端一样

  • 对于用户名,请使用您的Facebook用户名。(请参阅)
  • 对于域,请使用:chat.facebook.com
  • 为了
    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>
    
    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");
    }
    
    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();
    }
    
    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();
        }
    }
    
    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();
    }
    
    @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));
    }