Configuring logout url with Nginx and KeyCloak

318 Views Asked by At

I am using Nginx as an authenticating reverse proxy using OpenResty & Keycloak within AWS Kubernetes. Both Nginx and Keycloak are pods with a load balancer looking after the https.

The problem I am facing is that Nginx needs to send a request to Keycloak to perform a logout. In order to do this, the following sequence of events is followed:

  1. User clicks “logout” on our UI (or types the url manually)
  2. Request is sent to “https://external.xxx/logout”
  3. This is interpreted by Nginx as a request to logout and so it performs the following:
  • Discovery request is sent to “http://internal.xxx/auth/realms/xxx/.well-known/openid-configuration”

  • The endpoint is read from this response: "end_session_endpoint":"https://external.xxx/auth/realms/xxx/protocol/openid-connect/logout”

  • A request is then sent to this endpoint from Nginx to initiate the logoff.

  1. The user is logged off & returned to login screen.

I believe that the issue is that the endpoint is returned as https://external.xxx as opposed to http://internal.xxx and I can find no way to change this in keycloak. Consequently the nginx pod is now making a request to the public external url/ip and this needs to be allowed in the egress policy. Adding the external IP address to the egress rule does cause it to work - but is obviously a bit disgusting.

Here's the relevant part of the nginx config:

        # Secured - Auth through keycloak
    access_by_lua '
      -- Require authentication for everything except keycloak
      if (ngx.var.request_uri:find("^/auth/" ) == nil)  then
          local opts = {
            redirect_uri_path = "/redirect_uri",
            discovery = "http://keycloak.xxx.svc.cluster.local/auth/realms/xxx/.well-known/openid-configuration",
            client_id = "nginx",
            client_secret = "xxx",
            redirect_uri_scheme = "http",
            logout_path = "/logout",
            post_logout_redirect_uri  = "http://192.168.1.12/grafana/logout",
            revoke_tokens_on_logout = true
          }
          -- call introspect for OAuth 2.0 Bearer Access Token validation
          local res, err = require("resty.openidc").authenticate(opts)
          if err then
            ngx.status = 403
            ngx.say(err)
            ngx.exit(ngx.HTTP_FORBIDDEN)
          end
      end
    ';

My questions are:

  1. I'm 'assuming' that the end_session_endpoint is what is being used here - is this assumption correct?
  2. Is there a way to override the end_session_endpoint returned by Keycloak. I can see that several other endpoints return the internal host when queried using the internal host - (and external when external) but the end_session_endpoint is always the external.

Any insight here is greatly appreciated!!

0

There are 0 best solutions below