12

I'm using Nginx (version 1.9.9) as a reverse proxy to my backend server. It needs to perform authentication/authorization based on the contents of the POST requests. And I'm having trouble reading the POST request body in my auth_request handler. Here's what I got.

Nginx configuration (relevant part):

server {
    location / {
        auth_request /auth-proxy;
        proxy_pass http://backend/;
    }

    location = /auth-proxy {
        internal;
        proxy_pass http://auth-server/;
        proxy_pass_request_body on;
        proxy_no_cache "1";
    }
}

And in my auth-server code (Python 2.7), I try to read the request body like this:

class AuthHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def get_request_body(self):
        content_len = int(self.headers.getheader('content-length', 0))
        content = self.rfile.read(content_len)
        return content

I printed out the content_len and it had the correct value. However, the self.rfile.read() will simply hang. And eventually it will time out and returns "[Errno 32] Broken pipe".

This is how I posted test data to the server:

$ curl --data '12345678' localhost:1234

The above command hangs as well and eventually times out and prints "Closing connection 0".

Any obvious mistakes in what I'm doing?

Thanks much!

4

1 回答 1

11

nginx-auth-request-module 的代码在 nginx.com 注释。该模块总是用空缓冲区替换 POST 正文。

在其中一个教程中,他们解释了原因,并指出:

由于请求正文被丢弃以进行身份​​验证子请求,因此您需要将 proxy_pass_request_body 指令设置为 off 并将 Content-Length 标头设置为空字符串

原因是 auth 子请求是通过 HTTP GET 方法发送的,而不是 POST。由于 GET 没有正文,因此正文被丢弃。现有模块的唯一解决方法是从请求正文中提取所需信息并将其放入传递给身份验证服务的 HTTP 标头中。

于 2016-12-16T23:18:02.650 回答