如何使用nginx做用户级访问控制

我想有nginx的用户级访问控制到特定的url,

对于其他用户<uid> ,它们仅限于访问http://myserver.com/<uid> (METHOD POST )。 像用户larrycai只能发布到http://myserver.com/larrycai/xxx

我不想在上游服务器上有这个控制。

基本身份validation用于访问身份validation,如下所示

 server { ... auth_basic "Auth"; auth_basic_user_file conf/htpasswd; } 

现在我怎么能authentication的用户映射到自己的url? (我是nginx的新手)。

我的用例是dockerregistry前面的nginx docker容器,有更好的用户访问控制。

在2015.1.11更新

uid与unix系统无关,仅用于应用程序,映射到REST接口

是否有可能使用像openresty(卢阿为基础)的额外模块?

我已经能够找出一个解决方案,使许多用户从我的码头注册表中拉出容器,只有特殊的授权用户才能使用ngx_openresty-1.7.7.1推送到我的注册表

/usr/local/openresty/nginx/conf/nginx.conf

 worker_processes 1; error_log /var/log/lua.log notice; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; # For versions of nginx > 1.3.9 that include chunked transfer encoding support # Replace with appropriate values where necessary upstream docker-registry { server localhost:5000; } server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } } server { listen 443; server_name docker-registry01.company.com; ssl on; ssl_certificate /etc/ssl/certs/docker-registry; ssl_certificate_key /etc/ssl/private/docker-registry; client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) chunked_transfer_encoding on; location / { auth_basic "Restricted"; auth_basic_user_file docker-registry.htpasswd; access_by_lua_file 'authorize.lua'; include docker-registry.conf; } location /_ping { auth_basic off; include docker-registry.conf; } location /v1/_ping { auth_basic off; include docker-registry.conf; } } } 

/usr/local/openresty/nginx/conf/docker-registry.conf

 proxy_pass http://docker-registry; proxy_set_header Host $http_host; # required for docker client's sake proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP proxy_set_header Authorization ""; # see https://github.com/dotcloud/docker-registry/issues/170 proxy_read_timeout 900; 

/usr/local/openresty/nginx/authorize.lua

 -- authorization rules local restrictions = { all = { ["^/$"] = { "HEAD" } }, user = { ["^/$"] = { "HEAD", "GET" }, ["^/v1/search$"] = { "HEAD", "GET" }, ["^/v1/repositories/.*$"] = { "HEAD", "GET" }, ["^/v1/images/.*$"] = { "HEAD", "GET" } }, admin = { ["^/$"] = { "HEAD", "GET" }, ["^/v1/search$"] = { "HEAD", "GET" }, ["^/v1/repositories/.*$"] = { "HEAD", "GET", "PUT" }, ["^/v1/images/.*$"] = { "HEAD", "GET", "PUT" } } } -- list of roles and users local user_role = { all = {"all"}, user = {"user", "user2", "user3", "etc..."}, admin = {"admin", "dave_albert", "other_admin", "jenkins"} } -- get authenticated user as role local user = ngx.var.remote_user local role = nil for _role, user_list in pairs(user_role) do for k,user_name in pairs(user_list) do if user_name == user then role = _role end end end -- exit 403 when no matching role has been found if restrictions[role] == nil then ngx.header.content_type = 'text/plain' ngx.status = 403 ngx.say("403 Forbidden: You don't have access to this resource/role.") return ngx.exit(403) end -- get URL local uri = ngx.var.uri -- get method local method = ngx.req.get_method() local allowed = false for path, methods in pairs(restrictions[role]) do -- path matched rules? local p = string.match(uri, path) local m = nil -- method matched rules? for _, _method in pairs(methods) do m = m and m or string.match(method, _method) end if p and m then allowed = true end end if not allowed then ngx.header.content_type = 'text/plain' ngx.log(ngx.WARN, "Role ["..role.."] not allowed to access the resource ["..method.." "..uri.."]") ngx.status = 403 ngx.say("403 Forbidden: You don't have access to this resource.") return ngx.exit(403) else ngx.log(ngx.WARN, "User ["..user.."] accessing resource ["..method.." "..uri.."]") end 

你看不到,得到你的配置中的用户。

您可以通过限制某些访问

 location /larrycai { deny all; } 

总而言之,你不能通过nginx限制这个。 你可以写一个PHP脚本,但这似乎并不是你想要的。