如何限制WCF Data Service存取的用戶端IP

在開發WCF Data Service的時候,筆者一直在想一個問題,就是安全性的問題!如何限制哪些IP可以存取這個WCF Data Service,不然任何人都可以呼叫也很奇怪。當然方法其實有很多,也可以使用Windows整合驗證並使用Web.config來設定Role,但是筆者想的是像一般網站一樣,透過系統管理者在自行開發的程式上設定阻擋IP,限制這個WCF Data Service可以使用的IP位址。

要實作這樣的功能必須在WCF Data Service提供服務之前攔下來並檢查用戶端的IP是否符合要求。這時可以複寫DataService的OnStartProcessingRequest方法,並且要複寫HandleException()方法將HandleExceptionArgs的UseVerboseErrors設定為true,表示要對用戶端回應詳細錯誤訊息,這樣才能使我們throw的錯誤訊息可以回傳至用戶端。

筆者先使用最簡單的方式在OnStartProcessingRequest內以HttpContext.Current.Request.UserHostAddress 取得用戶端的IP。

程式碼非常的簡單,如下:
using System;
using System.Data.Services;
using System.Data.Services.Common;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Web;
using System.Data.Objects;
using NorthwindModel;
using System.ServiceModel;
using System.Web;

public class WcfSPDataService : DataService
{
// 只呼叫一次方法初始化全服務原則。
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: 設定規則,指出哪些實體集及服務作業可見、可更新等等。
// 範例:
config.SetEntitySetAccessRule("Orders", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}

[WebGet()]
public string GetHelloWorld()
{
NorthwindEntities entity = new NorthwindEntities();
ObjectResult result = entity.SP_HelloWorld(new ObjectParameter("Greeting", "Gelis"));
return result.First();
}

protected override void HandleException(HandleExceptionArgs args)
{
args.UseVerboseErrors = true;
base.HandleException(args);
}

protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
string ipAddress = HttpContext.Current.Request.UserHostAddress;

NorthwindEntities entity = new NorthwindEntities();
var result = (from s1 in entity.BlockIPAddress
where s1.IPAddress==ipAddress select s1).Count();
if(result>0)
throw new System.Exception("您的用戶端IP:" + ipAddress + " Address不被允許!.");

base.OnStartProcessingRequest(args);
}
}

為了準確性筆者將成是佈署至IIS後再執行,從其他台電腦執行結果是可以正常的執行,不會有錯誤,如下:


當IP Addres如果是被阻擋的,在IE即會出現錯誤訊息,如下:


讀者會發現,錯誤訊息中的IP怎與URL中的相同?因為筆者故意將BlockIPAddress 資料表中設定與筆者local相同的IP位址,192.168.1.27下對應到的也是筆者的IIS伺服器。OK, 簡單的應用,各位參考看看!

留言

這個網誌中的熱門文章

軟體工程師 - 成長的 10 個階段

常見的程式碼壞味道(Code Smell or Bad Smell)

什麼是 gRPC ?