版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載最域。
轉(zhuǎn)載請(qǐng)表明出處:http://www.reibang.com/p/9230b8217d07
快速導(dǎo)航,簡(jiǎn)單來(lái)個(gè)目錄圖片。
前言
繼上一篇博客Android平臺(tái)使用Smack后锈麸,這次咱們來(lái)分享一下在集成過(guò)程中SASL認(rèn)證的一些坑=_=镀脂。
在此為后面的smack學(xué)習(xí)做筆記,以作備忘忘伞。
以下是本次采用的Demo環(huán)境:
- Openfire 3.8.2
- smack 4.2.1
登錄成功后發(fā)現(xiàn)jid變成 亂碼@亂碼
一般發(fā)生這種問(wèn)題薄翅,在登錄時(shí)是沒(méi)問(wèn)題的,但是當(dāng)你想發(fā)送消息時(shí)氓奈,你會(huì)發(fā)現(xiàn)接收消息方的名字居然是亂碼翘魄,下面我來(lái)說(shuō)一下為什么會(huì)登錄成功,但是發(fā)送消息亂碼舀奶。
解決方案
解決方案很簡(jiǎn)單暑竟,僅需在調(diào)用connection.Login()
函數(shù)前先調(diào)用SASLAuthentication.blacklistSASLMechanism("ANONYMOUS");
,把ANONYMOUS
加入黑名單即可育勺,下面討論一下為什么會(huì)發(fā)生這種情況但荤。
如何證實(shí)
如何證實(shí)呢?咱們來(lái)看一下連接socket后的第二條報(bào)文:
<?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>
從上面的報(bào)文可以看到服務(wù)器支持的 SASL 認(rèn)證機(jī)制只有三種(你們的服務(wù)器不一定和我返回的認(rèn)證機(jī)制一樣涧至,這里只是打個(gè)比方)腹躁,但是當(dāng)你想設(shè)置PLAIN
認(rèn)證方式時(shí),你會(huì)在API中發(fā)現(xiàn)居然沒(méi)有設(shè)置唯一認(rèn)證方式化借,且無(wú)法設(shè)置優(yōu)先級(jí)潜慎,因?yàn)?code>ANONYMOUS的排序比PLAIN
的順序前,所以SDK直接返回了ANONYMOUS
,下面來(lái)看一下SASLAuthentication
的Sasl認(rèn)證是怎么做的:
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);
}
通過(guò)以上源碼咱們發(fā)現(xiàn)乘综,無(wú)非就是String.contains()
函數(shù)進(jìn)行匹配字符串憎账,那么問(wèn)題來(lái)了,如果ANONYMOUS
的排序比PLAIN
的順序前卡辰,則直接返回ANONYMOUS
胞皱,怎么看到系統(tǒng)的SASLMechanism
排序呢?咱們?cè)賮?lái)看下面的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已經(jīng)發(fā)現(xiàn)問(wèn)題所在了九妈,Prio
是優(yōu)先級(jí)反砌,ANONYMOUS
的優(yōu)先級(jí)明顯高于PLAIN
、DIGEST-MD5
萌朱、X-OAUTH2
等宴树。
小知識(shí)
ANONYMOUS
級(jí)別官方解釋是,匿名登錄晶疼,所以產(chǎn)生的JID是隨機(jī)生成的酒贬。
結(jié)尾
本篇博客簡(jiǎn)單描述了如何解決SASL認(rèn)證的一個(gè)小坑,歡迎支持冒晰。
引用
最新的smack接入指南鏈接:https://download.igniterealtime.org/smack/docs/latest/documentation/gettingstarted.html/
最新版smack JavaDoc鏈接:https://download.igniterealtime.org/smack/docs/latest/javadoc/