keycloak redirect behind reverse proxy

2019-08-20 20:04发布

问题:

I am trying to get keycloak to run behind a kong ingress in kubernetes. The issue I am having is keycloak is adding a port it thinks it is on to the urls it is returning. request: auth.mydomain.com/auth response: auth.mydomain.com:8443/auth/admin/master/console/

client -> NLB:443 -> kong:8443 -> keycloak:8080

keycloak sees the requests x-forwarded-port: 8443 that kong sets and replies with a path on port 8443

Kong must be on 8443 now because of how it is launched in the container under the user kong and doesn't have access to the privileged ports.

I have set the configs keycloak suggests,

/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket, value=proxy-https)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding, value=true)

But these look like they tell undertow to reply with 443 if the request comes in in plain text, my x-forwarded-proto: https is set correctly.

It is also possible that the issue is the host header instead.

----------------------------REQUEST---------------------------
               URI=/auth/admin/
 characterEncoding=null
     contentLength=-1
       contentType=null
            header=X-Real-IP=<REDACTED>
            header=Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            header=Accept-Language=en-us
            header=Accept-Encoding=br, gzip, deflate
            header=User-Agent=<REDACTED>
            header=Connection=keep-alive
            header=X-Forwarded-Proto=https
            header=X-Forwarded-Port=8443
            header=X-Forwarded-For=<REDACTED>
            header=Referer=https://auth.my-domain.com/auth/
            header=Host=auth.my-domain.com:8443
            header=X-Forwarded-Host=auth.my-domain.com
            locale=[en_US]
            method=GET
          protocol=HTTP/1.1
       queryString=
        remoteAddr=/<REDACTED>
        remoteHost=<REDACTED>
            scheme=https
              host=auth.my-domain.com:8443
        serverPort=8443
          isSecure=true
--------------------------RESPONSE--------------------------
     contentLength=0
       contentType=null
            header=Connection=keep-alive
            header=Location=https://auth.my-domain.com:8443/auth/admin/master/console/
            header=Content-Length=0
            header=Date=Fri, 21 Jun 2019 07:05:28 GMT
            status=302

It would be great if I could get keycloak to respond with just a path and not a port, or if it has to respond with a port, just tell it what port I want it to talk on.

回答1:

There is hostname SPI which allows you to set hostname and port for Keycloak instead of retrieving them from HTTP request. You can set ports to default ones (80/443) and resulting URLs will not have a port displayed.

# Replace `request` provider with `fixed`
/subsystem=keycloak-server/spi=hostname:write-attribute(name=default-provider,value=fixed)
# Set hostname and ports for http and https
/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.hostname,value=example.org)
/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.httpsPort,value=443)
/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.httpPort,value=80)

These values are not runtime configurable thus you have to restart Keycloak after the changes.