有一段时间没有写东西了,忙,心情不太好,生病等一堆事情将生活充斥着…

前一阵子因为工作的需要,需要实现资源的访问控制,且需要与应用结合起来,通过些时间的考虑,得出一个可以实现的方案,记下,权当笔记。

问题情况:

相册或者文章等资源,需要设置多种访问的控制,比如:好友可见、好友中的单个分组可见等。

解决办法:

利用nginx的几个mod结合来实现,相关的mod有:http_accesskey_module、mod_parsed_vars。http_accesskey_module估名思意是用来做限制访问的,通过传递的key检测来实现访问控制。mod_parsed_vars模块是用于得到生成key相关参数的模块,比如说http_accesskey_module中的key是依据COOKIE/GET/POST中的一个或者多个值来生成的,那么我们需要让nginx获取到这些具体的值,而nginx本身是不具备的,mod_parsed_vars起的就是这个作用。

我们要来实现访问控制的思路很简单,当用户登录后,检测到对资源的访问权限后,如果具有访问权限,那么依据资源的关键字、COOKIE/GET/POST中的一个可依赖的值、一个服务器端的密钥来生成一个用于http_accesskey_module模块来进行访问限制检查的KEY。

举例如下:

当用户登录后COOKIE中会有SESSIONID,假如用户要访问图片编号为PID的图片,图片地址为:http://img.com/PID.jpg。服务器端的密钥为PKEY,这个时候用于http_accesskey_module的KEY的生成方法则可以简单为:KEY = md5(SESSIONID + PID + PKEY).那么实现访问的URL则为:http://img.com/PID.jpg?key=KEY.同时我们在nginx中做相应的配置,来对图片的访问进行控制,就能达到限制访问的目的了。

相关配置参考:

我测试用的nginx版本为0.7.13.

1、下载http_accesskey_module和mod_parsed_vars两个模块。(如果你需要,可以找我。)

2、执行下面的一些命令,不做解释了。

cd nginx-0.7.13
bzcat ../nginx-accesskey-2.0.3.diff.bz2 | patch -p1
patch -p0 < /root/software/mod_parsed_vars/ngx_http_parsed_variables.patch
./configure –with-http_accesskey_module  –add-module=/root/software/mod_parsed_vars
make && make install

3、修改nginx的配置文件限制访问,注:密钥为&%*&*)(),使用的加密参数项为:GET中的pid的值。

server {
listen       81;

root   /www/images;

access_log  /var/log/nginx/host.access.log  main;

location / {
accesskey             on;
accesskey_hashmethod  md5;
accesskey_arg         “key”;
accesskey_signature   “&%*&*)()$args_pid”;
index  index.html index.htm index.php;
}
}

4、在你的程序中生成访问的URL(PHP代码)。

$pkey = ‘&%*&*)()’;

$pid = ’1314′;

$access_key = md5($pkey . $pid);

echo ‘<a href=”http://sitename/’ . $pid . ‘.jpg?key=’ . $access_key .’”>查看图片</a>’;

OK,到此为此我们基本实现的基于应用的权限控制,且方法灵活,因为KEY的生成由应用程序来控制,能进行任意的修改和变动,而架构不受影响。

您可能还喜欢

4 Responses to “用Nginx实现与应用结合的访问控制”

  1. sleetdrop Says:

    实用的好东东,mark.

  2. libing Says:

    好不容易见你来我这逛一回啦!:)

  3. pipa Says:

    sessionid、pid、key都是由客户端传递给nginx的,nginx据此进行鉴权,那么只要鉴权通过,其他客户端就可以伪造类似的请求给服务器端了,有什么办法阻止伪造?

  4. libing Says:

    key是存储在服务器端的,客户端是没法伪造的!

Leave a Reply