一步一步學Remoting之四:承載方式(2)
這裡來說一下iis承載方式,順便簡單說一下remoting的通道和【複雜對象】中的遺留問題。
首先明确一點:iis來承載的話隻能是http通道方式的。
我們來建立一個web項目,比如叫remoting,删除項目中的所有webform,把遠端對象dll-RemoteObject.dll複制到項目的dll檔案夾下面,然後打開web.config進行服務端設定:
<configuration>
<appSettings>
<add key="strconn" value="server=(local);uid=sa;pwd=;database=UBISOFT" />
</appSettings>
<system.runtime.remoting>
<application>
<service>
<wellknown type="RemoteObject.MyObject,RemoteObject" objectUri="MyObject.soap"
mode="SingleCall" />
</service>
<channels>
<channel ref="http"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
來分析一下這個config:
1、可能大家還不是很了解type屬性,其實type屬性分兩部分<命名空間.類名>,<程式集>
2、objectURi是用來表示對象的uri的,到時候我們用這個uri來連接配接到服務端
3、我們需要為uri指定soap(soap格式化)或者rem(二進制格式化)字尾
要進行測試其實很簡單,我們在浏覽器輸入:http://localhost/remoting/MyObject.soap?wsdl
進行測試,如果發生問題基本就是配置檔案的問題或者對象dll沒有正确複制到dll目錄
接下來修改一下用戶端的配置檔案就可以了,主要是修改位址。
<appSettings>
<add key="ServiceURL" value="http://localhost/remoting/MyObject.soap"/>
</appSettings>
iis承載方式預設是80端口,我們不需要在端口上做任何設定。還需要注意到的是iis方式,我們使用這樣的格式作為位址:
http://ip位址/虛拟目錄/遠端對象.soap
運作了用戶端以後如果我們的資料量比較大的話,就算是本機我們也能感受到延遲,比tcp方式延遲厲害很多很多,其實http方式的remoting效率比webservice還要差,具體選擇http方式的remoting還是webservice還是要看我們是不是對對象的狀态有需求。
iis的部署也是自動啟動服務的,還有一個優點就是可以結合iis的windows身份認證,這個參照一些iis的配置文章,這裡就不說了。
下面還是要來看一下兩種【通道】:
預設情況下,HTTP 通道使用 SOAP 格式化程式,是以,如果用戶端需要通過 Internet 通路對象,則可以使用 HTTP 通道。由于這種方法使用 HTTP,是以允許用戶端通過防火牆遠端通路 .NET 對象。将這些對象內建在 IIS 中,即可将其配置為 Web 服務對象。随後,用戶端就可以讀取這些對象的 WSDL 檔案,以便使用 SOAP 與 Remoting 對象通信。
預設情況下,TCP 通道使用二進制格式化程式。此格式化程式以二進制格式進行資料的序列化,并使用原始套接字在網絡中傳送資料。如果對象部署在受防火牆保護的封閉環境中,則此方法是理想的選擇。該方法使用套接字在對象之間傳遞二進制資料,是以性能更好。由于它使用 TCP 通道來提供對象,是以具有在封閉環境中開銷較小的優點。由于防火牆和配置問題,此方法不能在 Internet 上使用。
是以我們也需要更根據自己的需求來選擇通道!看看remoting有這麼多可以選擇的方式:選擇激活模式,選擇通道,選擇承載方式,如此多的選擇給了我們靈活的同時也增加了了解remoting的難度。
最後說一下前面的遺留問題,為什麼會發生這個安全異常?
<a href="http://www.cnblogs.com/lovecherry/archive/2005/05/20/159335.html">http://www.cnblogs.com/lovecherry/archive/2005/05/20/159335.html</a>
msdn說:
依賴于運作時類型驗證的遠端處理系統必須反序列化一個遠端流,然後才能開始使用它,未經授權的用戶端可能會試圖利用反序列化這一時機。為了免受這種攻擊,.NET 遠端處理提供了兩個自動反序列化級别:Low 和 Full。Low(預設值)防止反序列化攻擊的方式是,在反序列化時,隻處理與最基本的遠端處理功能關聯的類型,如自動反序列化遠端處理基礎結構類型、有限的系統實作類型集和基本的自定義類型集。Full 反序列化級别支援遠端處理在所有情況下支援的所有自動反序列化類型。
我們首先來修改服務端的配置檔案:
<application name="RemoteServer">
<wellknown type="RemoteObject.MyObject,RemoteObject" objectUri="RemoteObject.MyObject"
mode="Singleton" />
</service>
<channel ref="tcp" port="9999"/>
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channels>
當然也可以用程式進行設定:

using System;

using System.Collections;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using System.Runtime.Serialization.Formatters;
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject.MyObject), "RemoteObject.MyObject", WellKnownObjectMode.Singleton);
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = 9999;
TcpChannel channel = new TcpChannel(props,clientProvider,serverProvider);
ChannelServices.RegisterChannel(channel);
Console.ReadLine();
用戶端還要用程式進行調整:
若要使用配置檔案設定反序列化級别,必須顯式指定 <formatter> 元素的 typeFilterLevel 屬性。雖然這通常是在伺服器端指定的,但您還必須為注冊來偵聽回調的用戶端上的任何信道指定這一屬性,以控制其反序列化級别
在程式前面加上和服務端基本相同的代碼:
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
props["port"] = 0;
這樣就可以了,注意:如果在同一個機器上面測試端口号應設為不同于伺服器端設定的端口号,推薦設定為0(遠端處理系統自動選擇可用端口)
.NET Remoting 自身不提供安全模型。然而,通過将遠端對象駐留在 ASP.NET 中并使用 HTTP 通道進行通信,遠端對象可以使用 IIS 和 ASP.NET 提供的基本安全服務。比較而言,TCP 通道和自定義的主機可執行檔案能夠提供更高的性能,但這種組合不提供内置的安全功能。
• 若要對用戶端進行身份驗證,請使用 HTTP 通道,在 ASP.NET 中駐留對象,以及在 IIS 中禁用匿名通路。
• 如果您不擔心用戶端身份驗證問題,請使用 TCP 通道,它可以提供更高的性能。
• 如果您使用 TCP 通道,請使用 IPSec 保護用戶端和伺服器之間的通信通道。使用 SSL 來保護 HTTP 通道。
• 如果您需要對遠端資源進行受信任的調用,請将元件駐留在 Windows 服務中,而不是駐留在控制台應用程式中。
• 始終不要向 Internet 公開遠端對象。在這種情況下,請使用 Web 服務。
應該僅在 Intranet 中使用 .NET Remoting。應該使用内部方式從 Web 應用程式通路對象。即使對象駐留在 ASP.NET 中,也不要向 Internet 用戶端公開它們,因為用戶端必須是 .NET 用戶端。
最後,讓我們來看一篇msdn有關remoting安全的文章:
<a href="http://www.microsoft.com/china/msdn/library/architecture/architecture/architecturetopic/BuildSucApp/BSAAsecmod11.mspx">http://www.microsoft.com/china/msdn/library/architecture/architecture/architecturetopic/BuildSucApp/BSAAsecmod11.mspx</a>
說到這裡大家可能對remoting的一些基本知識稍微優點概念了,後續文章會繼續不斷強化這些概念!