Search code examples
corsapache-nifihaproxy

Uploading Nifi template responds with 403 error + browser logs invalid CORS request


I set up an experimental sandbox with a simple Nifi 1.9.2 service behind a reverse HAProxy 1.8. Everything is working as expected except for the feature to upload templates. I am not using any form of authentication or certificates at the moment (it's a sandbox)

The proxy set up in HAProxy was easy:

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

The relevant Nifi properties part is as follows:

# 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=

Everywhere I look for the solution behind the invalid request, the answer is always the same: the current version of Nifi has CORS filtering and I am supposed to set the Origin header to what Nifi expects it to be. I would guess that it should be as follows (as shown in the set-header line):

  • scheme: http
  • host: 127.0.0.1
  • port: 8080

I have already confirmed with tcpdump that the request is being forwarded as intended: sudo tcpdump -s 1024 -l -A -i lo 'tcp port 8080' > dump

Here's my request:

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

This is the response:

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

I know from the repository that POST is not among the accepted methods for the endpoint /process-groups/*/templates/upload.

I have also tried to increase the logging level of everything by tweaking the conf/logback.xml file to help troubleshoot but the output is overwhelming and it is mostly noise.

I am quite frustrated with this problem. I have read many threads about this issue and I've tried almost everything under the Sun. A lot of examples use NginX or Apache. I don't have that flexibility but I assess that HAProxy is more than enough. My best bet is that there is something I'm not seeing or that I have completely ignored.


Solution

  • If you take a look at your request it's indicating that you're being referred by http://experimental/nifi/ whereas the origin is http://127.0.0.1:8080.

    If you change the first line you rightly suspected to be the issue to http://experimental then the post should go through successfully.

    Alternatively, the not-so-correct hacky method would be to add an Access-Control-Allow-Origin header with the value http://127.0.0.1:8080.