I would like to authorize users depending on the requested path. For example, only user1 and user2 should have access to /projects/1.
My /etc/nginx/.htpasswd looks like this:
user1:$hashed_psswd1
user2:$hashed_psswd2
user3:$hashed_psswd3
...
Here's the location block in nginx config:
location ~ /projects(/.*) {
auth_basic "Please provide credentials";
auth_basic_user_file /etc/nginx/.htpasswd;
include /var/www/html/myapp.com/config/nginx/git-http-backend.conf;
}
And the rails action:
def git
redirect_to "#{Rails.configuration.x.domain}/projects/#{@project.id}"
end
The authentication seems to work:
$ git clone http://localhost:3000/projects/1
Cloning into '1'...
Username for 'http://localhost:3001': user1
Password for 'http://deploy@localhost:3001':
remote: Enumerating objects: 94, done.
# ... it successfully clones the git repo...
The problem is that user3 is able to clone project 1, but he shouldn't be able to clone such project.
So how could I authorize users in nginx rails depending on the requested path?
CodePudding user response:
Here is a config I've just tested with OpenResty 1.17.8.2 (based on nginx 1.17.8 core) and can confirm that it is workable:
map $uri $realm {
~^/projects/ "Protected projects";
~^/images/ "Protected images";
default off;
}
map $uri $authfile {
~^/projects/ /path/to/.htpasswd_projects;
~^/images/ /path/to/.htpasswd_images;
}
server {
...
auth_basic $realm;
auth_basic_user_file $authfile;
...
}
.htpasswd_projects and .htpasswd_images files contains each own user/password list. With the above config every URI started with /projects/ prefix is protected with basic authorization and available only for users listed in the htpasswd_projects file, every URI started with /images/ is protected with basic authorization and available only for users listed in the htpasswd_images file, and rest of the URIs are available without authorization for everyone.
Update
Here is another example, using dynamically generated .htpasswd path depending on the requested URI:
location ~ ^/projects/(?<project_id>[^/] ) {
if (!-f /var/www/projects/$project_id/.htpasswd) {
# '.htpasswd' file for the requested project does not exists
# assuming wrong project ID is given, returning HTTP 404 Not found
return 404;
}
auth_basic "Please provide credentials for project $1";
auth_basic_user_file /var/www/projects/$project_id/.htpasswd;
...
}
This one would work with the following .htpasswd files tree:
/var/www/projects
├── 1
│ └── .htpasswd
├── 2
│ └── .htpasswd
...
You can place this projects directory wherever you want, it isn't dependent on web server root.
