Configure nginx to return different files to different authenticated users with the same URI

三世轮回 提交于 2020-01-04 14:11:58

问题


I'm using nginx to serve static files in an embedded system, with no CGI back-end. I have basic-authentication up with multiple username/passwords. I'd like to have a specific URI deliver different content based on the name of the currently authenticated user.

For instance, let's say a browser requested URI /index.html. If the browser was authenticated as user "developer", then it could be served the file /index_developer.html. If instead the browser was authenticated as "administrator" it could be served the file /index_administrator.html.

I only want this redirection to occur on a small set of files; most will be served as-is. I'd also need to block direct access to the actual files so that nobody could do an end-run around the system.


回答1:


First, there is variable $remote_user.

I've end up with following structure:

$ 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

and this nginx config:

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;
}

So request to / will end up in /_auth/USER/index.html, request to /test.html will serve /test.html. And request to /hello.html will serve /_auth/admin/hello.html for user admin and /hello.html for any other user.

Direct access to /_auth/.. is forbidden by internal directive.




回答2:


Although I'm accepting Alexy Ten's answer, as his insight was what got me there, I ended up using a slightly different scheme.

Instead of having the user-specific files residing in a completely separate tree, I chose to have them live right next to the generic files, but adding a standard prefix of _user_<userName>_. For instance, I might have the following two files in the webroot:

  1. /scripts/menus.js
  2. /scripts/_user_developer_menus.js

Then, if logged in as user "developer", a request for /scripts/menus.js would be served the second file, but with any other user the first file would be served.

Here is the core of my nginx configuration:

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;
}

Since both locations are as specific (both regexes) they're searched in order. So, the first location blocks direct access to any of the _user_<userName>_ files. The second location matches any URL, with the path up to the file name left in $1, and the file name left in $1. Then, the try_files looks for a user-specific file, a user-specific directory, a common file, and a common directory, in that order, until it gives up with a 404 error.




回答3:


Simple root /path/to/root/$remote_user is worked for me.

Note: if you use $document_root in auth_basic_user_file (like auth_basic_user_file $document_root/.htpasswd;), then your .htpasswd file should be in all subdirectories, not just root

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


来源:https://stackoverflow.com/questions/23506626/configure-nginx-to-return-different-files-to-different-authenticated-users-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!