4

我正在尝试使用 smack API 集成 facebook 聊天。但是我收到一个错误,告诉我使用摘要 md5 进行身份验证失败...

这是身份验证的代码:

 SASLAuthentication.registerSASLMechanism("DIGEST-MD5", SASLDigestMD5Mechanism.class);
  SASLAuthentication.supportSASLMechanism("DIGEST-MD5", 0);

    ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222);
    connection = new XMPPConnection(config);
    config.setSASLAuthenticationEnabled(true);
    connection.connect();
    connection.login(userName, password);

以下是我运行它时遇到的错误:

Exception in thread "main" SASL authentication failed using mechanism DIGEST-MD5: 
    at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:325)
    at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
    at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
    at JabberSmackAPIFacebook.login(JabberSmackAPIFacebook.java:31)
    at JabberSmackAPIFacebook.main(JabberSmackAPIFacebook.java:77)

我可以成功连接到 gtalk,但没有成功 vit fb... 可以打电话给我吗?

4

4 回答 4

1

对我来说,解决方案是在没有 DNS SRV 的情况下调用时不将主机部分包含在用户名中login(),而不是针对 Google Talk 服务。这也在ignite 论坛中有所描述。

例如

connection.login("user@jabber.org", "password", "resource");

变成

connection.login("user", "password", "resource");
于 2011-12-05T11:12:57.730 回答
0

我已经使用 DIGEST-MD5 成功连接到 facebook,您发布的代码看起来不错。但是我们仍然需要检查您的 SASLDigestMD5Mechanism 类的内容

我已经成功使用了此处提供的课程

http://community.igniterealtime.org/message/200878#200878

您还必须注意,在 DIGEST-MD5 机制中,您必须使用您的facebook 用户名而不是电子邮件地址登录。默认情况下,Facebook 帐户没有用户名,您必须先创建一个,您可以在此处查看:

http://www.facebook.com/username/

于 2011-05-20T16:37:44.767 回答
0

MainActivity.java

public class MainActivity extends Activity {

XMPPConnection xmpp;
ArrayList<HashMap<String, String>> friends_list;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Session.openActiveSession(this, true, new StatusCallback() {

        @Override
        public void call(Session session, SessionState state, Exception exception) {

            if ( session.isOpened()){
                new testLoginTask().execute();
            }
        }
    });

}

private class testLoginTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected Void doInBackground(Void... params) {

        testLogin();

        return null;
    }

}

private void testLogin(){

    ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
    config.setSASLAuthenticationEnabled(true);
    config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
    config.setDebuggerEnabled(true);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        config.setTruststoreType("AndroidCAStore");
        config.setTruststorePassword(null);
        config.setTruststorePath(null);
    } else {
        config.setTruststoreType("BKS");
        String path = System.getProperty("javax.net.ssl.trustStore");
        if (path == null)
            path = System.getProperty("java.home") + File.separator + "etc"
                                            + File.separator + "security" + File.separator
                                            + "cacerts.bks";
        config.setTruststorePath(path);
    }


    xmpp = new XMPPConnection(config);
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM",SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);

    try {
        xmpp.connect();
        Log.i("XMPPClient","Connected to " + xmpp.getHost());

    } catch (XMPPException e1) {
        Log.i("XMPPClient","Unable to " + xmpp.getHost());

        e1.printStackTrace();
    }
    try {


        String apiKey = Session.getActiveSession().getApplicationId();
        String sessionKey = Session.getActiveSession().getAccessToken();
        String sessionSecret = "replace with your app secret key";

        xmpp.login(apiKey + "|" + sessionKey, sessionSecret , "Application");

        Log.i("XMPPClient"," its logined ");

        Log.i("Connected",""+xmpp.isConnected());

        if ( xmpp.isConnected()){
            Presence presence = new Presence(Presence.Type.available);
            xmpp.sendPacket(presence);

        }

    } catch (XMPPException e) {
        e.printStackTrace();
    }  
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}

SASLXFacebookPlatformMechanism.java

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

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

}
于 2013-08-22T12:06:17.873 回答
0

Ignite有一个巨大的线程来处理这个问题。您可能想看看它,因为有几种适用于 Java 和 Android 的解决方案似乎可行。

于 2011-04-05T17:31:21.113 回答