我在反向 HAProxy 1.8 后面设置了一个实验性沙箱,其中包含一个简单的 Nifi 1.9.2 服务。除了上传模板的功能之外,一切都按预期工作。我目前没有使用任何形式的身份验证或证书(它是一个沙箱)
HAProxy 中的代理设置很简单:
backend service-nifi
# I think this first line is the issue
http-request set-header Origin http://127.0.0.1:8080
http-request add-header X-ProxyPort 80
http-request add-header X-ProxyScheme http
http-request add-header X-ProxyHost experimental
server nifi-server 127.0.0.1:8080 check
Nifi相关属性部分如下:
# web properties #
nifi.web.war.directory=./lib
nifi.web.http.host=127.0.0.1
nifi.web.http.port=8080
nifi.web.http.network.interface.default=
nifi.web.https.host=
nifi.web.https.port=
nifi.web.https.network.interface.default=
nifi.web.jetty.working.directory=./work/jetty
nifi.web.jetty.threads=200
nifi.web.max.header.size=16 KB
# whatever I put next breaks my current setup. I don't understand why yet
nifi.web.proxy.context.path=
nifi.web.proxy.host=
无论我在哪里寻找无效请求背后的解决方案,答案总是相同的:当前版本的 Nifi 具有 CORS 过滤,我应该将
Origin
标头设置为 Nifi 期望的内容。我猜应该如下(如set-header
行所示):
http
127.0.0.1
8080
我已经与
tcpdump
确认该请求正在按预期转发:
sudo tcpdump -s 1024 -l -A -i lo 'tcp port 8080' > dump
这是我的要求:
21:31:43 IP localhost.38642 > localhost.http-alt: Flags [P.], seq ..., ack ..., win ..., options [...], length ...: HTTP: POST /nifi-api/process-groups/{id}/templates/upload HTTP/1.1
...
POST /nifi-api/process-groups/{id}/templates/upload HTTP/1.1
Host: experimental
User-Agent: Mozilla... Firefox...
Accept: application/xml, text/xml, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------1434591419995738407236256922
Content-Length: 10378
Referer: http://experimental/nifi/
Origin: http://127.0.0.1:8080
X-ProxyPort: 80
X-ProxyScheme: http
X-ProxyHost: experimental
这是回复:
21:31:43 IP localhost.http-alt > localhost.38642: Flags [P.], seq ..., ack ..., win ..., options [...], length ...: HTTP: HTTP/1.1 403 Forbidden
...
HTTP/1.1 403 Forbidden
Date: Mon, 21 Oct 2019 21:31:43 GMT
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
X-XSS-Protection: 1; mode=block
Content-Length: 20
Server: Jetty(9.4.11.v20180605)
Invalid CORS request
我从 存储库 知道 POST 不属于端点可接受的方法
/process-groups/*/templates/upload
。
我还尝试通过调整
conf/logback.xml
文件来提高所有内容的日志记录级别以帮助排除故障,但输出是巨大的,而且大部分都是噪音。
我对这个问题感到非常沮丧。我读过很多关于这个问题的帖子,并且我已经尝试了几乎所有的方法。很多示例使用 NginX 或 Apache。我没有这种灵活性,但我认为 HAProxy 已经足够了。我最好的选择是有些东西我没有看到或者我完全忽略了。
如果您查看您的请求,则表明您是由
http://experimental/nifi/
推荐的,而来源是 http://127.0.0.1:8080
。
如果您将您正确怀疑是问题的第一行更改为
http://experimental
,那么该帖子应该会成功通过。
或者,不太正确的 hacky 方法是添加一个 Access-Control-Allow-Origin 标头,其值为
http://127.0.0.1:8080
。
我认为您遇到了 NiFi 跨站请求伪造保护。这是手册的链接:https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#csrf-protection
当您执行授权请求(/access/token)时,您会得到两个 cookie:__Secure-Authorization-Bearer 和 __Secure-Request-Token。
您可以将 __Secure-Authorization-Bearer cookie 的值用作授权标头的值,或者您的 http 客户端可以自动添加它。
为了避免 CSRF 安全过滤器,您应该在所有 POST/PUT/DELETE 请求标头中添加名称为 Request-Token 且值为 __Secure-Request-Token cookie 的标头。