Remoting系列专题---构建Remoting“防火墙”
生活随笔
收集整理的這篇文章主要介紹了
Remoting系列专题---构建Remoting“防火墙”
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
做項目不得不考慮安全問題,但是在Remoting應用中我似乎沒有找到象WebService那樣現成可用的防止非授權人員隨意調用的方法和驗證安全機制。當然,簡單一點的可以通過Remoting客戶端傳輸一些驗證代碼,然后在服務端驗證這些代碼的合法性,以實現是否安全授權調用,但是總覺得這樣比較麻煩。我也見有些人主動把客戶端的IP地址獲取后主動送入到Remotin g服務端驗證以便識別是否合法,其實原理跟上面的是一樣的道理,我覺得這樣傳送很容易讓別人仿造一些數據送入,從而輕易獲得合法調用。當然以上數據可以通過把數據特殊的加密和解密也能得到比較好的安全性。在這里我是想介紹另外一種安全機制,即構建Remoting“防火墻”。
???? 其實我所說的Remoting“防火墻”也是最基本的。由于Remoting的TcpChannel沒有提供內建的認證機制,所以沒有現成獲取客戶端的方法,我們可以在Remoting Server端注冊上自定義的Server Channel Sink,通過Transport Headers來獲取request的IP,以下是自定義的Server Channel Sink類的代碼,(注:原代碼不是我寫的,原出處我忘記了,所以無法標注來源)
??1using?System;
??2using?System.Collections;
??3using?System.IO;
??4using?System.Runtime.Remoting;
??5using?System.Runtime.Remoting.Messaging;
??6using?System.Runtime.Remoting.Channels;
??7using?System.Threading;
??8using?System.Net;
??9
?10
?11namespace?Colorful.RemoteObject
?12{
?13????public?class?ClientIPServerSinkProvider?:?IServerChannelSinkProvider
?14????{
?15
?16????????private?IServerChannelSinkProvider?next?=?null;
?17
?18????????public?ClientIPServerSinkProvider()
?19????????{
?20????????}
?21
?22????????public?ClientIPServerSinkProvider(IDictionary?properties,?ICollection?providerData)
?23????????{
?24????????}
?25
?26????????public?void?GetChannelData(IChannelDataStore?channelData)
?27????????{
?28????????}
?29
?30????????public?IServerChannelSink?CreateSink(IChannelReceiver?channel)
?31????????{
?32????????????IServerChannelSink?nextSink?=?null;
?33
?34????????????if?(next?!=?null)
?35????????????{
?36????????????????nextSink?=?next.CreateSink(channel);
?37????????????}
?38
?39????????????return?new?ClientIPServerSink(nextSink);
?40????????}
?41
?42
?43
?44????????public?IServerChannelSinkProvider?Next
?45????????{
?46????????????get?{?return?next;?}
?47????????????set?{?next?=?value;?}
?48????????}
?49????}
?50
?51????public?class?ClientIPServerSink?:?BaseChannelObjectWithProperties,?IServerChannelSink,?IChannelSinkBase
?52????{
?53????????private?IServerChannelSink?_next;
?54
?55????????public?ClientIPServerSink(IServerChannelSink?next)
?56????????{
?57????????????_next?=?next;
?58????????}
?59
?60????????public?void?AsyncProcessResponse(System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack?sinkStack,?System.Object?state,?System.Runtime.Remoting.Messaging.IMessage?msg,?System.Runtime.Remoting.Channels.ITransportHeaders?headers,?System.IO.Stream?stream)
?61????????{
?62????????}
?63
?64????????public?Stream?GetResponseStream(System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack?sinkStack,?System.Object?state,?System.Runtime.Remoting.Messaging.IMessage?msg,?System.Runtime.Remoting.Channels.ITransportHeaders?headers)
?65????????{
?66????????????return?null;
?67????????}
?68
?69????????public?System.Runtime.Remoting.Channels.ServerProcessing?ProcessMessage(System.Runtime.Remoting.Channels.IServerChannelSinkStack?sinkStack,?System.Runtime.Remoting.Messaging.IMessage?requestMsg,?System.Runtime.Remoting.Channels.ITransportHeaders?requestHeaders,?System.IO.Stream?requestStream,?out?System.Runtime.Remoting.Messaging.IMessage?responseMsg,?out?System.Runtime.Remoting.Channels.ITransportHeaders?responseHeaders,?out?System.IO.Stream?responseStream)
?70????????{
?71????????????if?(_next?!=?null)
?72????????????{
?73????????????????IPAddress?ip?=?requestHeaders[CommonTransportKeys.IPAddress]?as?IPAddress;
?74
?75????????????????CallContext.SetData("IP",?ip);
?76
?77????????????????ServerProcessing?spres?=?_next.ProcessMessage(sinkStack,?requestMsg,?requestHeaders,?requestStream,?out?responseMsg,?out?responseHeaders,?out?responseStream);
?78
?79????????????????return?spres;
?80????????????}
?81????????????else
?82????????????{
?83????????????????responseMsg?=?null;
?84
?85????????????????responseHeaders?=?null;
?86
?87????????????????responseStream?=?null;
?88
?89????????????????return?new?ServerProcessing();
?90????????????}
?91????????}
?92
?93
?94
?95????????public?IServerChannelSink?NextChannelSink
?96????????{
?97????????????get?{?return?_next;?}
?98????????????set?{?_next?=?value;?}
?99????????}
100????}
101}
102 以下是遠程對象主程序代碼
?1class?Program
?2????{
?3????????static?void?Main(string[]?args)
?4????????{
?5????????????int?TcpPort?=?ConfigInfo.RemoteSocketPort;
?6????????????BinaryServerFormatterSinkProvider?provider?=?new?BinaryServerFormatterSinkProvider();
?7????????????provider.TypeFilterLevel?=?System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
?8????????????//實例化自定義的Server Channel Sink類
?9????????????Colorful.RemoteObject.ClientIPServerSinkProvider?IpInjProvider?=?new?Colorful.RemoteObject.ClientIPServerSinkProvider();
10????????????provider.Next?=?IpInjProvider;//加入接收鏈
11????????????
12????????????IDictionary?props?=?new?Hashtable();
13????????????props["port"]?=?TcpPort;
14????????????
15????????????TcpChannel?chan1?=?new?TcpChannel(props,null,provider);
16
17????????????ChannelServices.RegisterChannel(chan1,?false);
18
19????????????LifetimeServices.LeaseTime?=?TimeSpan.Zero;//租用周期
20????????????RemotingConfiguration.RegisterWellKnownServiceType
21????????????????(
22????????????????typeof(Colorful.RemoteObject.Server),
23????????????????ConfigInfo.RemoteSocketURI,
24????????????????WellKnownObjectMode.Singleton
25????????????????);
26????????????Console.WriteLine(DateTime.Now.ToString()?+?"服務通道注冊成功!等待數據服務請求");????????????
27
28????????????Console.ReadLine();
29????????}
30????} 然后通過配置許可的IP地址XML文件,讀取XML驗證IP地址列表,然后調用以下函數驗證客戶端調用的合法性,非授權的IP拒絕訪問
?驗證客服端的合法性#region?驗證客服端的合法性
????????/**////?<summary>
????????///?檢查Remoting客戶端的合法性
????????///?</summary>
????????///?<returns></returns>
????????public?bool?CheckRemotingClient()
????????{
????????????IPAddress?data?=?(IPAddress)CallContext.GetData("ClientIPAddress");
????????????if?(clientIPAddress.ContainsKey(data))
????????????{
????????????????string?msg?=?"接受遠程地址:"?+?data.ToString()?+?"的服務請求";
????????????????Console.WriteLine(msg);
????????????????return?true;
????????????}
????????????else
????????????{
????????????????string?msg?=?"遠程地址:"?+?data.ToString()?+"不在許可范圍內,服務請求被拒絕";
????????????????Console.WriteLine(msg);
????????????????SQL2005DAL.CommDAL.WriteLogFile("RemotingClientTrace",?msg,?"Warring",?false);
????????????????return?false;
????????????}
????????}
????????#endregion
???? 其實我所說的Remoting“防火墻”也是最基本的。由于Remoting的TcpChannel沒有提供內建的認證機制,所以沒有現成獲取客戶端的方法,我們可以在Remoting Server端注冊上自定義的Server Channel Sink,通過Transport Headers來獲取request的IP,以下是自定義的Server Channel Sink類的代碼,(注:原代碼不是我寫的,原出處我忘記了,所以無法標注來源)
??1using?System;
??2using?System.Collections;
??3using?System.IO;
??4using?System.Runtime.Remoting;
??5using?System.Runtime.Remoting.Messaging;
??6using?System.Runtime.Remoting.Channels;
??7using?System.Threading;
??8using?System.Net;
??9
?10
?11namespace?Colorful.RemoteObject
?12{
?13????public?class?ClientIPServerSinkProvider?:?IServerChannelSinkProvider
?14????{
?15
?16????????private?IServerChannelSinkProvider?next?=?null;
?17
?18????????public?ClientIPServerSinkProvider()
?19????????{
?20????????}
?21
?22????????public?ClientIPServerSinkProvider(IDictionary?properties,?ICollection?providerData)
?23????????{
?24????????}
?25
?26????????public?void?GetChannelData(IChannelDataStore?channelData)
?27????????{
?28????????}
?29
?30????????public?IServerChannelSink?CreateSink(IChannelReceiver?channel)
?31????????{
?32????????????IServerChannelSink?nextSink?=?null;
?33
?34????????????if?(next?!=?null)
?35????????????{
?36????????????????nextSink?=?next.CreateSink(channel);
?37????????????}
?38
?39????????????return?new?ClientIPServerSink(nextSink);
?40????????}
?41
?42
?43
?44????????public?IServerChannelSinkProvider?Next
?45????????{
?46????????????get?{?return?next;?}
?47????????????set?{?next?=?value;?}
?48????????}
?49????}
?50
?51????public?class?ClientIPServerSink?:?BaseChannelObjectWithProperties,?IServerChannelSink,?IChannelSinkBase
?52????{
?53????????private?IServerChannelSink?_next;
?54
?55????????public?ClientIPServerSink(IServerChannelSink?next)
?56????????{
?57????????????_next?=?next;
?58????????}
?59
?60????????public?void?AsyncProcessResponse(System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack?sinkStack,?System.Object?state,?System.Runtime.Remoting.Messaging.IMessage?msg,?System.Runtime.Remoting.Channels.ITransportHeaders?headers,?System.IO.Stream?stream)
?61????????{
?62????????}
?63
?64????????public?Stream?GetResponseStream(System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack?sinkStack,?System.Object?state,?System.Runtime.Remoting.Messaging.IMessage?msg,?System.Runtime.Remoting.Channels.ITransportHeaders?headers)
?65????????{
?66????????????return?null;
?67????????}
?68
?69????????public?System.Runtime.Remoting.Channels.ServerProcessing?ProcessMessage(System.Runtime.Remoting.Channels.IServerChannelSinkStack?sinkStack,?System.Runtime.Remoting.Messaging.IMessage?requestMsg,?System.Runtime.Remoting.Channels.ITransportHeaders?requestHeaders,?System.IO.Stream?requestStream,?out?System.Runtime.Remoting.Messaging.IMessage?responseMsg,?out?System.Runtime.Remoting.Channels.ITransportHeaders?responseHeaders,?out?System.IO.Stream?responseStream)
?70????????{
?71????????????if?(_next?!=?null)
?72????????????{
?73????????????????IPAddress?ip?=?requestHeaders[CommonTransportKeys.IPAddress]?as?IPAddress;
?74
?75????????????????CallContext.SetData("IP",?ip);
?76
?77????????????????ServerProcessing?spres?=?_next.ProcessMessage(sinkStack,?requestMsg,?requestHeaders,?requestStream,?out?responseMsg,?out?responseHeaders,?out?responseStream);
?78
?79????????????????return?spres;
?80????????????}
?81????????????else
?82????????????{
?83????????????????responseMsg?=?null;
?84
?85????????????????responseHeaders?=?null;
?86
?87????????????????responseStream?=?null;
?88
?89????????????????return?new?ServerProcessing();
?90????????????}
?91????????}
?92
?93
?94
?95????????public?IServerChannelSink?NextChannelSink
?96????????{
?97????????????get?{?return?_next;?}
?98????????????set?{?_next?=?value;?}
?99????????}
100????}
101}
102 以下是遠程對象主程序代碼
?1class?Program
?2????{
?3????????static?void?Main(string[]?args)
?4????????{
?5????????????int?TcpPort?=?ConfigInfo.RemoteSocketPort;
?6????????????BinaryServerFormatterSinkProvider?provider?=?new?BinaryServerFormatterSinkProvider();
?7????????????provider.TypeFilterLevel?=?System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
?8????????????//實例化自定義的Server Channel Sink類
?9????????????Colorful.RemoteObject.ClientIPServerSinkProvider?IpInjProvider?=?new?Colorful.RemoteObject.ClientIPServerSinkProvider();
10????????????provider.Next?=?IpInjProvider;//加入接收鏈
11????????????
12????????????IDictionary?props?=?new?Hashtable();
13????????????props["port"]?=?TcpPort;
14????????????
15????????????TcpChannel?chan1?=?new?TcpChannel(props,null,provider);
16
17????????????ChannelServices.RegisterChannel(chan1,?false);
18
19????????????LifetimeServices.LeaseTime?=?TimeSpan.Zero;//租用周期
20????????????RemotingConfiguration.RegisterWellKnownServiceType
21????????????????(
22????????????????typeof(Colorful.RemoteObject.Server),
23????????????????ConfigInfo.RemoteSocketURI,
24????????????????WellKnownObjectMode.Singleton
25????????????????);
26????????????Console.WriteLine(DateTime.Now.ToString()?+?"服務通道注冊成功!等待數據服務請求");????????????
27
28????????????Console.ReadLine();
29????????}
30????} 然后通過配置許可的IP地址XML文件,讀取XML驗證IP地址列表,然后調用以下函數驗證客戶端調用的合法性,非授權的IP拒絕訪問
?驗證客服端的合法性#region?驗證客服端的合法性
????????/**////?<summary>
????????///?檢查Remoting客戶端的合法性
????????///?</summary>
????????///?<returns></returns>
????????public?bool?CheckRemotingClient()
????????{
????????????IPAddress?data?=?(IPAddress)CallContext.GetData("ClientIPAddress");
????????????if?(clientIPAddress.ContainsKey(data))
????????????{
????????????????string?msg?=?"接受遠程地址:"?+?data.ToString()?+?"的服務請求";
????????????????Console.WriteLine(msg);
????????????????return?true;
????????????}
????????????else
????????????{
????????????????string?msg?=?"遠程地址:"?+?data.ToString()?+"不在許可范圍內,服務請求被拒絕";
????????????????Console.WriteLine(msg);
????????????????SQL2005DAL.CommDAL.WriteLogFile("RemotingClientTrace",?msg,?"Warring",?false);
????????????????return?false;
????????????}
????????}
????????#endregion
轉載于:https://www.cnblogs.com/chinhr/archive/2008/04/17/1157963.html
總結
以上是生活随笔為你收集整理的Remoting系列专题---构建Remoting“防火墙”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#3.0系列:Object Initi
- 下一篇: 解决wmv播放的问题