构建 Owin 中间件 来获取客户端IP地址
Not so long ago, we discussed on this blog the possible ways of retrieving the client’s IP address in ASP.NET Web API.
With the latest changes in the Web API 2 infrastructure, and the emergence of Owin and the Katana project as the common glue between the underlying host and the web framework(s) running on it, it’s becoming natural to move these types of application-wide concerns (security, logging etc) to Owin middleware.
Let’s have a look at how you could – as an introductory example – obtain client’s IP address at the Owin middleware level, and why is it beneficial.
The benefits of Owin
We’ll not really go into the basic details of Owin here – I have already covered that in previous posts – so let’s just say that the gist is that with Owin we can easily host a number of frameworks side by side and decouple our web frameworks from the host beneath it. Naturally, through Owin middleware, we can address common concerns in a single place too – the most obvious usage being security.
If you are used to working with HttpMessageHandlers, the idea behind OWIN middleware is very similar – as they are chained one after another and allow you to modify the incoming request or outgoing response.
For quite a while, working with OWIN middleware meant dealing with quite a raw API, as you’d have to handle constructs such as Func<idictionary<string, object="">, Task>.
Now, Microsoft.Owin.dll provides a base abstract class for creating Owin middleware easily:
public abstract class OwinMiddleware
{
protected OwinMiddleware(OwinMiddleware next);
protected OwinMiddleware Next { get; set; }
public abstract Task Invoke(OwinRequest request, OwinResponse response);
}
With that in place, it’s almost like implementing a MessageHandler.
Getting started with IP example
To get started we’ll need a new console project and following packages:
- – Katana: install-package Microsoft.Owin.Hosting -pre
- – Katana Http Listener: install-package Microsoft.Owin.Host.HttpListener -pre
- – Web API adapter: install-package Microsoft.AspNet.WebApi.Owin -pre
These 3 packages will bring in some additional dependencies they have.
We can now start a simple Owin server with Web API host – this is nothing new and should be very straight forward.
class Program
{
static void Main(string[] args)
{
string uri = "http://localhost:999/";
using (WebApp.Start<Startup>(uri))
{
Console.WriteLine("Started");
Console.ReadKey();
Console.WriteLine("Stopped");
}
}
} public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
}
} public class TestController : ApiController
{
public string Get()
{
return "Hello world!";
}
}
So really just a simple Web API Test controller and a setup to wire it all together.
Adding Owin middleware for IP inspection
Now suppose you’d like to restrict specific IP addresses.
If we do it at Owin level, it would affect all the frameworks running in your process (perhaps you might want to add SignalR or NancyFx) – so sounds like a perfect place to do it, doesn’t it?
Well, it’s extremely easy. We simply inherit from OwinMiddleware class and implement the Invoke method.
public class IpMiddleware : OwinMiddleware
{
private readonly HashSet<string> _deniedIps; public IpMiddleware(OwinMiddleware next, HashSet<string> deniedIps) :
base(next)
{
_deniedIps = deniedIps;
} public override async Task Invoke(OwinRequest request, OwinResponse response)
{
var ipAddress = (string)request.Environment["server.RemoteIpAddress"]; if (_deniedIps.Contains(ipAddress))
{
response.StatusCode = 403;
return;
} await Next.Invoke(request, response);
}
}
In this case, we also pass in the list of restricted IPs. When we add our middleware to the pipeline, we are allowed to pass in params object[] so we can send whatever we want into our middleware constructor (more on that in a second).
We can retrieve the client’s IP address by asking for server.RemoteIpAddress key of the Environment object on the OwinRequest – it’s an IDictionary<string, object=""> and contains everything that could be interesting for us.
Based on that we can either deny the request (let’s say send a 403 Forbidden status code), otherwise we continue on to the next middleware.
To plug this in we need to add the following in the Configuration method of the Startup class – notice that this is the moment that we can send in any params to the Middleware too:
var deniedIps = new HashSet<string> {"192.168.0.100", "192.168.0.101"}; //whatever
app.Use(typeof(IpMiddleware), deniedIps);
Also, we want to add it before the call to setup Web API!
Trying it out
Now if we access from a client that’s allowed to see the API, he gets the correct response as expected:

If the client is restricted, we reply with the 403 directly from the middleware:

构建 Owin 中间件 来获取客户端IP地址的更多相关文章
- C# WebApi 获取客户端ip地址
转自:http://www.cnblogs.com/weixing/p/5674078.html References required: HttpContextWrapper - System.We ...
- 在Thinkphp3.2.3框架下实现自动获取客户端IP地址的get_client_ip()函数
在Thinkphp框架下使用get_client_ip()函数获取客户端IP地址十分方便: 一行代码便可以实现:$ip = get_client_ip(); 但当我们测试时会遇到后台获取的IP地址显示 ...
- JAVA获取客户端IP地址
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...
- (转)【ASP.NET开发】获取客户端IP地址 via C#
[ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...
- php获取客户端ip地址
本文介绍一个,php获取客户端的IP地址的实例代码,有需要的朋友参考下吧. 获取客户端IP地址的代码,如下: 复制代码代码示例: <?php//取得客户端IP的函数function get_cl ...
- 获取客户端IP地址 via C#
获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己在项目中做过的事情,同 ...
- thinkphp 获取客户端ip地址方法
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有 ...
- 获取客户端IP地址定位城市信息
获取客户端IP地址定位城市信息 1.首先获取客户端的IP地址 function getIPaddress(){ $IPaddress=''; if (isset($_SERVER)){ if (iss ...
- Tp框架获取客户端IP地址
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_cl ...
随机推荐
- JS截取字符串多余的为...
如果截取字符串前几位,多余的用...表示该怎样做呢? JS代码 /** * js截取字符串,中英文都能用 * @param str:需要截取的字符串 * @param len: 需要截取的长度 */ ...
- 【分享】Web前端开发第三方插件大全
收集整理了一些Web前端开发比较成熟的第三方插件,分享给大家. ******************************************************************** ...
- Windows SDK DDK WDK (Windows Driver Kit) 区别
首先,先从基础的东西说起,开发WINDOWS下的驱动程序,需要一个专门的开发包,如:开发JAVA程序,我们可能需要一个JDK,开发WINDOWS应用程序,我们需要WINDOWS的SDK,现在开发WIN ...
- springboot项目使用拦截器修改/添加前端传输到后台header和cookie参数
本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除. 但在后台程序中,一般对request的参数的操作,都是通过request的getParameter.getParameter ...
- kafka性能测试
参考阿里中间件团队博客的博文 Kafka vs RocketMQ——多Topic对性能稳定性的影响 使用的测试工具为Jmeter
- MapReduce原理
MapReduce原理 WordCount例子 用mapreduce计算wordcount的例子: package org.apache.hadoop.examples; import java.io ...
- excel函数vloopup使用方法
邮件处理,查找null手机号码 G1=VLOOKUP(F1,A:B,2,FALSE) H1=VLOOKUP(F1,A:F,7,FALSE)参数1是:查找列,参数2是:范围,参数3是:查找的 ...
- opencv利用Cascade Classifier训练人脸检测器
opencv默认提供了haar特征和lbp特征训练的人脸分类器,但是效果不太好,所以我们可以用opencv提供的跑opencv_traincascade函数来训练一个LBP特征的分类器.(由于open ...
- linux 使用不安全的sprintf函数,存储字符越界导致程序莫名崩溃问题
linux c++编程 问题背景: 在处理一个公共模块的代码中,其中有以下代码片段 //代码片段-组合一组字符串并存放到szSignKey数组中 ] = {}; sprintf(szSignKey, ...
- 135、JS和Android交互范例
很简单的直接上代码 <uses-permission android:name="android.permission.INTERNET" /> assets/web. ...