构建 Owin 中间件 来获取客户端IP地址

摘要:
除此之外,我们还在博客上讨论了在ASP.NETWebAPI中检索客户端IP地址的可能方法。随着WebAPI2架构的最新变化,以及Owina和Katanap项目作为通用Web的合并

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:

构建 Owin 中间件 来获取客户端IP地址第1张

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

构建 Owin 中间件 来获取客户端IP地址第2张

免责声明:文章转载自《构建 Owin 中间件 来获取客户端IP地址》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇编码 编码的转化spring-入门下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

尚硅谷《谷粒商城项目总结》

1、前言 花了几天的时间把尚硅谷的视频项目看完了,跟着做了一遍,基本上没啥大的问题,有几个小问题也做了总结。 技术方面除了 vue/nacos 没用过,其他的基本都用过,我们公司实际开发中用的也就是这一套东西。 中间的不想看,可以直接点击目录,看总结,总结里有你针对此项目所有的总结及问题解决的说明 1.1技术栈 springcloud 统一配置中心:apo...

Android系统中的广播(Broadcast)机制简要介绍和学习计划

  在Android系统中,广播(Broadcast)是在组件之间传播数据(Intent)的一种机制;这些组件甚至是可以位于不同的进程中,这样它就像Binder机制一样,起到进程间通信的作用;本文通过一个简单的例子来学习Android系统的广播机制,为后续分析广播机制的源代码作准备。         在Android系统中,为什么需要广播机制呢?广播机制,...

Java 生成指定时间范围的随机时间、随机中文姓名、随机字符姓名、随机数

解决问题: Java生成指定时间范围的随机时间? Java生成随机中文姓名? Java生成随机字符姓名? Java生成随机数? 代码: import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.text.SimpleDateFormat...

okhttp同步异步下载文件,与http请求工具类

<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.8.0</ve...

【笔记】SpringBoot+Shiro 实现简单权限管理(使用mysql数据库)

网上翻了好久 都没有SpringBoot+Shiro的入门教程 原本想看《跟我学Shiro》 然后发现这是从头开始 但是我就需要和SpringBoot整一块 不需要那么多的东西 感觉这个当参考书不错 于是东拼西凑终于整成了 把别人的教程上我用不到的都删了 该改的改 终于拿到了我理想中的效果 先是数据库部分 因为是简单的实现 就没有弄得太复杂 三部分 用户...

Android Volley框架的几种post提交请求方式

首先简单描写叙述一下Google的Android开发团队在2013年推出的一个网络通信框架Volley.它的设计目标是进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比方下载文件等,Volley的表现就不尽如人意。 在app开发中,我们最常见的就是从appclient向服务端发一个http请求.对于两种主要的web请求方式get和post...