XMPP包含一个认证流的方法,此方法依靠一个简单认证与安全层(SASL)协议[SASL]的XMPP-specific profile。SASL提供一个通常化方法,用于给基于链接的协议加认证支持,而且,XMPP使用一个通常化XML命名空间profile,用于 SASL,听从[SASL]的profiling需求。
如下规则应用:
1) 若是两个服务器间发生SASL协商,直到由服务器宣称的域名系统(DNS)主机名被解析了(参考服务器到服务器通讯(14.4)),通讯才可处理。
2) 若是实始实体可以进行SASL协商,,它必须在初始流头中包含值至少为“1.0”的版本属性。
3) 若是接收实体可以进行SASL协商,它必须在一个<mechanisms/>元素中广告一个或多个认证机制,此元素靠 'urn:ietf:params:xml:ns:xmpp-sasl'命名空间响应从初始实体(若是开放流标记包含所设值至少为“1.0”的版本属性)接收的开放流标记认证。
4) 在SASL协商期间,实体不许在根流元素中发送任何空白字符(匹配[XML]内容,产品[3])做为元素间(任何在SASL例子中的空白字符都只是为了便于阅读)的分隔符;这种限制有助于确保合适的安全层字节精度。
5) 任何包含在XML元素中的XML字符数据,在SASL协商期间使用,必须使用base64编码,编码在RFC3548第三节有定义。
6) 若是所提供的一个“简单用户名”可以被选定SASL机制(例:由DIGEST-MD5与CRAM-MD5机制所支持,但不靠EXTERNAL与 GSSAPI机制所支持)所支持,在认证期间,初始实体应看成为简单用户名提供它的发送域(IP地址或包含在域标识符中的全认证域名)在服务器对服务器的通讯状况下,或是它的已注册账户名(包含在XMPP结点标识符中的用户或结点名)在客户到服务器的通讯状况下。
7) 若是初始实体但愿表明其它实体与支持受权身份传输的被选SASL机制来行动,初始实体在SASL协商期间必须提供一个受权身份。若是初始实体不但愿表明另外一个实体行动,它不许提供一个受权身份。正如[SASL]中指定的,初始实体不许提供一个受权身份,除非一个受权身份不一样于缺省受权身份,此缺省受权身份派生于描述在[SASL]中的认证身份。若是提供了,受权身份值对服务器来讲必须是<domain>值形式(例:只有一个域标识符),对客户端来讲,必须是<node@domain>值形式(例:结点标识符与域标识符)。
8) 靠涉及到安全层协商的SASL协商的成功,接收实体必须抛弃来自自己没有得到SASL协商的初始实体的任何知识。
9) 靠涉及到安全层协商的SASL协商的成功,初始实体必须抛弃来自自己没有得到SASL协商的接收实体的任何知识。
10) 参考必须被支持的相关机制的强制实施技术(14.7)。
6.2叙述
当初始实体使用SASL认证接收实体时,步骤以下:
1) 初始实体请求SASL认证,经过在开放XML流头中包含版本属性,并将其发送给接收实体,属性值设为“1.0”。
2) 发送一个XML流头做为回应后,接收实体广告一个可利用的SASL认证机制列表;列表中每一项都是一个<mechanism/>元素,做为<mechanism/>容器元素的子元素,由'urn:ietf:params:xml:ns:xmpp-sasl'命名空间认证,在流命名空间中,依次是<features/>元素的子元素。若是使用TLS(5)须要在一个特别认证机制可能使用之间创建,接收实体不许提供在 TLS协商以前的可利用SASL认证机制列表中的机制。若是初始实体在TLS协商以前出示了有效证书,接收实体应当在SASL协商(参考[SASL])之间,提供SASL EXTERNAL机制给初始实体,虽然EXTERNAL机制可能在其它环境下被提供了。
3) 初始实体选择一个机制,靠发送一个已被'urn:ietf:params:xml:ns:xmpp-sasl'命名空间认定为合格的<auth/>元素给接收实体,并为‘mechanism’属性包含一个合适的值。若是此机制须要XML字符数据,此元素可能包含XML字符数据(在SASL术语中,“初始响应”);若是初始实体须要发送一个0长度的初始响应,它必须按一个单等号符号(“=”)传输此响应,意味着响应出现,但不包含数据。
4) 若是须要,接收实体靠发送一个<chanllenge/>元素来挑战实始实体,此元素由给初始实体的 'urn:ietf:params:xml:ns:xmpp-sasl'命名空间来限定;此元素可能包含XML字符数据(必须根据由初始实体选择的 SASL机制的定义一致的来计算)。
5) 初始实体响应此挑战,靠发送由'urn:ietf:params:xml:ns:xmpp-sasl'命名空间限定的<response/> 元素给接收实体;此元素可能包含XML字符数据(必须根据由初始实体选择的SASL机制的定义一致的来计算)。
6) 若是须要,接收实体发送更多的挑战,初始实体发送更多的响应。
Challenge/response序列对继续,直到如下三种事情之一发生:
1) 初始实体终止握手,靠发送一个由'urn:ietf:params:xml:ns:xmpp-sasl'命名空间限定的<abort/>元素给接收实体。根据接收一个<abort/>元素,接收实体应当容许一个可配置的但合理的重试号(至少2),以后,必须终止TCP链接;这使初始实体(例:一个终端用户客户端)可以忍受已提供的不正确的信任(例:一个错误类型的password)而不用被迫重连。
2) 接收实体报告握手失败,靠发送一个由'urn:ietf:params:xml:ns:xmpp-sasl'命名空间限定的<failure/>元素给初始实体(失败的特殊缘由应当以<failure/>元素的子元素进行通讯,<failure/>元素定义在SASL错误中(6.4))。若是错误状况发生,接收实体应当容许一个可配置的,但合理的重试号(至少 2),以后,它必须终止TCP链接;这使初始实体(例:一个终端用户客户端)可以忍受已提供的不正确的信任(例:一个错误类型的password)而不用被迫重连。
3) 接收实体报告握手成功,靠发送一个由'urn:ietf:params:xml:ns:xmpp-sasl'命名空间限定的<success/>元素给初始实体;此元素可能包含XML字符数据(在SASL术语中,“additional data with success”),若是须要靠选定的SASL机制。根据接收的<success/>元素,初始实体必须靠发送一个开放的XML流头去初始化一个新流给接收实体(它没必要事先发送一个关闭</stream>标记,由于接收实体与初始实体必须考虑源流根据发送或接收<success/>元素而将被关闭)。根据从初始实体接收的新流头,接收实体必须发送一个新XML流头给初始实体做为响应,并带有任何可利用的特征(但并不包含STARTTLS与SASL特征)或一个空<features/>元素(重要表示没有其它特征可利用);任何那种其它在此未定义的特征必须由XMPP的相关扩展来定义。
6.3 SASL定义
[SASL]的profiling需求要求协议定义提供如下信息:
服务名:“xmpp”
初始序列:初始实体提供一个开放XML流头后,而且接收实体按此响应后,接收实体提供一个可接收的认证方法列表。初始实体从列表中选择一个方法并做为 ‘machanism’属性值发送给接收实体,此属性被<auth/>元素拥有,随意的包括一个初始响应以免环路。
交换序列:挑战与响应经过由接收实体到初始实体<challenge/>元素的交换与由初始实体到接收实体的<response />元素的交换而执行。接收实体靠发送一个<failure/>元素报告错误,发送一个<success/>元素报告成功;初始实体靠发送<abort/>元素终止交换。根据成功协商,两端都认为源XML流将被关而且新流头由两端实体发送。
安全层协商:安全层在为接收实体发送<success/>元素的关闭“>”字符后当即有效,安全层在为初始实体发送<success/>元素的关闭“>”字符后当即有效。层顺序为:首先是[TCP],而后是[TLS],而后是[SASL],而后是 XMPP。
使用受权身份:受权身份能够被XMPP用于指示客户端非缺省<node@domain>或服务器发送<domain>。
6.4 SASL错误
如下是SASL相关错误条件的定义:(略)
1)<aborted/>--
2)<incorrect-encoding/>--
3)<invalid-authzid/>--
4)<invalid-mechanism/>--
5)<mechanism-too-weak/>--
6)<not-authorized/>--
7)<temporary-auth-failure/>--
6.5 客户端到服务器的例子
如下例子显示了使用SASL受权的客户端与服务器端的数据流,正常状况下,是在TLS协商(注:显示在下面的替换步骤用于显示错误状况的协议;他们并不详尽也不是必要的由本例中数据发送而触发。)成功以后。
步1:客户端初始流给服务器:
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
步2:服务器使用一个流标记做为响应发送给客户端:
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='c2s_234'
from='example.com'
version='1.0'>
步3:服务器通知客户端可利用的认证机制:
<stream:features>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
步4:客户端选择一个认证机制:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
mechanism='DIGEST-MD5'/>
步5:服务器发送一个[BASE64]编码挑战给客户端:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
解码挑战是:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
步5(替换):服务器返回错误给客户端:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<incorrect-encoding/>
</failure>
</stream:stream>
步6:客户端发送一个[BASE64]编码响应挑战:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNoYXJzZXQ9dXRmLTgK
</response>
步7:服务器发送另外一个[BASE64]编码挑战给客户端:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
解码挑战是:
rspauth=ea40f60335c427b5527b84dbabcdfffd
步7(替换):服务器返回错误给客户端:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<temporary-auth-failure/>
</failure>
</stream:stream>
步8:客户端响应挑战:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步9:服务器通知客户端认证成功:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步9(替换):服务器通知客户端认证失败:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<temporary-auth-failure/>
</failure>
</stream:stream>
步10:客户端初始化一个新流给服务器:
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
步11:服务器经过发送流头来响应客户端,伴随有任意另外的特征(或空特征元素):
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='c2s_345'
from='example.com'
version='1.0'>
<stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</stream:features>
6.6服务器到服务器的例子
如下例子显示服务器与服务器使用SASL认证的数据流,正常状况下,是在TLS协商以后(注:如下可替换步骤是由失败状况提供的;他们不是详尽的也不是必要的由数据发送而触发)。
步1:Server1初始化流给Server2:
<stream:stream
xmlns='jabber:server'
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
步2:Server2发送一个流标记响应Server1:
<stream:stream
xmlns='jabber:server'
xmlns:stream='http://etherx.jabber.org/streams'
from='example.com'
id='s2s_234'
version='1.0'>
步3:Server2通知Server1可利用的认证机制:
<stream:features>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>KERBEROS_V4</mechanism>
</mechanisms>
</stream:features>
步4:Server1选择一个认证机制:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
mechanism='DIGEST-MD5'/>
步5:Server2发送一个[BASE64]编码挑战给Server1:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9
ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz
</challenge>
编码挑战是:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
步5(替换):Server2返回错误给Server1
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<incorrect-encoding/>
</failure>
</stream:stream>
步6:Server1发送[BASE64]编码响应挑战:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j
ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j
PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5vcmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNoYXJzZXQ9dXRmLTgK
</response>
解码响应是:
username="example.org",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.org",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
步7:Server2发送另外一个[BASE64]编码挑战给Server1:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
解码挑战是:
rspauth=ea40f60335c427b5527b84dbabcdfffd
步7(替换):Server2返回错误给Server1:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<invalid-authzid/>
</failure>
</stream:stream>
步8:Server1响应挑战:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步8(替换):Server1终止协商:
<abort xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步9:Server2通知Server1成功认证:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步9(替换):Server2通知Server1认证失败:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<aborted/>
</failure>
</stream:stream>
步10:Server1初始化一个新流给Server2:
<stream:stream
xmlns='jabber:server'
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
步11:Server2经过发送一个流头响应Server1,并伴随着其它特征(或空特征元素):
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
from='example.com'
id='s2s_345'
version='1.0'>
<stream:features/>
7.资源绑定
接收实体SASL协商(6)以后,初始实体可能想要或是须要绑定一个特殊资源至那个流。普通的,这仅用于客户端:为了听从在此指定的寻址格式(3)与节传送规则(10),必须有一个资源标识符联合客户端的<node@domain>(便可以由服务器产生也能够由客户应用提供);这确保基于流使用的地址是“全JID”形式<node@domain/resource>。
根据在SASL协商中接收的一个成功指示,客户端必须发送一个新流头给服务器,服务器必须用可利用流特征列表中的内容来响应。特别的,若是服务器须要客户端在SASL成功协商后,将资源绑定到流上,它必须包括一个由在流特征列表中的'urn:ietf:params:xml:ns:xmpp-bind'命名空间限定的空<bind/>元素。成功SASL协商后(不是前),它经过发送响应流的头表示给客户端:
服务器广告资源绑定特征给客户端:
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='c2s_345'
from='example.com'
version='1.0'>
<stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</stream:features>
根据这样的通知,资源绑定是须要的,客户端必须靠送给服务器一个包含由'urn:ietf:params:xml:ns:xmpp-bind' 命名空间限定的,类型“set”(参考IQ语义(9.2.3))的IQ节,将资源绑定到流上。
若是客户端但愿容许服务器表明本身产生资源标识符,它发送一个类型“set”的IQ节,包含一个空<bind/>元素:
客户端请求服务器绑定资源:
<iq type='set' id='bind_1'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</iq>
支持资源绑定的服务器必须能表明一个客户端产生一个资源标识符。由服务器产生的资源标识符必须对<node@domain>是惟一的。若是客户端但愿指定资源标识符,它发送一个类型为“set”的IQ节,包含所需资源的标识符,做为<bind/>元素子元素<resource/>的XML字符数据。
客户端绑定一个资源:
<iq type='set' id='bind_2'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>someresource</resource>
</bind>
</iq>
一旦服务器为客户端产生了一个资源标识符或是接受了由客户端提供的资源标识符,它必须返回一个类型为“result”的IQ节给客户端,必须包含一个<jid>子元素,来为服务器决定的已链接资源指定全JID:
服务器通知客户端成功资源绑定:
<iq type='result' id='bind_2'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<jid>somenode@example.com/someresource</jid>
</bind>
</iq>
服务器应当接受由客户端提供的资源标识符,但可能用一个服务器产生的资源标识符覆盖它;在这种状况,服务器不该当返回一个节错误(例:<forbidden/>)给客户端,取而代之,应当以以上显示的IQ结果,传达产生的资源标识符给客户端。
当客户端提供一个资源标识符,如下节错误条件是可能的(参考节错误(9.3)):
1) 提供的资源标识符不能被与Resourceprep(附录B)一致的服务器处理。
2) 客户端不容许绑定资源到流上(例:由于结点或用户已经达到了在被容许的链接的资源的数目)。
3) 已提供资源标识符已经使用,但服务器并不容许用一样的标识符绑定多链接资源。
用于这些错误条件的协议显示以下。
资源标识符不能被处理:
<iq type='error' id='bind_2'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>someresource</resource>
</bind>
<error type='modify'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
客户端不容许绑定资源:
<iq type='error' id='bind_2'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>someresource</resource>
</bind>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
资源标识符在使用:
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>someresource</resource>
</bind>
<error type='cancel'>
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
若是,完成资源绑定步骤以前,客户端尝试发送一个XML节,而不仅是一个带有由'urn:ietf:params:xml:ns:xmpp-bind'命名空间限定的<bind/>子元素的IQ节,服务器不许处理此节,而且,应当返回一个<not-authorized/>节错误给客户端。
8.服务器回叫
8.1概述
Jabber协议来自于XMPP适用的,包含一个“服务器回叫”方法,用以保护免受域哄骗,所以,使哄骗XML节更困难。服务器回叫并非一个安全机制,而且仅致使服务器身份弱验证(参考服务器到服务器的通讯(14.4)相关方法的安全特性)。域须要健壮的安全性,应当使用TLS与SASL;参考服务器到服务器通讯(4.4)细节。若是SASL用于服务器到服务器的认证,回叫不该当使用,由于它是没必要要的。包含回叫文档主要是出于与现存实现与部署向后兼容的缘由。
服务器回叫方法因域名系统(DNS)存在而成为可能,因为一个服务器可以(正常的)对一个给定域发现受权服务器。由于回叫依靠DNS,域内通讯不许处理,直到由服务器宣称的域名系统(DNS)的主机名被解析(参考服务器到服务器的通讯(14.4))。
服务器回叫是单向的,致使一个方向上一个流身份的(弱)验证。由于服务器回叫不是一个认证机制,经过回叫是不可能进行双向认证的。所以,服务器回叫必须在每一个方向上完成,为了使在两个域间进行双向通讯成为可能。
产生与验证密钥的方法用于服务器回叫,必须考虑被用的主机名,由接收服务器产生的流ID,和由受权服务器的网络秘密知道。流ID在服务器回叫中是严格安全的,而且所以必须是即不可预测也不可重复的(参考[RANDOM]推荐资料相关用于安全观点的随机性。)
任何在回叫协商期间发生的错误必须考虑一个流错误,致使终止流与潜在的TCP链接。协议描述中说明的可能的错误条件以下。
如下术语应用:
1) 源服务器——试图在两个域间创建链接的服务器。
2) 接收服务器——尝试认证源服务器是否按它声明的那样去表达。
3) 受权服务器——回答由源服务器宣称的DNS主机名;对基本环境来讲是源服务器,但在源服务器网络中能够是一个分离的机器。
8.2事件顺序
如下是回叫事件顺序的简单总结:
1) 源服务器创建到接收服务器的链接。
2) 源服务器经过链接,给接收服务器发送‘key’值。
3) 接收服务器创建到认证服务器的链接。
4) 接收服务器向受权服务器发送相同的‘key’值。
5) 受权服务器回答密钥值是否有效。
6) 接收服务器通知源服务器受权是否经过。
咱们能够将事件顺序如下图表示:
Originating Receiving
Server Server
----------- ---------
| |
| establish connection |
| ----------------------> |
| |
| send stream header |
| ----------------------> |
| |
| send stream header |
| <---------------------- |
| | Authoritative
| send dialback key | Server
| ----------------------> | -------------
| | |
| establish connection |
| ----------------------> |
| |
| send stream header |
| ----------------------> |
| |
| send stream header |
| <---------------------- |
| |
| send verify request |
| ----------------------> |
| |
| send verify response |
| <---------------------- |
|
| report dialback result |
| <---------------------- |
| |
8.3协议
服务器间具体协议交互以下:
1) 源服务器创建TCP链接到接收服务器。
2) 源服务器发送流头给接收服务器:
<stream:stream
xmlns:stream='http://etherx.jabber.org/streams'
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'>
注:‘to’与‘from’属性在根流元素中是可选的。包含xmlns:db命名空间声明,名字显示向接收实体指示源服务器支持回叫。若是命名空间名不正确,那么,接收服务器必须产生一个<invalid-namespace/>流错误条件并终止XML流与TCP链接。
3) 接收服务器应当发送一个流头返回给源服务器,包含一个用于交互的惟一的ID:
<stream:stream
xmlns:stream='http://etherx.jabber.org/streams'
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
id='457F9224A0...'>
注:‘to’与‘from’属性在根流元素中是可选的。若是命名空间名不正确,那么源服务器必须产生一个<invalid- namespace/>流错误条件,并终止XML流与TCP链接。并且,接收服务器应当回应,但可能根据适当的安全策略默默终止XML流与TCP链接。然而,若是接收服务器想要处理,它必须发送一个流头返回给源服务器。
4) 源服务器发送一个回叫密钥给接收服务器:
<db:result
to='Receiving Server'
from='Originating Server'>
98AF014EDC0...
</db:result>
注:此密钥并不被接收服务器所检查,由于接收服务器并不保存相关源服务器间会话信息。由源服务器产生的密钥必须部分基于接收服务器在先前步骤提供的ID 值,并部分基于源服务器与受权服务器的保密共享。若是‘to’地址值并不与接收服务器所识别的主机名匹配,那么,接收服务器必须产生一个<host-unknown/>流错误条件并终止XML流与潜在的TCP链接。若是‘from’地址值与带有接收服务器已经创建的链接的域匹配,那么,接收服务器可能选择为新链接产生一个<not-authorized/>流错误条件,而后终止XML流与潜在的与新请求相关的 TCP链接。
5) 接收服务器创建一个TCP链接支持由源服务器宣称的域,做为它链接到受权服务器的结果。(注意:做为优化,一个实现可能重用一个现存的链接。)
6) 接收服务器发送给受权服务器一个流头:
<stream:stream
xmlns:stream='http://etherx.jabber.org/streams'
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'>
注:在根流元素中,‘to’与‘from’属性是可选的。若是命名空间名不正确,则受权服务器必须产生一个<invalid-namespace/>流错误条件并终止两个XML流与潜在的TCP链接。
7) 受权服务器发送给接收服务器一个流头:
<stream:stream
xmlns:stream='http://etherx.jabber.org/streams'
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
id='1251A342B...'>
注:若是命名空间名不正确,则接收服务器必须产生一个<invalid-namespace/>流错误条件并终止它与受权服务器间的两个 XML流与潜在的TCP链接。若是流错误发生在接收服务器与受权服务器间,则接收服务器必须产生一个<remote-connection- failed/>流错误条件并终止它与发起服务器间的两个XML流与潜在的TCP链接。
8) 接收服务器发给受权服务器要求认证密钥的请求:
<db:verify
from='Receiving Server'
to='Originating Server'
id='457F9224A0...'>
98AF014EDC0...
</db:verify>
注:通过这儿的是来自接收服务器的流头的主机名、源标识符,到步骤3中的发起服务器,源服务器发送给接收服务器的密钥在步骤4。根据这些信息,还有受权服务器网络中的共享密钥信息,密钥被验证。任何验证方法可能用于产生密钥。若是‘to’地址值与受权服务器识别的主机名不匹配,那么,受权服务器必须产生一个<host-unknown/>流错误条件并终止两个XML与潜在的TCP链接。若是‘from’地址值与源服务器打开TCP链接时(或任意相关有效域,例如接收服务器的主机名或其它有效域一个有效子域)所表示的主机名不匹配,则受权服务器必须产生一个<invalid- from/>流错误条件并终止两个XML流与潜在的TCP链接。
9) 受权服务器验证密钥是否有效
<db:verify
from='Originating Server'
to='Receiving Server'
type='valid'
id='457F9224A0...'/>
或
<db:verify
from='Originating Server'
to='Receiving Server'
type='invalid'
id='457F9224A0...'/>
注:若是ID与步骤3中的接收服务器不匹配,那么接收服务器必须产生一个<invalid-id/>流错误条件并终止两个XML流与潜在的 TCP链接。若是‘to’地址值与接收服务器所识别的主机名不匹配,则接收服务器必须产生一个<host-unknown/>流错误条件并终止两个XML流与潜在的TXP链接。若是‘from’地址值与源服务器打开TCP链接时(或任意相关有效域,例如接收服务器的主机名或其它有效域一个有效子域)所表示的主机名不匹配,则接收服务器必须产生一个<invalid-from/>流错误条件并终止两个XML流与潜在的TCP链接。返回认证信息给接收服务器以后,受权服务器应当终止他们之间的流。
10) 接收服务器通知源服务器结果:
<db:result
from='Receiving Server'
to='Originating Server'
type='valid'/>
注:在这里,链接可经过一个type='valid'或报告为无效来被认证。若是链接无效,则接收服务器必须终止两个XML流与潜在的TCP链接。若是链接被认证,数据可被源服务器发送并被接收服务器读取;在此这前,全部发送给接收服务器的XML节应该默默被扔掉。
前述结果是接收服务器已经认证了源服务器的身份,为了节经过“初始流”(如,从源服务器到接收服务器的流)的XML能被源服务器发送与接收服务器能接收,为了验证使用“响应流”(如,从接收服务器到源服务器)实体的身份,回叫必须以相反方向完成。
成功回叫协调后,接收服务器应当接收来自经过现存已认证链接的源服务器的子序列<db:result/>包(例如,认证需求发送到子域或其它由接收服务器服务主机名);这使在一个方向上的原来的已认证链接的"piggybacking"成为可能。
即便回叫协调成功,服务器必须认证从其它服务器接收的XML节,包括‘from’属性与‘to’属性;若是一个节并不知足此限制,接收节的服务器必须产生一个<improper-addressing/>流错误条件并终止两个XML流与潜在的TCP链接。进一步讲,服务器必须认证从其它服务器,包括流的一个已验证域的‘from’属性;若是节并不知足此限制,收到节的服务器必须产生一个<invalid-from/>流错误条件并终止两个XML流与潜在的TCP链接。这两个检查有助于阻止关联到特别节的哄骗。
本文同步分享在 博客“xiangzhihong8”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。node