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:

C#
 
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.

C#
 
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.

C#
 
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:

C#
 
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地址的更多相关文章

  1. C# WebApi 获取客户端ip地址

    转自:http://www.cnblogs.com/weixing/p/5674078.html References required: HttpContextWrapper - System.We ...

  2. 在Thinkphp3.2.3框架下实现自动获取客户端IP地址的get_client_ip()函数

    在Thinkphp框架下使用get_client_ip()函数获取客户端IP地址十分方便: 一行代码便可以实现:$ip = get_client_ip(); 但当我们测试时会遇到后台获取的IP地址显示 ...

  3. JAVA获取客户端IP地址

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...

  4. (转)【ASP.NET开发】获取客户端IP地址 via C#

    [ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...

  5. php获取客户端ip地址

    本文介绍一个,php获取客户端的IP地址的实例代码,有需要的朋友参考下吧. 获取客户端IP地址的代码,如下: 复制代码代码示例: <?php//取得客户端IP的函数function get_cl ...

  6. 获取客户端IP地址 via C#

    获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己在项目中做过的事情,同 ...

  7. thinkphp 获取客户端ip地址方法

    /** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有 ...

  8. 获取客户端IP地址定位城市信息

    获取客户端IP地址定位城市信息 1.首先获取客户端的IP地址 function getIPaddress(){ $IPaddress=''; if (isset($_SERVER)){ if (iss ...

  9. Tp框架获取客户端IP地址

    /** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_cl ...

随机推荐

  1. 使用Go语言+Protobuf协议完成一个多人聊天室

    软件环境:Goland Github地址 一.目的 之前用纯逻辑垒完了一个可登入登出的在线多人聊天室(代码仓库地址),这次学习了Protobuf协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...

  2. docker安装和使用

    1.安装的docker版本 docker -v Docker version 17.03.2-ce 2.查看本地的镜像 docker images 3.拉取镜像 docker pull centos: ...

  3. Centos7.0下Nexus私服搭建

    1.下载nexus wget https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.11.2-03-bundle.tar. ...

  4. idea中git颜色不显示或者文件右键没有git按钮解决方法

    VCS--->Enable Version Control Integration,然后选择git就可以了

  5. ambari 安装HDP3.0.1后,启动服务的问题记录

    HDP的ambari集成安装工具真的是比ClouderaManager差上那么一点儿,不说安装的时候就麻烦,即使软件安装包已成功安装,也不意味着可以正常使用了,启动HDP集群过程中还会有不少的错误! ...

  6. Cookie的简单实用

    作用域: 一个域名下的所有网页共用一套cookie. 几个封装好的工具方法: // 添加一个cookie function setCookie(name, value, iDay) { var oDa ...

  7. 关于npm的坑

    http://javascript.ruanyifeng.com/nodejs/packagejson.html 一.npm常用易忘指令 npm list --depth=0:查看所有高级的npm m ...

  8. linux内存和swap

    https://www.cnblogs.com/Zfc-Cjk/archive/2018/02/13/8447270.html

  9. mysql获取相隔时间段的数据

    思路:为时间段内的数据进行编序号,然后计算好相隔时间,拿到id作为搜索条件 SELECT * FROM ( SELECT (@i:=@i+1) as i, id, data_send_time FRO ...

  10. PentestBox在win10里打不开工具

    PentestBox详细安装过程:http://www.cnblogs.com/ESHLkangi/p/8336398.html 在使用PentestBox的时候出现了打不开工具的问题,最后看到一个老 ...