6.6. Пример сервер-сервер
Следующий пример демонстрирует информационный обмен при аутентификации одного сервера другим при использовании SASL, это в норме может производиться только после завершения согласования применения TLS (заметим: альтернативные шаги, показанные ниже, приведены исключительно с иллюстративной целью).
Шаг 1: Сервер1 инициирует поток к Серверу2:
<stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
Шаг 2: Сервер2 откликается посылкой Серверу1 тэга потока:
<stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_234' version='1.0'>
Шаг 3: Сервер2 информирует Сервер1 о доступных механизмах аутентификации:
<stream:features> <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>DIGEST-MD5</mechanism> <mechanism>KERBEROS_V4</mechanism> </mechanisms> </stream:features>
Шаг 4: Сервер1 выбирает механизм аутентификации:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
Шаг 5: Сервер2 посылает закодированный [BASE64] вызов Серверу1:
<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 (alt): Сервер2 возвращает Серверу1 сообщение об ошибке:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <incorrect-encoding/> </failure> </stream:stream>
Шаг 6: Сервер1 посылает закодированный отклик [BASE64] на вызов:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5v cmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3 LGNoYXJzZXQ9dXRmLTgK </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: Сервер2 посылает еще один закодированный [BASE64] вызов Серверу1:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo= </challenge>
Декодированный вызов имеет вид:
rspauth=ea40f60335c427b5527b84dbabcdfffd
Шаг 7 (alt): Сервер2 возвращает Серверу1 сообщение об ошибке:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <invalid-authzid/> </failure> </stream:stream>
Шаг 8: Сервер1 откликается на вызов:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
Шаг 8 (alt): Сервер1 абортирует согласование:
<abort xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
Шаг 9: Сервер2 информирует Сервер1 об успешной аутентификации:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
Шаг 9 (alt): Сервер2 информирует Сервер1 о неудаче аутентификации:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <aborted/> </failure> </stream:stream>
Шаг 10: Сервер1 инициирует новый поток к Серверу2:
<stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
Шаг 11: Сервер2 откликается посылкой Серверу1 заголовка потока, а также данными о любых дополнительных возможностях (при отсутствии последних посылается пустой элемент):
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_345' version='1.0'> <stream:features/>