通过ejabberd的日志,整理了下客户端登录流程。

1. 通过TCP连接5222端口的流程:

(1) 客户端向服务器发送stream流

<stream:stream to="nba.com"
xml:lang="*"
version="1.0"
xmlns:stream="http://etherx.jabber.org/streams"
xmlns="jabber:client">

(2) 服务器应答stream

<?xml version='1.0'?>
<stream:stream xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='4171758611'
from='nba.com'
version='1.0'
xml:lang='en'>

(3) 服务器发送流特性

<stream:features>
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>PLAIN</mechanism>
</mechanisms>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
node='http://www.process-one.net/en/ejabberd/'
ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/>
<register xmlns='http://jabber.org/features/iq-register'/>
</stream:features>

(4) 客户端发送tls请求

<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>

(5) 服务器回应并开始TLS握手

<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

(6) TLS握手完成后,客户端重新初始化stream流

<stream:stream to="nba.com"
xml:lang="*"
version="1.0"
xmlns:stream="http://etherx.jabber.org/streams"
xmlns="jabber:client">

(7) 服务器应答

<?xml version='1.0'?>
<stream:stream xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='703708799'
from='nba.com'
version='1.0'
xml:lang='en'>

(8) 服务器告知客户端支持的SASL验证机制

<stream:features>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>PLAIN</mechanism>
</mechanisms>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
node='http://www.process-one.net/en/ejabberd/'
ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/>
<register xmlns='http://jabber.org/features/iq-register'/>
</stream:features>

(9) 客户端选择简单认证机制并发送用户名密码

<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AG1iZWQAbWlycm9y</auth> 

(10) 服务器告诉客户端校验通过,SASL握手完成

<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

(11) 客户端再次初始化stream流

<stream:stream to="nba.com"
xml:lang="*"
version="1.0"
xmlns:stream="http://etherx.jabber.org/streams"
xmlns="jabber:client">

(12) 服务器应答

<?xml version='1.0'?>
<stream:stream xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='2767342509'
from='nba.com'
version='1.0'
xml:lang='en'>

(13) 通知客户端进行资源绑定

<stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
node='http://www.process-one.net/en/ejabberd/'
ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/>
<register xmlns='http://jabber.org/features/iq-register'/>
</stream:features>

(14) 客户端请求资源绑定

<iq type="set" id="0">
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
<resource>boston</resource>
</bind>
</iq>

(15) 服务器应答

<iq id='0' type='result'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<jid>rondo@nba.com/boston</jid>
</bind>
</iq>

(16) 客户端请求session绑定

<iq type="set" id="1">
<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</iq>

(17) 服务器应答

<iq type='result' id='1'>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</iq>

至此,可认为登陆完成,后续进行能力协商,发送其他请求消息,发送出息消息等。

2. 通过http连接5280端口的流程

http方式的交互是通过BOSH协议完成的,详细可参见

http://xmpp.org/extensions/xep-0124.html

http://xmpp.org/xmpp-protocols/xmpp-extensions/

具体流程为:

(1) 发起bosh会话

<body rid='16488487'
xmlns='http://jabber.org/protocol/httpbind'
to='nba.com'
xml:lang='en'
wait='60'
hold='1'
content='text/xml;charset=utf-8'
ver='1.6'
xmpp:version='1.0'
xmlns:xmpp='urn:xmpp:xbosh'/>

(2) 服务器应答

<body xmlns='http://jabber.org/protocol/httpbind'
sid='90582e464361adb537351e65ecfa66d1336ea486'
wait='60'
requests='2'
inactivity='30'
maxpause='120'
polling='2'
ver='1.8'
from='nba.com'
secure='true'
authid='1145683568'
xmlns:xmpp='urn:xmpp:xbosh'
xmlns:stream='http://etherx.jabber.org/streams'
xmpp:version='1.0'>
<stream:features xmlns:stream='http://etherx.jabber.org/streams'>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>PLAIN</mechanism>
</mechanisms>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
node='http://www.process-one.net/en/ejabberd/'
ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/>
<register xmlns='http://jabber.org/features/iq-register'/>
</stream:features>
</body>

(3) 客户端发送用户名密码

<body rid='16488488'
xmlns='http://jabber.org/protocol/httpbind'
sid='90582e464361adb537351e65ecfa66d1336ea486'>
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>
AGNoZW53ZW5jYW4ja2VkYWNvbS5jb20AMjEyMThjY2E3NwgzNGQyYmExOTIyYzMzZTAxNTExMDU=
</auth>
</body>

(4) 服务器响应告知校验结果

<body xmlns='http://jabber.org/protocol/httpbind'>
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
</body>

(5) 客户端重新初始化stream流

<body rid='16488489'
xmlns='http://jabber.org/protocol/httpbind'
sid='90582e464361adb537351e65ecfa66d1336ea486'
to='nba.com'
xml:lang='en'
xmpp:restart='true'
xmlns:xmpp='urn:xmpp:xbosh'/>

(6) 服务器通知完成资源绑定

<body xmlns='http://jabber.org/protocol/httpbind'
sid='90582e464361adb537351e65ecfa66d1336ea486'
wait='60'
requests='2'
inactivity='30'
maxpause='120'
polling='2'
ver='1.8'
from='nba.com'
secure='true'
authid='3855745118'
xmlns:xmpp='urn:xmpp:xbosh'
xmlns:stream='http://etherx.jabber.org/streams'
xmpp:version='1.0'>
<stream:features xmlns:stream='http://etherx.jabber.org/streams'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
node='http://www.process-one.net/en/ejabberd/'
ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/>
<register xmlns='http://jabber.org/features/iq-register'/>
</stream:features>
</body>

(7) 客户端请求资源绑定

<body rid='16488490'
xmlns='http://jabber.org/protocol/httpbind'
sid='90582e464361adb537351e65ecfa66d1336ea486'>
<iq type='set' id='_bind_auth_2' xmlns='jabber:client'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>boston</resource>
</bind>
</iq>
</body>

(8) 服务器应答

<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns='jabber:client' id='_bind_auth_2' type='result'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<jid>rondo@nba.com/boston</jid>
</bind>
</iq>
</body>

(9) 客户端请求session绑定

<body rid='16488491'
xmlns='http://jabber.org/protocol/httpbind'
sid='90582e464361adb537351e65ecfa66d1336ea486'>
<iq type='set' id='_session_auth_2' xmlns='jabber:client'>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</iq>
</body>

(10) 服务器应答

<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns='jabber:client' id='_session_auth_2' type='result'>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</iq>
</body> 分析:

 SASL 交涉

Client 客户端需要选择一个服务器上有效的认证方式来携带SASL交涉数据, 上面的情况, “DIGEST-MD5“, “PLAIN” 和 “EXTERNAL” 是一些可选项.

“PLAIN” 认证模式是三者之中最简单的了. 它是这样工作的:

Client: 客户端按照自己选择的认证模式发送一个将用户名和密码以base64编码的 stream. 用户名和密码按这种格式组织:

    “\0UserName\0Password”.

例如我想以用户名为“mbed@ceit.org”登录, 密码是“mirror”. 那么, 在进行base64编码之前, 用户名和密码按照上面的格式组织为一个新的字符串,“\0mbed\0mirror”, 再进行base64编码, 得到字符串“AG1iZWQAbWlycm9y”.

然后, 客户端发送下列 stream 到服务器.

 <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AG1iZWQAbWlycm9y</auth>  

代码如下:
直接base64 编码decode,可看到用户名和密码。

ejabberd日志分析客户端登录流程的更多相关文章

  1. Cas_Java客户端登录相关过滤器的处理流程

    首先了解一下CAS登录原理: 1.CAS结构中一般包含CAS服务器(Cas验证服务器).应用服务器(程序所在服务器).客户端(web浏览器)三个部分. 2.客户端向应用服务器发出请求,由于未登录,会被 ...

  2. Netty源码分析第3章(客户端接入流程)---->第1节: 初始化NioSockectChannelConfig

    Netty源码分析第三章: 客户端接入流程 概述: 之前的章节学习了server启动以及eventLoop相关的逻辑, eventLoop轮询到客户端接入事件之后是如何处理的?这一章我们循序渐进, 带 ...

  3. Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建

    Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...

  4. Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建

    Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...

  5. Netty源码分析第3章(客户端接入流程)---->第4节: NioSocketChannel注册到selector

    Netty源码分析第三章: 客户端接入流程 第四节: NioSocketChannel注册到selector 我们回到最初的NioMessageUnsafe的read()方法: public void ...

  6. Netty源码分析第3章(客户端接入流程)---->第5节: 监听读事件

    Netty源码分析第三章: 客户端接入流程 第五节: 监听读事件 我们回到AbstractUnsafe的register0()方法: private void register0(ChannelPro ...

  7. netty服务端客户端启动流程分析

    服务端启动流程 我们回顾前面讲解的netty启动流程,服务端这边有两个EventLoopGroup,一个专门用来处理连接,一个用来处理后续的io事件 服务端启动还是跟nio一样,绑定端口进行监听,我们 ...

  8. ELK5.3日志分析平台&部署

    https://www.cnblogs.com/xing901022/p/6030296.html ELK简介: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现 ...

  9. ELK、ELFK企业级日志分析系统

    ELK.ELFK企业级日志分析系统 目录 ELK.ELFK企业级日志分析系统 一.ELK日志分析系统 1. ELK简介 1.2 ElasticSearch 1.3 Logstash 1.4 Kiban ...

随机推荐

  1. request.setAttribute()、session.setAttribute()和request.getParameter()的联系与区别

    1.session.setAttribute()和session.getAttribute()配对使用,作用域是整个会话期间,在所有的页面都使用这些数据的时候使用. 2.request.setAttr ...

  2. 告别 MongoDB 2.x 拥抱 3.x 版本的5大理由(转)

    据不完全统计,目前还有很多同学在生产环境使用着 MongoDB 2.x 版本的服务,偶尔也会听到一些抱怨,但有些抱怨其实很没道理,因为抱怨的问题在最新版本的MongoDB里已经解决了,你缺的只是一次版 ...

  3. Block为什么使用Copy?

    block:本质就是一个object-c对象block:存储位置,可能分为3个地方:代码去,堆区.栈区(ARC情况下会自动拷贝到堆区,因此ARC下只能有两个地方:代码去.堆区)代码区:不访问栈区的变量 ...

  4. 10.1综合强化刷题 Day7

                                                                                       noip提高组模拟赛       ...

  5. Algorithm | Random

    随机生成[0,n)中不重复的m个数. class Random { public: Random(int n, int m):n(n), m(m) {} void generate() { srand ...

  6. PHP处理Android的POST数据

    今天用PHP开发Android网络数据接口的时候,发现Thinkphp的I函数(php的$_POST)并不能获取到androidpost过来的数据 Android代码如下: Map<String ...

  7. Jenkins强制设置语言为中文

    解决方法如下: 1.使用中文版的google浏览器,并确定把语言设置成了中文.语言配置在设置页.如下: 2.直接设置jenkins的语言.强制性. 前提:先安装插件:Locale plugin 配置如 ...

  8. Oracle递归操作

    需求:找出代理商中没有挂商家的代理商 简单SQL如下: select * from t_proxy tp where tp.id not in (SELECT tp.id as p_id FROM t ...

  9. 2016.6.21 maven使用cmd新建项目时,failed to execute goal org.apache.maven.plugins:maven-archetye-plugin:2.4:generate...

    在学习maven的时候,想要新建一个maven工程,在命令行执行create或generate命令. 错误如图所示: failed to execute goal org.apache.maven.p ...

  10. 有趣的HTML5/CSS3艺术网站

    http://www.html5tricks.com/ 2017年8月31日08:16:21