使用 Smack 集成 facebook 聊天时 SASL 身份验证失败
Posted
技术标签:
【中文标题】使用 Smack 集成 facebook 聊天时 SASL 身份验证失败【英文标题】:SASL Authentication failed while integrating facebook chat using Smack 【发布时间】:2011-03-31 10:16:11 【问题描述】:我正在尝试使用 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... 可以叫我看看有什么问题吗
【问题讨论】:
嘿任何人都可以提出一个解决方案请...运行超时 【参考方案1】:对我来说,解决方案是在没有 DNS SRV 的情况下调用 login()
时不要在用户名中包含主机部分,而不是反对 Google Talk 服务。这也是described in the ignite forums.
例如
connection.login("user@jabber.org", "password", "resource");
变成
connection.login("user", "password", "resource");
【讨论】:
【参考方案2】:Ignite 有一个巨大的线程来处理这个问题。您可能想看看它,因为有几种适用于 Java 和 android 的解决方案似乎可行。
【讨论】:
是的,我尝试了那里给出的所有解决方案,但都没有奏效...在论坛上发布了问题,但没有回复【参考方案3】:我已使用 DIGEST-MD5 成功连接到 facebook,您发布的代码看起来不错。 但是我们仍然需要检查您的 SASLDigestMD5Mechanism 类的内容
我已经成功使用了这里提供的类
http://community.igniterealtime.org/message/200878#200878
您还必须注意,在 DIGEST-MD5 机制中,您必须使用 facebook 用户名 而不是电子邮件地址登录。默认情况下,Facebook 帐户没有用户名,您必须先创建一个,您可以在此处查看:
http://www.facebook.com/username/
【讨论】:
【参考方案4】: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;
【讨论】:
以上是关于使用 Smack 集成 facebook 聊天时 SASL 身份验证失败的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用 smack 连接 facebook 聊天时出现此错误
用于 Facebook 聊天的 Asmack 不适用于 PrivacyListManager