配置nginx以使用相同的URI将不同的文件返回给不同的经过身份验证的用户

时间:2014-05-07 00:15:36

标签: authentication nginx basic-authentication username

我正在使用nginx在嵌入式系统中提供静态文件,没有CGI后端。我有多个用户名/密码的基本身份验证。我希望有一个特定的URI根据当前经过身份验证的用户的名称提供不同的内容。

例如,假设浏览器请求URI /index.html。如果浏览器被认证为用户“developer”,则可以将其提供给文件/index_developer.html。如果浏览器被认证为“管理员”,则可以将其提供给文件/index_administrator.html。

我只希望在一小组文件上进行此重定向;大多数将按原样提供。我还需要阻止对实际文件的直接访问,以便没有人可以在系统中进行最终运行。

3 个答案:

答案 0 :(得分:5)

首先,有变量$remote_user

我最终得到以下结构:

$ tree
.
├── _auth
│   ├── admin
│   │   ├── f
│   │   │   └── index.html
│   │   ├── hello.html
│   │   └── index.html
│   └── user
│       ├── f
│       │   └── index.html
│       └── index.html
├── f
│   └── x.html
├── hello.html
├── test.html
└── x
    └── index.html

和这个nginx配置:

auth_basic "Restricted area";
auth_basic_user_file path/to/passwd/file;

root /path/to/root;

location / {
    try_files /_auth/$remote_user$uri
              /_auth/$remote_user$uri/index.html
              $uri $uri/index.html =404;
}

location /_auth/ {
    internal;
}

因此/的请求最终会在/_auth/USER/index.html中,/test.html的请求将会/test.html/hello.html的请求将为用户/_auth/admin/hello.html提供admin,为任何其他用户提供/hello.html

/_auth/..指令禁止直接访问internal

答案 1 :(得分:2)

虽然我接受了Alexy Ten的回答,因为他的洞察力让我在那里,我最终使用了一个稍微不同的方案。

我没有让用户特定的文件驻留在一个完全独立的树中,而是选择将它们放在通用文件旁边,但添加标准前缀_user_<userName>_。例如,我可能在webroot中有以下两个文件:

  1. /scripts/menus.js
  2. /scripts/_user_developer_menus.js
  3. 然后,如果以用户&#34;开发人员&#34;身份登录,则会向第二个文件提供/scripts/menus.js请求,但是对于任何其他用户,将提供第一个文件。

    这是我的nginx配置的核心:

    location ~ "^.*/_user_[^/]*$" {
        internal;
    }
    
    location ~ "^(.*)/([^/]*)$" {
        auth_basic_user_file /opt/product/cfg/nginx_conf/htpasswd;
        try_files   $1/_user_${remote_user}_$2$is_args$args
                    $1/_user_${remote_user}_$2/index.html$is_args$args
                    $1/$2$is_args$args
                    $1/$2/index.html$is_args$args
                    =404;
    }
    

    由于两个位置都是特定的(两个正则表达式),因此按顺序搜索它们。因此,第一个位置阻止直接访问任何_user_<userName>_文件。第二个位置匹配任何网址,文件名前面的路径位于$1,文件名保留在$1中。然后,try_files按顺序查找用户特定文件,用户特定目录,公共文件和公共目录,直到它放弃404错误。

答案 2 :(得分:0)

简单root /path/to/root/$remote_user为我工作。

注意:如果您在$document_root中使用auth_basic_user_file(例如auth_basic_user_file $document_root/.htpasswd;),那么您的.htpasswd文件应该在所有子目录中,而不是只是根

$ tree -a
.
├── .htpasswd
├── user1
│   ├── hello1
│   └── .htpasswd -> ../.htpasswd
├── user2
│   ├── hello2
│   └── .htpasswd -> ../.htpasswd
└── user3
    ├── hello3
    └── .htpasswd -> ../.htpasswd