編寫者:鄭昀@ultrapower
<b>dotnet framwork 1.1</b>
<b>關鍵字:</b><b>channel,remoting</b>
編寫時間:2005-5-18
<b>摘要:</b>.net framework更新之後,remoting中的事件就需要對信道進行特别的設定,要自己建立binaryserverformattersinkprovider類的執行個體,并且将其typefilterlevel設為typefilterlevel.full,這是.net 1.1中增強了安全設定後必須要做的事情。
<b> </b>
<b>引子:</b>
現在使用以前在dotnet framework1.0下編寫的例子代碼時,remoting常常會在使用channel時發生異常,錯誤如下所示:
中文錯誤報告以及錯誤堆棧
system.security.securityexception: 不允許類型 system.delegateserializationholder和從中派生的類型(例如 system.delegateserializationholder)在此安全級别上被反序列化。
server stack trace:
at system.runtime.serialization.formatterservices.checktypesecurity(type t, typefilterlevel securitylevel)
at system.runtime.serialization.formatters.soap.objectreader.checksecurity(parserecord pr)
英文錯誤報告
[securityexception: type system.delegateserializationholder and the types derived from it (such as system.delegateserializationholder) are not permitted to be deserialized at this security level.]
這個錯誤是因為.net framework更新到1.1後,加強了安全設定導緻的。
<b>錯誤重制:</b>
異常發生在
remsspi\microsoft\samples\security\sspi\sample\controlpanel\client
的mainform.cs下面這句話上:
_clientsecurity.signedmessageevent =
newmicrosoft.samples.security.sspi.sample.classlibrary.client.signedmessagedelegate(this.signedmessage);
_clientsecurity對象是這麼建立的:
_clientsecurity = (microsoft.samples.security.sspi.sample.classlibrary.client.security)activator.getobject(typeof(microsoft.samples.security.sspi.sample.classlibrary.client.security), clienturl);
這時候,他所使用的信道建立方法如下所示:
channelservices.registerchannel(newhttpchannel(convert.toint32(txtclientport.text)));
隻有将其改為:
//////////////////////////////////////////////////////////
/// zhengyun 20050518
binaryserverformattersinkprovider serverprov = newbinaryserverformattersinkprovider();
<b>serverprov.typefilterlevel = system.runtime.serialization.formatters.typefilterlevel.full;</b>
binaryclientformattersinkprovider clientprov = newbinaryclientformattersinkprovider();
idictionary props = new hashtable();
props["port"] = convert.toint32(txtclientport.text);
<b>httpchannel chan = new httpchannel(props, clientprov, serverprov);</b>
///
//
// setup the channel for the client side object
channelservices.registerchannel(chan);
方可。
<b>原因:</b>
當你使用用戶端激活的對象、事件或者委托時,在.net framework 1.1下你會遇到以下兩種錯誤:
· <b>system.security.securityexception</b>.
type system.delegateserializationholder and the types derived from it (such as system.delegateserializationholder) are not permitted to be deserialized at this security level.
· <b>system.runtime.serialization.serializationexception</b>
because of security restrictions, the type system.runtime.remoting.objref cannot be accessed.
要想回到以前的預設模式,就是允許跨越remoting邊界傳遞委托和對象引用,你必須改變“typefilterlevel”。
<b>微軟的正式解釋:</b>
這一問題影響到的apis有:
system.runtime.serialization.iserializable
system.runtime.remoting.objref
system.runtime.remoting.lifetime.ilease
system.runtime.remoting.lifetime.isponsor
system.runtime.remoting.contexts.icontributeenvoysink
system.runtime.remoting.channels.soapserverformattersinkprovider
system.runtime.remoting.channels.binaryserverformattersinkprovider
依賴于運作時類型驗證的遠端處理系統必須反序列化一個遠端流,然後才能開始使用它,未經授權的用戶端可能會試圖利用反序列化這一時機。為了免受這種攻擊,.net 遠端處理提供了兩個自動反序列化級别:<b>low</b> 和<b>full</b>。<b>low</b>(預設值)防止反序列化攻擊的方式是,在反序列化時,隻處理與最基本的遠端處理功能關聯的類型,如自動反序列化遠端處理基礎結構類型、有限的系統實作類型集和基本的自定義類型集。<b>full</b> 反序列化級别支援遠端處理在所有情況下支援的所有自動反序列化類型。
· 如果應用程式需要使用僅在 <b>full</b> 反序列化級别才可用的遠端處理功能,您必須提供身份驗證的類型和必要的加密級别,以保護任何在使用遠端方案中的這些進階功能時可能遭受風險的資源。
<b>解決之道:</b>
您可以通過程式設計方式或使用應用程式配置檔案設定反序列化級别。
[c#]
<code>// creating a custom formatter for a tcpchannel sink chain.</code>
<code>binaryserverformattersinkprovider provider = new binaryserverformattersinkprovider();</code>
<code>provider.typefilterlevel = typefilterlevel.full;</code>
<code>// creating the idictionary to set the port on the channel instance.</code>
<code>idictionary props = new hashtable();</code>
<code>props["port"] = 8085;</code>
<code>// pass the properties for the port setting and the server provider in the server chain argument. (client remains null here.)</code>
<code>tcpchannel chan = new tcpchannel(props, null, provider);</code>
[visual basic]
<code>' creating a custom formatter for your tcpchannel sink chain.</code>
<code>dim provider as new binaryserverformattersinkprovider()</code>
<code>provider.typefilterlevel = typefilterlevel.full</code>
<code>' creating the idictionary to set the port on the channel instance.</code>
<code>idictionary props = new hashtable()</code>
<code>props("port") = 8085</code>
<code>' pass the properties for the port setting and the server provider in the server chain argument. (client remains null here.)</code>
<code>dim chan as new tcpchannel(props, null, provider)</code>
若要使用配置檔案設定反序列化級别,必須顯式指定 <formatter> 元素的 <b>typefilterlevel </b>屬性。雖然這通常是在伺服器端指定的,但您還必須為注冊來偵聽回調的用戶端上的任何信道指定這一屬性,以控制其反序列化級别。以下示例為應用程式域中的 <b>soapformatter</b> 和 <b>binaryformatter</b> 顯式地将反序列化級别設定為 <b>low</b>。
<code><configuration></code>
<code><system.runtime.remoting></code>
<code><application></code>
<code><service></code>
<code><wellknown</code>
<code>type="servicetype, common"</code>
<code>objecturi="servicetype.soap"</code>
<code>mode="singleton"</code>
<code>/></code>
<code></service></code>
<code><channels></code>
<code><channel ref="http"></code>
<code><serverproviders></code>
<code><provider ref="wsdl" /></code>
<code><formatter ref="soap" typefilterlevel="low" /></code>
<code><formatter ref="binary" typefilterlevel="low" /></code>
<code></serverproviders></code>
<code></channel></code>
<code></channels></code>
<code></application></code>
<code></configuration></code>
<b>更多資訊:</b><b></b>
<b>binaryserverformattersinkprovider </b><b>類</b><b></b>
為使用 binaryformatter 的伺服器格式化程式信道接收器提供程式提供實作。
備注
信道接收器通過 iserverchannelsinkprovider 接口的實作連接配接到伺服器信道。所有遠端處理伺服器信道均提供以iserverchannelsinkprovider 為參數的構造函數。
信道接收器提供程式存儲在一個鍊中,在向信道構造函數傳遞外部信道接收器提供程式之前,使用者負責将所有的信道接收器提供程式連結在一起。為此,iserverchannelsinkprovider 提供了名為 next 的屬性。當在一個配置檔案中提供了多個信道接收器提供程式時,遠端處理結構将這些程式按在配置檔案中找到的順序連結起來。在remotingconfiguration.configure 調用過程中建立信道時,将建立信道接收器提供程式。
格式化程式接收器在運作時使用接收器配置屬性來配置信道。接收器屬性可在配置檔案中指定,或在 idictionary 中以程式設計方式指定。在配置檔案中,所有值都由字元串表示,但是當以程式設計方式生成屬性 idictionary 時,值類型可以用它們的本機值或字元串指定。
<b>binaryserverformattersinkprovider.typefilterlevel </b><b>屬性</b><b></b>
注意:此命名空間、類或成員僅在 .net framework 1.1 版中受支援。
擷取或設定 binaryserverformattersink 所執行的自動反序列化的 typefilterlevel。
.net framework 安全性:
對直接調用方完全信任。部分受信任的代碼不能使用此成員。有關更多資訊,請參閱在部分受信任的代碼中使用庫