Xmpp学习之Smack发送消息JID变乱码
快速导航,简单来个目录图片。
前言
继上一篇博客Android平台使用Smack后,这次咱们来分享一下在集成过程中SASL认证的一些坑=_=。
在此为后面的smack学习做笔记,以作备忘。
以下是本次采用的Demo环境:
- Openfire 3.8.2
- smack 4.2.1
登录成功后发现jid变成 乱码@乱码
一般发生这种问题,在登录时是没问题的,但是当你想发送消息时,你会发现接收消息方的名字居然是乱码,下面我来说一下为什么会登录成功,但是发送消息乱码。
解决方案
解决方案很简单,仅需在调用connection.Login()
函数前先调用SASLAuthentication.blacklistSASLMechanism("ANONYMOUS");
,把ANONYMOUS
加入黑名单即可,下面我来说一下为什么会发生这种情况。
如何证实
如何证实呢?咱们来看一下连接socket后的第二条报文:
<?xml version='1.0' encoding='UTF-8'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams"
xmlns="jabber:client" from="im"
id="e26ece26"
xml:lang="en"
version="1.0">
<stream:features>
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">
</starttls>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>PLAIN</mechanism>
<mechanism>ANONYMOUS</mechanism>
<mechanism>JIVE-SHAREDSECRET</mechanism>
</mechanisms>
<compression xmlns="http://jabber.org/features/compress">
<method>zlib</method>
</compression>
<auth xmlns="http://jabber.org/features/iq-auth"/>
<register xmlns="http://jabber.org/features/iq-register"/>
</stream:features>
从上面的报文可以看到服务器支持的 SASL 认证机制只有三种(你们的服务器不一定和我返回的认证机制一样,这里只是打个比方),但是当你想设置PLAIN
认证方式时,你会在API中发现居然没有设置唯一认证方式,且无法设置优先级,因为ANONYMOUS
的排序比PLAIN
的顺序前,所以SDK直接返回了ANONYMOUS
,下面来看一下SASLAuthentication
的Sasl认证是怎么做的:
Iterator<SASLMechanism> it = REGISTERED_MECHANISMS.iterator();
final List<String> serverMechanisms = getServerMechanisms();
、、、
// Iterate in SASL Priority order over registered mechanisms
while (it.hasNext()) {
SASLMechanism mechanism = it.next();
String mechanismName = mechanism.getName();
、、、
、、、
if (serverMechanisms.contains(mechanismName)) {
/* Create a new instance of the SASLMechanism
for every authentication attempt.
return*/
mechanism.instanceForAuthentication(connection,
configuration);
}
通过以上源码咱们发现,无非就是String.contains()
函数进行匹配字符串,那么问题来了,如果ANONYMOUS
的排序比PLAIN
的顺序前,则直接返回ANONYMOUS
,怎么看到系统的SASLMechanism
排序呢?咱们再来看下面的log:
W/System.err: org.jivesoftware.smack.SmackException:
No supported and enabled SASL Mechanism provided by server.
Server announced mechanisms:
[PLAIN, ANONYMOUS, JIVE-SHAREDSECRET].
Registerd SASL mechanisms with Smack: [
SASL Mech:
SCRAM-SHA-1-PLUS, Prio: 100,
SASL Mech: SCRAM-SHA-1, Prio: 110,
SASL Mech: DIGEST-MD5, Prio: 210,
SASL Mech: PLAIN, Prio: 410,
SASL Mech: X-OAUTH2, Prio: 410,
SASL Mech: ANONYMOUS, Prio: 500,
SASL Mech: EXTERNAL, Prio: 510
]. Enabled SASL mechansisms for this connection: [PLAIN].
Blacklisted SASL mechanisms: [PLAIN, SCRAM-SHA-1-PLUS].
相信大家看到上面的log已经发现问题所在了,Prio
是优先级,ANONYMOUS
的优先级明显高于PLAIN
、DIGEST-MD5
、X-OAUTH2
等。
小知识
ANONYMOUS
级别官方解释是,匿名登录,所以产生的JID是随机生成的。
结尾
本篇博客简单描述了如何解决SASL认证的一个小坑,欢迎支持。
引用
最新的smack接入指南链接:https://download.igniterealtime.org/smack/docs/latest/documentation/gettingstarted.html/
最新版smack JavaDoc链接:https://download.igniterealtime.org/smack/docs/latest/javadoc/