Gloox 注册用户

改定履历

2011-09-09---------------------新建文本文档


引文:

调试GLOOX 1.0的注册功能颇费了一些功夫。总体逻辑如GLOOX自带的例子一样是毫无疑问的,但是照搬例子又是不能完成注册的,返回错误码为4------RegistrationBadRequest。笔者一开始在网上狂搜解决方案,资料少之又少,有建议重写Client::handleNormalNode函数(目的是禁止SASL认证)的,有直接继承Client重写Client::handleNormalNode函数的,但都没说到点子上。经过一段时间的研究,在GLOOX的maillist上得到启发,顺利完成注册。现将解决方案记录下来:


环境

客户端:GLOOX1.0 VS2008

服务器:OPENFIRE 默认安装


对于GLOOX自带的注册例子不能正常注册的问题有人在邮件列表里提出来。一个哥们这样回答:

[plain]  view plain copy
  1. Ok, I've found what the problem was 
  2. In openFire server parameters, Anonymous Login => Disabled !!! 
[plain]  view plain copy
  1. Ok, I've found what the problem was  
  2. In openFire server parameters, Anonymous Login => Disabled !!!  

意思是要 禁用openFire服务器里的选项”注册和登录“的”匿名登录“项

笔者按此说明禁用该选项,果然注册成功。

这说明开始的注册失败是和匿名登录有关系的。我们来看一下引用registration_expmple例子登录失败时的XML流:

S->C:服务器返回给客户端支持的认证机制:

[html]  view plain copy
  1. <stream:features xmlns:stream='http://etherx.jabber.org/streams'><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns='http://jabber.org/features/compress'><method>zlib</method></compression><authxmlns='http://jabber.org/features/iq-auth'/><register xmlns='http://jabber.org/features/iq-register'/></stream:features> 
[html]  view plain copy
  1. <stream:features xmlns:stream='http://etherx.jabber.org/streams'><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>CRAM-MD5</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>  

从上面XML流中我们可以看到,默认openFire支持四种认证机制,分别是:DIGEST-MD5、PLAIN、ANONYMOUS、CRAM-MD5。然后我们看GLOOX客户端的响应流:

C->S:客户端返回选择的认证方式:

[html]  view plain copy
  1. <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/> 
[html]  view plain copy
  1. <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>  
可以看出,客户端”无耻“的选择了”匿名“-- 'ANONYMOUS'方式

接下来的流程就是客户端”无耻“的选择了以匿名的方式登录了服务器,然后再发送注册请求,请求如下:

[html]  view plain copy
  1. <iq id='uid:4e69eccd:00006784' type='set' from='447e0585@zxl/447e0585' xmlns='jabber:client'><queryxmlns='jabber:iq:register'><username>bbaxiao</username><password>123456</password><name>test2</name><email>163@gmail.com</email></query></iq> 
[html]  view plain copy
  1. <iq id='uid:4e69eccd:00006784' type='set' from='447e0585@zxl/447e0585' xmlns='jabber:client'><query xmlns='jabber:iq:register'><username>bbaxiao</username><password>123456</password><name>test2</name><email>163@gmail.com</email></query></iq>  

我们看到,IQ节里包含“form”属性,即客户端匿名身份标识。

注意,一个客户端已经以一个身份(由服务器临时分配的一个JID)登录,建立了会话,在服务器上我们会看到这个会话,并且服务器发送心跳一直维护这个会话。这种情况下,这个客户端再发送注册请求(另一个身份)建立与服务器的连接是不被允许的。具体请参考XEP-0077(In-Band Registration):我们关注这两段:

[plain]  view plain copy
  1. If the entity cancels its registration with its "home" server (i.e., the server at which it has maintained its XMPP account), then the entity SHOULD NOT include a 'from' or 'to' address in the remove request the server SHOULD then return a <not-authorized/> stream error and terminate all active sessions for the entity. The server SHOULD perform the remove based on the bare JID <localpart@domain.tld> associated with the current session or connection over which it received the remove request. If the server is an instant messaging and presence server that conforms to XMPP IM [8], the server SHOULD also cancel all existing presence subscriptions related to that entity (as stored in the entity's roster). 
  2.  
  3. If the entity cancels its registration with a service other than its home server, its home server MUST stamp a 'from' address on the remove request, which in accordance with XMPP Core will be the entity's full JID <localpart@domain.tld/resource>. The service MUST perform the remove based on the bare JID <localpart@domain.tld> portion of the 'from' address. 
[plain]  view plain copy
  1. If the entity cancels its registration with its "home" server (i.e., the server at which it has maintained its XMPP account), then the entity SHOULD NOT include a 'from' or 'to' address in the remove request the server SHOULD then return a <not-authorized/> stream error and terminate all active sessions for the entity. The server SHOULD perform the remove based on the bare JID <localpart@domain.tld> associated with the current session or connection over which it received the remove request. If the server is an instant messaging and presence server that conforms to XMPP IM [8], the server SHOULD also cancel all existing presence subscriptions related to that entity (as stored in the entity's roster).  
  2.   
  3. If the entity cancels its registration with a service other than its home server, its home server MUST stamp a 'from' address on the remove request, which in accordance with XMPP Core will be the entity's full JID <localpart@domain.tld/resource>. The service MUST perform the remove based on the bare JID <localpart@domain.tld> portion of the 'from' address.  

意思是说注册请求不能包含“from”属性。

正常的注册流如下:

[html]  view plain copy
  1. <iq id='uid:4e69eccd:00003d6c' type='set' xmlns='jabber:client'><query xmlns='jabber:iq:register'><username>bbaxiao</username><password>123456</password><name>test2</name><email>163@gmail.com</email></query></iq> 
[html]  view plain copy
  1. <iq id='uid:4e69eccd:00003d6c' type='set' xmlns='jabber:client'><query xmlns='jabber:iq:register'><username>bbaxiao</username><password>123456</password><name>test2</name><email>163@gmail.com</email></query></iq>  

---------------------------

综上所述,解决方案如下:

一、关闭openFire的匿名登录功能。^_^……

二、禁止GLOOX匿名认证功能。

[cpp]  view plain copy
  1. file:client.cpp 
  2.  
  3. fun: int Client::getSaslMechs( Tag* tag ) 
  4.  
  5. line:355 
  6.  
  7. 将355行注释掉即可。 
  8. 354:if( tag->hasChildWithCData( mech, "ANONYMOUS" ) ) 
  9. 355      //mechs |= SaslMechAnonymous; 
[cpp]  view plain copy
  1. file:client.cpp  
  2.   
  3. fun: int Client::getSaslMechs( Tag* tag )  
  4.   
  5. line:355  
  6.   
  7. 将355行注释掉即可。  
  8. 354:if( tag->hasChildWithCData( mech, "ANONYMOUS" ) )  
  9. 355      //mechs |= SaslMechAnonymous;  

重新编译生成DLL即可。

三、手动设置GLOOX客户端SASL认证机制

在调用j->connect()之前设置SASL认证机制,比如设置为“DIGEST-MD5”

[cpp]  view plain copy
  1. j->setSASLMechanisms(SaslMechDigestMd5); 
[cpp]  view plain copy
  1. j->setSASLMechanisms(SaslMechDigestMd5);  
这种方式的缺点是需要先确定服务器支持的认证机制。

四、根据XEP-0077所述,即使其名登录,注册流只要不带“from”属性应该也可以。所以我们要处理发出的注册流,去除“from”属性重新发送注册流即可。


-------------------------------------------------------------------------------------------------------------

自行记录:

禁止服务器匿名登录功能,注册成功。

注册功能的协议为:

gloox拓展协议 xep-0077  地址:http://wiki.jabbercn.org/XEP-0077

名词解释

带内注册指的是未在你的服务器上开通账号的用户可以通过xmpp协议注册新账号。相反的概念是带外注册(out-of-band registration),例如
你必须到某个指定的web页面进行注册。
如果服务器允许带内注册,那么我们就可以通过自己开发的客户端注册新账号。


openfire 服务器的 服务器设置-注册和登录有关于带内注册的设置

流程:

首先登录openfire服务器(只提供服务器域名就可以)-- 与服务器成功建立链接(没有具体的用户,sasl没有执行)-- 申请注册新用户--服务器返回需要提供的字段-- 客户端发送注册用的字段--注册成功。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值