App behind Caddy proxy getting 405 when trying to POST

1. The problem I’m having:

I have a rather complex setup. But I have an app that is accessible via:

https://myapp.company.com/ and then I use caddy-security to enforce OIDC if this URL is hit:
https://myapp.company.com/sso/

It works perfectly fine, everything works as expected. However if I put another caddy proxy in front of this, everything using GET still works, but if I try to POST it fails. Again, the website proxies fine, the GET works fine, but if I try to POST it fails.

http:// {
    @authEmpty not header_regexp X-Token-User-Email ^(.*)
    @authSet header_regexp X-Token-User-Email ^(.*)

    # Bind to the zrok share
    bind {{ .ZrokBindAddress }}

    #If user has not authenticated, then force them through the sso.
    redir @authEmpty /sso{uri}

    route /* {
        reverse_proxy @authSet localhost:631 {
            header_up Host localhost:631
            header_up X-Real-IP {http.request.header.x-forwarded-for}
        }

    }
}

2. Error messages and/or full log output:

3. Caddy version:

v2.8.4

4. How I installed and ran Caddy:

This part is a bit complex, as this tool is embeds caddy into it for this part.

a. System environment:

RHEL8 Server.

b. Command:

This is ran through ZROK, so I am not quite sure what it is doing internally.

d. My complete Caddy config:

http:// {

    @authEmpty not header_regexp X-Token-User-Email ^(.*)
    @authSet header_regexp X-Token-User-Email ^(.*)

    # Bind to the zrok share
    bind {{ .ZrokBindAddress }}

    #If user has not authenticated, then force them through the sso.
    redir @authEmpty /sso{uri}

    route /* {
        reverse_proxy @authSet localhost:631 {
            header_up Host localhost:631
            header_up X-Real-IP {http.request.header.x-forwarded-for}
        }

    }
}

From the error in chrome, giving the 405 I tried to add some CORS stuff…

    header {
        Access-Control-Allow-Origin *
        Access-Control-Allow-Credentials true
        Access-Control-Allow-Methods *
        Access-Control-Allow-Headers *
        defer
    }

5. Links to relevant resources:

That screenshot is showing a GET request, not a POST.

Show your Caddy logs. Add the debug global option, add the log directive. Make a POST request. Make a request with curl -v. Show details.

1 Like

Yeah, so when the proxy was returning the method not allowed, this is returned as a GET message for the text, AFAIK. If you look into the console, you can actually see the first POST, which hits a 302 to the GET and returns the {method not allowed} in the body.

Ultimately, I got this working. So the app that I was proxying actually had an issue with supplying a path/uri as the javascript/css being returned (ultimately controlled by the upstream app itself), was missing my /sso path, which was causing all sorts of issues.

SO, what I ended up doing, was using another wildcard cert I generated, I moved the proxy from redirecting to https://*.my.company.com/sso/

to:
https://*.sso.my.company.com/
This has been preferable, as it will resolve any pathing issues from the upstream app.

 http:// {

     # I decided to test for auth not based on the path, but based on the auth set in the header
     # In the upstream proxy. if the none SSO endpoint is hit, I make sure that any X-Token 
     # header is emptied/clear so that someone cant inject the correct variable in the http header
     @authEmpty not header_regexp X-Token-User-Email ^(.*)
     @authSet header_regexp X-Token-User-Email ^(.*)
 
     # Bind to the zrok share
     bind {{ .ZrokBindAddress }}
 
     #Where labels.5 would return "a" from this URL - a.b.c.d.company.com
     redir @authEmpty https://{labels.5}.sso.zrok.my.company.com{uri}
     route /* {
         #wenapp running on port 8080
         reverse_proxy 127.0.0.1:8080 {
         }
 
     }
 }

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.