在Nginx中实现基于HTTP方法(GET/POST/PUT/DELETE等)和请求路径的访问控制(ACL)可以通过多种方式实现。以下是几种常见的配置方法:
$request_method
变量和location
块server {
listen 80;
server_name example.com;
# 允许所有GET请求到/public路径
location /public {
if ($request_method !~ ^(GET|HEAD)$ ) {
return 405;
}
proxy_pass http://backend;
}
# 只允许POST请求到/api/submit
location = /api/submit {
if ($request_method != POST) {
return 405;
}
proxy_pass http://backend;
}
# 允许GET和DELETE到/resources
location /resources {
if ($request_method !~ ^(GET|DELETE)$ ) {
return 405;
}
proxy_pass http://backend;
}
}
limit_except
指令server {
listen 80;
server_name example.com;
# 只允许GET和HEAD方法
location /read-only {
limit_except GET HEAD {
deny all;
}
proxy_pass http://backend;
}
# 允许POST和PUT方法
location /write {
limit_except POST PUT {
deny all;
}
proxy_pass http://backend;
}
}
# 定义允许的方法映射
map $request_method $method_allowed {
default 0;
"GET" 1;
"POST" 1;
"HEAD" 1;
"OPTIONS" 1;
}
# 定义路径和方法组合的ACL
map "$uri:$request_method" $acl {
default 0;
"~/api/users:GET" 1;
"~/api/users:POST" 1;
"~/api/users/[0-9]+:GET" 1;
"~/api/users/[0-9]+:PUT" 1;
"~/api/users/[0-9]+:DELETE" 1;
"~/public/.*:GET" 1;
}
server {
listen 80;
server_name example.com;
location / {
# 检查ACL
if ($acl = 0) {
return 403;
}
proxy_pass http://backend;
}
}
server {
listen 80;
server_name example.com;
location / {
access_by_lua_block {
local acl = {
["GET"] = {
["^/public/.*"] = true,
["^/api/info"] = true
},
["POST"] = {
["^/api/submit"] = true
},
["DELETE"] = {
["^/api/resource/%d+"] = true
}
}
local method = ngx.req.get_method()
local path = ngx.var.uri
if not acl[method] then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
local allowed = false
for pattern, _ in pairs(acl[method]) do
if ngx.re.match(path, pattern) then
allowed = true
break
end
end
if not allowed then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
proxy_pass http://backend;
}
}
日志记录:记录被拒绝的请求以便审计
log_format acl_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$request_method"';
server {
access_log /var/log/nginx/acl.log acl_log;
}
nginx
error_page 403 = @method_not_allowed;
location @method_not_allowed {
return 403 '{"error": "Method not allowed for this resource"}';
}
这些配置可以根据实际需求组合使用,构建出适合您应用场景的访问控制策略。