注册模块的错误解决

来源:互联网 发布:cad工程量计算软件 编辑:程序博客网 时间:2024/05/27 20:36

今天在弄注册模块的时候发现注册不了,,为了方便直接用了openfire。。然后问题就来 了,return错误码为4------RegistrationBadRequest;百度了下,找到解决的办法如下:

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

[plain] view plaincopy
  1. Ok, I've found what the problem was 
  2. In openFire server parameters, Anonymous Login => Disabled !!! 
[plain] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/> 
[html] view plaincopy
  1. <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>  
可以看出,客户端”无耻“的选择了”匿名“--'ANONYMOUS'方式

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

[html] view plaincopy
  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> 
[html] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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> 
[tml] view plaincopy
  1. <iq id='uid:4e69eccd:00003d6c' type='set' xmlns='jabber:client'><query xmlns='jabber:iq:register'><username>bbaxiao</username><password>123456</pssword><name>test2</name><email>163@gmail.com</email></query></iq>  

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

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

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

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

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

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

附原地址:

http://blog.csdn.net/abcpanpeng/article/details/7370974
0 0