使用ActionFilterAttribute抽象類別並覆寫OnActionExecuting。實作IP過濾
覆寫OnActionExecuting虛擬方法
先繼承ActionFilterAttribute
抽象類別,並覆寫虛擬方法OnActionExecuting。
透過參數ActionExecutingContext取得遠端IP位置,進行IP篩選。
IP位置不符合篩選條件,則回傳一個ContentResult,ContentResult可以自行定義ContentType(MIME)。這裡我們的ContentType設成存文字text/pain,並設定錯誤訊息ip not allowed!!。
順帶一提!!
base.OnActionExecuting(context)這一行依據這篇文章(Why call base.OnActionExecuting(filterContext);?)來看的話是可以註解掉,因為如果回去看原始碼,base.OnActionExecuting()這個虛擬方法(註:虛擬方法裡面可以實做程式碼,跟介面不同)裡面是沒有任何程式碼的。所以就算不加上去也是不會有任何影響的。
但我這裡是建議加上他的,至於是什麼原因,我們在另外一篇文章在來說(傳送門:ActionFilter的流程以及ActionFilter流程結束時間點)。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
public class AllowedIpAttribute: ActionFilterAttribute
{
private string[] ipList = new string[] { };
public AllowedIpAttribute(string allowedIps)
{
ipList = allowedIps.Split(',', ';');
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var clientIp = context.HttpContext.Connection.RemoteIpAddress.ToString();
if (!ipList.Contains(clientIp))
{
context.Result = new ContentResult()
{
StatusCode = 400,
Content = "ip not allowed!!",
ContentType = "text/plain; charset=utf-8"
};
}
base.OnActionExecuting(context);
}
}
指定API(Action)掛載Attribute
private const string _allowIpList = "172.21.130.8,172.22.136.54,172.22.136.97,::1,127.0.0.1";
[HttpGet]
[Filters.AllowedIp(_allowIpList)]
public async Task TestAPI()
{
...
}
接收錯誤訊息
這便我們接收的catch類別要換成WebException才能取得錯誤訊息的文字串流。用一般常用的Exception類別會無法取得。
try
{
呼叫TestAPI...
}
catch (WebException exWeb)
{
using (var response = exWeb.Response.GetResponseStream())
{
using (var sr = new StreamReader(response, Encoding.UTF8))
{
var responseMsg = sr.ReadToEnd().ToString();
response.Close();
filterContext.Result = new HttpStatusCodeResult((exWeb.Response as HttpWebResponse).StatusCode, $"darType OnActionExecuting error:{responseMsg}");
}
}
}
Ref: