1.使用规则:
1.如果SASL协商发生在两台服务器之间,除非服务器宣称的DNS主机名得到解析,不能进行通信。
2.如果初始化实体有能力使用 SASL 协商, 它必须在初始化流的头信息中包含一个值为"1.0"的属性'version'。
3.通过'urn:ietf:params:xml:ns:xmpp-sasl'名字空间中的<mechanisms/>元素声明一个或多个验证机制。
4.当 SASL 协商时, 一个实体不能在流的根元素中发送任何空格符号作为分隔符。
5.当SASL握手时,在XML元素中使用的任何 XML 字符数据必须被编码成 base64, 编码遵循 RFC 3548 第三章的规定。
2.SASL定义
service name(服务名): "xmpp"
initiation sequence(开始序列): 当初始化实体提供一个打开的XML流头信息并且接收实体善意回应之后,接收实体提供一个可接受的验证方法清单。初始化实体从这个清单中选择一个方法,把它作为 <auth/> 元素的 'mechanism' 属性的值发送给接收实体,也可以选择发送一个初始化应答以避免循环。
exchange sequence(交换序列): 挑战和回应的交换,从接收实体发送给初始化实体的 <challenge/> 元素和从初始化实体发送给接收实体的 <response/> 元素信息。接收实体通过发送 <failure/>元素报告失败,发送<success/>元素报告成功;初始化实体通过发送<abort/> 元素中止交换。成功的协商之后,两边都认为原来的XML流已经关闭并且都开始发送新的流头信息。
security layer negotiation(安全层协商): 安全层在接收实体发送 <success/> 元素的关闭字符">"之后立刻生效,在初始化实体发送 <success/> 元素的关闭字符">"之后也立刻生效。层的顺序是 \[TCP\],\[TLS\],然后是 \[SASL\],然后是 \[XMPP\]。
use of the authorization identity(授权ID的使用): 授权ID可在xmpp中用于表示一个客户端的非缺省的<node@domain>,或一个服务器的<domain> 。
3.SASL 错误
<aborted/> -- 接收实体认可由初始化实体发送的<abort/>元素;在回应一个<abort/>元素时发送。
<incorrect-encoding/> -- 由初始化实体提供的数据无法处理,因为[BASE64]编码不正确(例如,因为编码不符合[BASE64]的第三章); 在回应一个包含初始化响应数据的<response/> 元素或<auth/>元素时发送.
<invalid-authzid/> -- 由初始化实体提供的授权id是非法的,因为它的格式不正确或初始化实体无权给那个ID授权;在回应一个包含初始化响应数据的<response/> 元素或<auth/>元素时发送。
<invalid-mechanism/> -- 初始化实体不能提供一个机制活、或请求一个不被接受实体支持的机制;在回应一个<auth/>元素时发送。
<mechanism-too-weak/> -- 初始化实体请求的机制比服务器策略对它的要求弱;在回应一个包含初始化响应数据的<response/> 元素或<auth/>元素时发送。
<not-authorized/> -- 验证失败,因为初始化实体没有提供合法的credentials(这包括但不限于未知用户名等情形);在回应一个包含初始化响应数据的<response/> 元素或<auth/>元素时发送。
<temporary-auth-failure/> -- 验证失败,因为接收实体出现了临时的错误;在回应一个<response/> 元素或<auth/>元素时发送。
4.实例
客户端--服务器
客户端向服务器发送初始化流
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
服务器响应并返回可用的验证机制(清单)
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='c2s_234'
from='example.com'
version='1.0'>
<stream:features>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
客户端选择一个机制
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
mechanism='DIGEST-MD5'/>
此处有两种可能:
成功
服务器返回一个BASE64的挑战
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi
LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
解码后的挑战信息是:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
失败
服务器返回一个错误给客户端
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<incorrect-encoding/>
</failure>
</stream:stream>
继续
客户端返回一个response到服务器(也是BASE64)
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i
LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
YXJzZXQ9dXRmLTgK
</response>
解码后的response内容是
username="somenode",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.com",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
此处有两种可能
服务器判断response有效
在发送一个challenge给客户端
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
编码后是
rspauth=ea40f60335c427b5527b84dbabcdfffd
服务器判断response无效
返回一个错误信息
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<temporary-auth-failure/>
</failure>
</stream:stream>
继续
此处有两种可能
客户端接受挑战
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
客户端不接受挑战,放弃协商
<abort xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
服务器通知客户端验证成功
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
或验证失败
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<temporary-auth-failure/>
</failure>
</stream:stream>
如果是客户端终止协商 (abort)
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<aborted/>
</failure>
</stream:stream>
继续
客户端重新发送一个初始化流到服务器
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
服务器相应客户端并附上feature
<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>
服务器--服务器相似