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. Github + Hexo 搭建个人博客

    参考博客: 我是如何利用Github Pages搭建起我的博客,细数一路的坑 使用Hexo+Github一步步搭建属于自己的博客(基础) Hexo 准备工作: 本机已安装好 git, npm 和 no ...

  2. 关于Retrofit网络请求URL中含有可变参数的处理

    开题:在此默认各位看官对Retrofit.以及Okhttp已经有过一定的了解及应用,所以今天我们不谈基础入门的东西,今天我们谈在Retrofit请求接口管理类中URL参数含有动态参数的处理方式.一般我 ...

  3. java中获取两个时间中的每一天

    引入下面方法即可: /** * 获取两个时间中的每一天 * @param bigtimeStr 开始时间 yyyy-MM-dd * @param endTimeStr 结束时间 yyyy-MM-dd ...

  4. etl数据同步工具 kettle

    kellet使用 https://www.cnblogs.com/gala1021/p/7814712.html

  5. SpringBoot------异步任务的使用

    步骤,如图所示: 1.添加异步任务业务类 package top.ytheng.demo.task; import java.util.concurrent.Future; import org.sp ...

  6. kylin 使用RESTful API 请求

    目前根据Kylin的官方文档介绍,Kylin的认证是basic authentication,加密算法是Base64,在POST的header进行用户认证我使用的用户和密码是(格式:username: ...

  7. springboot中Properties注解的实现

    关于@PropertySources注解的理解:http://www.imooc.com/article/252889?block_id=tuijian_wz public interface Pro ...

  8. 11.5vue(5)完结

    2018-11-5 19:03:50 老师用了五天把vue昨晚,前后端分离!就是 后端给前端接口,前端用vue,建个项目,然后用vuex接受数据!全在前端显示 后端不涉及任何前端页面!前端用vue把页 ...

  9. jquery面试(2)

    DOM操作——怎样添加.移除.移动.复制.创建和查找节点? (1)创建新节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体 ...

  10. js 时分秒与秒数的转换

    1. 时间戳 格式化为 时分秒(00:00:00) /** * 时间秒数格式化 * @param s 时间戳(单位:秒) * @returns {*} 格式化后的时分秒 */ var sec_to_t ...