客户端使用WS-Discovery协议来发现设备。符合此规范的设备(server)以及客户端(client)必须实现在WS-Discovery中描述的服务。在WS-Discovery中所描述的发现代理(discovery Proxy)并不是必须实现的。本标准定义了一种可支持远程发现的设备发现代理。远程发现依赖于发现代理以及设备供应商提供的具有远程设备发现的设备。
client通过发送probe以去检索通远程服务的Types,scopes,发现远程服务。
WS-Discovery描述了一个独一无二的标识(UUID):对于Endpoint的格式参考2.6节,但是本规范重新定义了此命令。统一的资源Name:(URN:UUID)使用【RFC4122】格式(见7.3.1)。
7.2 工作模式:
设备可设置两个模式:可发现模式;不可发现模式
可发现模式:工作于此模式的设备一旦接入网络或者其状态改变了(依据WS-Discovery所规定的状态)就会广播一条Hello消息出去。另外设备还会一直监听Probe和Resolve消息,一旦接收到这些消息,设备会发送相应的应答报文。工作在不可发现模式的设备是不会发送和应答这些消息的。设备的默认工作模式是可发现模式。为避免阻断式服务攻击,设备可以通过8.3.9节所示的操作将设备设置为不可发现模式。
7.3 设备发现定义
7.3.1 Endpoint
客户端应该使用URN:UUID[RFC4122]来作为设备的 Endpoint refernce地址属性。不论client或者server,都需要一个全球唯一(或者全局唯一)的UUID作为地址标识。结合Wsadis:Address以及Wsadis:ReferenceProperties提供全局唯一的地址标识
7.3.2.Hello
Hello的一些固定的参数:
为最低风险的出现网络风暴,server设备在发送了Hello之后必须等待一段时间。而对于远程设备发现来说server需要没有延迟的发送单播hello,这意味着在远程发现代理的模式下,客户端不必去广播probe而只需单播即可,
规范化的Hello如下所示:
<s:Envelope ... >
<s:Header ... >
<a:Action ... >http://schemas.xmlsoap.org/ws/2005/04/discovery/Hello</a:Action>
<a:MessageID ... >xs:anyURI</a:MessageID>
<a:RelatesTo RelationshipType="d:Suppression" >xs:anyURI</a:RelatesTo>
<a:To ... >urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>
<d:AppSequence ... />
...
</s:Header>
<s:Body ... >
<d:Hello ... >
<a:EndpointReference> ... </a:EndpointReference>
<d:Types>list of xs:QName</d:Types>
<d:Scopes>list of xs:anyURI</d:Scopes>
<d:XAddrs>list of xs:anyURI</d:XAddrs>
<d:MetadataVersion>xs:unsignedInt</d:MetadataVersion>
...
</d:Hello>
</s:Body>
</s:Envelope>
Header是每个SOAP都必须有的。
Action----------------------------------------仅仅为了标识这是一个Hello消息
MessageID--------------------------------hello消息的ID
Header/RelatesTo----------------------在组播probe并且单播Hello的代理发现的模式下此选项必须有(Resolve)。当且仅当采用代理发现模式的时候并且以单播模式回应probe的时候它必须与probe的MessageID属性保持一致。
Header/RelationshipTypes---------RelationshipType="d:Suppression"------->表示此消息抑制probe组播
Header/AppSequence---------------当目标服务允许订阅discovery消息的时候必须包含此选项
Body/EndpointReference----------Client可用于识别目标服务的Server的Endpint Reference
Body/Types-------------------------------server端实现的 可设置类型,如果server端忽略此项则此处无隐含值,
如果使用了远程代理发现,则此项必须明确包含 d:DiscoveryProxy和d:TargetService。
d:DiscoveryProxy标识支持远程代理设备发现,d:TargetService标识所支持的目标服务信息在此endpoint
Body/Scopes----------------------------可设置的目标服务,它或许不只有一个。此选项如果有则其必须为URIs,并且这些URIs中不能包含空格。
如果此项可忽略的话,则此项的隐含值是"http://schemas.xmlsoap.org/ws/2005/04/discovery/adhoc
Body/XAddrs----------------------------与目标服务的通信地址。此处的值为不含空格的URIs
Body/MetadataVersion----------------------------当远程服务的元数据有改变的时候MetadataVersion依次增加>=1。如果远程服务挂掉或者重启的话,这个值只增不减。Metadata并不仅限于
types以及scopes。此数据或许会被client去控制远程服务。具体作用目前本人不是很清楚
为了减少probe的次数,client应该监听hello信息,并存储于远程服务相关的信息。需要注意的是在hello中可能有不同的元数据包,因此client可能收到两个具有相同的Envelope body metadataersion的数据但是却包含不同的metadata。如果用户对元数据进行了缓存,将不能约束下列行为:
1.使用其他方式检索更完整的数据
2.新数据覆盖旧缓存
3.缓存旧缓存于新数据
完整Hello数据包实例:
<s:Envelope
xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"
xmlns:s="http://www.w3.org/2003/05/soap-envelope" >
<s:Header>
<a:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Hello</a:Action>
<a:MessageID>uuid:73948edc-3204-4455-bae2-7c7d0ff6c37c</a:MessageID>
<a:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>
<d:AppSequence InstanceId="1077004800" MessageNumber="1" />
</s:Header>
<s:Body>
<d:Hello>
<a:EndpointReference>
<a:Address>uuid:98190dc2-0890-4ef8-ac9a-5940995e6119</a:Address>
</a:EndpointReference>
<d:MetadataVersion>75965</d:MetadataVersion>
</d:Hello>
</s:Body>
-
</s:Envelope>
7.3.2.1 Types
一个支持onvif的设备一定包含设备管理服务端口类型 ,下面是一个关于此类型的如何整合到SOAP Hello body中的例子。Hello消息或许还包含其他的types.
<d:Types>tds:Device</d:Types>
7.3.2.2 Scopes
一个支持onvif的设备必须包含scope属性在hello消息中,设备的scopes是通过[rfc 3986]URIs来设置的。本标准设置scopes属性如下模式:
(scheme)设计属性:onvif
(authority)授权属性:www.onvif.org
这就意味着所有的onvif的scopes属性的定义要按照片如下的方式去定义:
onvif://www.onvif.org/<path>
设备或许有其他scopes的URi,这些URI并不需要严格遵守onvif的scopes定义的格式
下表定义了一组scopes的参数。除了这些标准化参数外,设备所有者应该设置所有的scopes参数。scopes参数可以按照8.3节所示的命令去列出以及设置scopes参数。
设备至少应该提供一个规定的条目的配置文件。Hardwares以及name应该分别设置,设备也可能拥有其他类型的scopes。也需要列出。设备可能包含任意数码的scopes参数,这意味着,可能一个单元会拥有几个Location scopes。Probe需要匹配此列表中的所有scopes。
BYE
Bye:当一个设备要离开一个网络的时候,设备会广播一个Bye。Bye消息的完整规范格式如下:
-
<s:Envelope ... >
-
<s:Header ... >
-
<a:Action ... >
http://schemas.xmlsoap.org/ws/2005/04/discovery/Bye</a:Action> <a:MessageID ... >xs:anyURI</a:MessageID>
<a:To ...>urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>
<d:AppSequence ... />
...
-
</s:Header>
-
<s:Body ... >
<d:Bye ... >
<a:EndpointReference> ... </a:EndpointReference>
...
</d:Bye>
</s:Body>
-
</s:Envelope>
client应该监听来自服务端的bye消息,并以合法的方式标记删除通信信息。client希望持有远程服务离开网络的信息。例如如果client期待远程服务重新加入网络。相反client可能在出现内存不足,没有可通信的远程服务的任何时间丢弃于远程服务相关的信息。
Bye消息实例:
<s:Envelope
xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"
xmlns:s="http://www.w3.org/2003/05/soap-envelope" >
-
<s:Header>
-
<a:Action>
http://schemas.xmlsoap.org/ws/2005/04/discovery/Bye</a:Action> -
<a:MessageID>
uuid:337497fa-3b10-43a5-95c2-186461d72c9e</a:MessageID> <a:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>
<d:AppSequence InstanceId="1077004800" MessageNumber="4" />
-
</s:Header>
-
<s:Body>
<d:Bye>
-
<a:EndpointReference>
-
<a:Address>
uuid:98190dc2-0890-4ef8-ac9a-5940995e6119</a:Address>
-
</a:EndpointReference>
</d:Bye>
</s:Body>
</s:Envelope>
Probe以及Probematches
matching Types and scopes
一个probe可能包括0-2个关于目标服务的约束项:Types或者scopes.当且仅当所有的Types以及scopes都匹配的时候,probe才得以匹配一个目标服务。(Type1)在T1匹配(Type2)T2的时候其QNam需要匹配。T1和T2匹配必须保证以下都匹配:
1.T1和T2的namespace相同
2.local name相同
Scopes1于Scopes2在匹配的时候可采用不同的匹配规范,如果匹配规则不被另一个receiver接收的时候,s1与s2也是不匹配的。
http://schemas.xmlsoap.org/ws/2005/04/discovery/rfc2396
使用敏感比较:1.s1的path_segments与s2的segment_wise前缀scheme要相同 2.authority要相同使用不敏感比较:1.s1与s2的scheme要相同 2.authority要相同 2.s1与s2均不包含..和.字段其他元素是被排除在外。,另外在匹配前s1和s2必须是规范化的匹配规则并不测试s1中字符串是否与s2字符串中前面一部分是否相同。
http://schemas.xmlsoap.org/ws/2005/04/discovery/uuid
使用敏感比较规则,s1和s2的方案是uuid。如果s1与s2的uuid这128位数据相同则二者匹配。
http://schemas.xmlsoap.org/ws/2005/04/discovery/ldap
使用敏感规则:s1和s2的方案是 ldap以及hostport,s1的dn的RDNSequence与s2的dn的RDNSequence前缀相同。
http://schemas.xmlsoap.org/ws/2005/04/discovery/strcmp0
使用敏感比较,只要s1和s2的string代表的意思一样即可
Probe:
client或许发送一个probe去发现目标服务所提供的Types以及Scopes,或者是仅仅发现目标服务而忽略上述Types和Scopes。
client没有检测到设备的时候client广播一个probe去发现目标服务。如果client已知了设备的地址,则client单播一个probe到此地址以获取信息。
由于client不知道会有多少目标服务会发送probmatch,则client可以采用如下行为:
1、等待一个有效的probematch消息】
2、多次重发probe直到client确认没有新的probematches收到。client在对通过一个probe必须使用同一个值来区分这些copy probe。
probe的规范化示例:
-
<s:Envelope ... >
-
<s:Header ... >
<a:Action ... >
http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe
</a:Action>
<a:MessageID ... >xs:anyURI</a:MessageID>
<a:ReplyTo ... >endpoint-reference</a:ReplyTo>
<a:To ... >xs:anyURI</a:To>
...
</s:Header>
-
<s:Body ... >
<d:Probe ... >
<d:Types>list of xs:QName</d:Types>
<d:Scopes [MatchBy="xs:anyURI"... >
list of xs:anyURI
</d:Scopes>
...
</d:Probe>
</s:Body>
-
</s:Envelope>
/Envelope/s:Header/a:ReplyTo/a:Address----------------值为http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous 是由底层传输协议确定。如果Probe使用UDP协议,【reply
endpoint 】是probe报文中的header的源地址和端口号。
/Envelope/s:Header/a:To
1.如果发送至目标服务,一定是"urn:schemas-xmlsoaporg:ws:2005:04:discovery"
2.如果发送至发现代理,则必须是远程发现代理的Endpoint Reference,此信息可从远程发现的Hello报文中获得。
/Envelope/s:Body/d:Probe/d:Type 如果忽略则隐含值是任何Type
/Envelope/s:Body/d:Probe/d:Scopes 如果存在则必定是确定的URIS;,如果忽略则隐含值是任何Scopes
/Envelope/s:Body/d:Probe/d:Scopes/@MatchBy 如果忽略了,则其隐含值是"http://schemas.xmlsoap.org/ws/2005/04/discovery/rfc2396 "如果目标服务或者远程发现代理不支持匹配规则,其或许会产生一个错误而不是一个probematch.错误与SOAP绑定的形式如下:
为获得目标服务的所有类型于服务 ,client发送的probe或许会忽略 /Envelope/s:Body/d:Probe/d:Scopes 以及 /Envelope/s:Body/d:Probe/d:Types
Probe match
如果一个目标服务匹配了一个probe,则目标服务必须返回一个Probematch消息。如果目标服务收到了多个相同的probe,server端应该只回应一次
如果未做此处理,在服务端会出现,会出现多问多答的情况。出现这种情况的原因主要是1.client在probe的时候的查找方式,2.server端并未只做回应一次处理
重发:目标服务接收到probe后需要经过一段时间后再回传probematch
如果目标服务接收到不匹配的probe则需要不必回发Probematch
如果远程发现代理接收到了一个广播probe,则必须以hello返回
如果远程发现代理匹配到了probe则必须无延迟的发送probematch。probematch必须以以下规范单播回应probe
-
<s:Envelope ... >
-
<s:Header ... >
<a:Action ... >
http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches
</a:Action>
<a:MessageID ... >xs:anyURI</a:MessageID>
<a:RelatesTo ... >xs:anyURI</a:RelatesTo>
<a:To ... >xs:anyURI</a:To>
<d:AppSequence ... />
...
</s:Header>
-
<s:Body ... >
<d:ProbeMatches ... >
<d:ProbeMatch ... >
<a:EndpointReference> ... </a:EndpointReference>
<d:Types>list of xs:QName</d:Types>
<d:Scopes>list of xs:anyURI</d:Scopes>
<d:XAddrs>list of xs:anyURI</d:XAddrs>
<d:MetadataVersion>xs:unsignedInt</d:MetadataVersion>
...
</d:ProbeMatch>]*
...
</d:ProbeMatches>
</s:Body>
-
</s:Envelope>
/s:Envelope/s:Header/a:RelatesTo------必须填充probe的Message id这个属性
/s:Envelope/s:Header/a:To-------如果接收到的Probe的【reply Endpoint】是probe的header的IP以及端口号。则此处的值必须是"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"
/s:Envelope/s:Header/d:Appsequence-----当允许从目标服务订阅discovery 消息的时候此处必须有
/s:Envelope/s:Body/d:Probematches ------匹配目标服务
1.如果目标服务发送了probe match,则此项必须包含一个d:probematch 子列表。如果不匹配则不发送Probematch
2.如果probematch是被远程设备发现代理发送的,则此处会包含0个或多个d:probmatch子列表。
/s:Envelope/s:Body/d:Probematches/d:ProbeMatch/a:EndpointReferce
目标服务的EndpointReferce
/s:Envelope/s:Body/d:Probematches/d:ProbeMatch/d:Types
/s:Envelope/s:Body/d:Probematches/d:ProbeMatch/d:Scopes
/s:Envelope/s:Body/d:Probematches/d:ProbeMatch/d:XAddrs
/s:Envelope/s:Body/d:Probematches/d:ProbeMatch/d:MetadataVersion
这些参看hello部分
安全模式:
本规范不认为加入在设备发现过程中加入endpoint是安全的。此规范安全必须是可以适应各种类型的攻击。如果一个目标服务希望安全的Hello,bye,probemath 或者resolvematch。其应该使用小型签名认证。客户端可能会忽略不能通过小型认证的Hello,bye,Probematch
如果下面的情况发生则目标服务不回应来自client的probe
1.目标服务于client在不同的管理域,并且probe是广播的
2.目标服务不能认证probe的小型签名认证
为阻止网络攻击,目标服务对于不能通过认证的消息不进行回应除非在【reply endpoint】设置的是"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"
发生下面情况的时候client会舍弃probe
1.对于Probematch或者resolvematch接收超时
2.probematch并没有认证通过
默认的接收超时时间是:
如果目标服务有广播认证凭据,其应该发送独立的Hello,Bye,Probematch.或者说对于resolve使用不同的认证凭据。
紧凑(小型)签名格式
为见小品XML namespace的数量,需定义以下全局变量
@d:Id 于@wsu:Id具有相同的ID参考机制,此属性可用于验证使用紧凑呀签名格式的部分,紧凑签名的具体格式如下:
<d:Security ... >
[<d:Sig Scheme="xs:anyURI"
[KeyId="xs:base64Binary"]?
Refs="..."
Sig="xs:base64Binary"
... />]?
...
</d:Security>
d:Security
是Header字段中的一部分。其下的d:sig通紧凑型签名认证。其格式是小型的XML签名格式。为处理此签名,一个ds:SignedInfo块被创建去认证此签名
d:Security/@s11:mustUnderstand | d:Security/@s12:mustUnderstand
由于对于d:security的处理并不是强制的,所以d:Security并不必设置其mustUnderstand为true
d:Security/d:Sig/@Scheme 为此签名提供明确的算法以产生digest
d:Security/d:Sig/@Scheme=d:"http://schemas.xmlsoap.org/ws/2005/04/discovery/rsa"
采用C14N规范,SHA1用于计算digest,签名使用RSA.:
d:Security/d:Sig/@KeyId
代表签名的token,如果公钥token被采用的话,其必须设置,如果公钥token被忽略的话,此处无任何意义。
d:Security/d:Sig/@Refs
此部分的每一部分均已经被规范化。每一部分均可参考@d:Id。此列表仅仅可以引用Only immediate children of the security header,top-level SOAP header blocks (/s:Envelope/s:Header/*),
and the full SOAP Body (/s:Envelope/s:Body)。在此消息中值和IDs是分离的。
d:Security/d:Sig/@Sig 签名的值紧凑签名示例:
<d:Sig xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"
Scheme="http://schemas.xmlsoap.org/ws/2005/04/discovery/rsa"
KeyId="Dx42/9g="
Refs="ID1"
Sig="ru5Ef76xGz5Y5IB2iAzDuMvR5Tg=" />
使用下述伪代码可将紧凑签名扩展为XML签名ds:SignedInfo
1.创建XML签名ds:SignedInfo块,规范包含namespace 首选项,所以必须使用XML namespace首选项ds。所以每一方都可以计算出digest的值。
2.依据用合适的规范和算法填充
鉴于本人英文水平有限,翻译不准确的地方敬请谅解!
相关资源:http://download.****.net/detail/no_pao_spite/9856513