ansible-middleware/keycloak

Troubles with console access behind a proxy when setting keycloak_quarkus_http_relative_path

Closed this issue ยท 7 comments

SUMMARY

I have troubles accessing the admin console when exposing keycloak under /auth behind a custom nginx proxy.

ISSUE TYPE
  • Bug Report
ANSIBLE VERSION
ansible [core 2.14.4]
  config file = /Users/Giovanni.Toraldo/src/alfresco/alfresco-ansible-deployment/ansible.cfg
  configured module search path = ['/Users/Giovanni.Toraldo/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/Giovanni.Toraldo/.virtualenvs/alfresco-ansible-deployment-LdMEq9P-/lib/python3.10/site-packages/ansible
  ansible collection location = /Users/Giovanni.Toraldo/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/Giovanni.Toraldo/.virtualenvs/alfresco-ansible-deployment-LdMEq9P-/bin/ansible
  python version = 3.10.12 (main, Jul 28 2023, 18:44:44) [Clang 14.0.3 (clang-1403.0.22.14.1)] (/Users/Giovanni.Toraldo/.virtualenvs/alfresco-ansible-deployment-LdMEq9P-/bin/python)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
Collection                     Version
------------------------------ -------
amazon.aws                     6.3.0  
ansible.posix                  1.5.4  
ansible.utils                  2.6.0  
community.aws                  6.3.0  
community.crypto               2.10.0 
community.docker               3.4.8  
community.general              7.4.0  
community.postgresql           2.1.0  
middleware_automation.common   1.1.2  
middleware_automation.keycloak 1.3.0  
STEPS TO REPRODUCE
- name: Install Keycloak
  vars:
    keycloak_quarkus_admin_pass: "{{ identity_admin_password }}"
    keycloak_quarkus_version: "21.1.2"
    keycloak_quarkus_start_dev: true
    keycloak_quarkus_proxy_mode: edge
    keycloak_quarkus_host: localhost
    keycloak_quarkus_http_port: 8082
    keycloak_quarkus_http_relative_path: auth
  ansible.builtin.include_role:
    name: middleware_automation.keycloak.keycloak_quarkus

nginx vhost snippet as a reference:

    location /auth/ {
        proxy_pass http://172.17.0.2:8082/;
        proxy_set_header Host              $host:$server_port;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
EXPECTED RESULTS

I should be able to access keycloak admin console under /auth/admin and my realm under /auth/realms/myrealm

ACTUAL RESULTS

Realm seems properly exposed under /auth because I can reach the public info at https://localhost/auth/realms/alfresco:
Screenshot 2023-10-03 at 17 15 18

If I try to access the console under /auth/admin I get a redirect to https://localhost/admin/master/console/ (which returns 404 because it's outside of the keycloak location).

If I try to access /auth/admin/master/console/ directly I get the Loading the Admin UI message but it fails to load /resources/ (again, because it should have been /auth/resources).

I tried also configuring manually http-relative-path documented here in /etc/systeconfig/keycloak and drop the hostname-path=auth, and actually it seems that I get what I expected without any additional configuration change.

Also setting manually hostname-admin-url (while keeping hostname-path) seems a way to fix my issue, but it's slightly less convenient to set because it requires a full URL.

So, what's actually the reason for having the role argument keycloak_quarkus_http_relative_path to set hostname-path config param instead of the http-relative-path param?

I would like to submit a PR to have the possibility to set http-relative-path within the quarkus role, but not sure how to proceed / if it make sense overall (I am definitively not a keycloak expert).

If I understand the docs correctly, one is for reverse proxy paths (hostname-), the other for the internal paths (http-). We should probably have both configurable, and one should default to other value. We badly need molecule to test those behaviours too

I raised a PR to add support for hostname-url and hostname-admin-url which for my specific use case seems the most reliable way to address the issue.

not sure what to do with http-relative-path change which may break things but it seems the most reasonable thing to do given the name of the role var and choosing another var name may confuse users - up to you.

forgot to mention:

We badly need molecule to test those behaviours too

I am happy to work on them after agreeing on a solution for this, but I am afraid that for the actual console access we are pretty limited unless throwing a javascript-enabled browser in the stack.

Thank you very much for looking into this. So about the molecule tests

I am happy to work on them after agreeing on a solution for this, but I am afraid that for the actual console access we are pretty limited unless throwing a javascript-enabled browser in the stack.

it's more about verifying what values the .well-known/openid-configuration returns
https://github.com/ansible-middleware/keycloak/blob/main/molecule/quarkus/verify.yml#L32
given various combinations of parameters passed to the http- and hostname- variables.

In general, I have had a couple bad choices for choosing defaults (ie. proxy-mode=edge and relative-path=/auth/), that were the result of trying to ease keycloak-legacy -> keyclockx upgrade.

Given there will be a major version bump of the collection soon anyway, I think we should go back to be more transparent, and just take all of the hostname- * and http-* keycloak parameters, with their default, and mimic in our role defaults. So yeah, lets break backwards compatibility here, make it well and as a punishement I'll write the porting guide ๐Ÿฅฒ

In general, I have had a couple bad choices for choosing defaults (ie. proxy-mode=edge and relative-path=/auth/), that were the result of trying to ease keycloak-legacy -> keyclockx upgrade.

At this point I would prefer to mimic the behavior of the upstream keycloakx and do not try to take a different choice, in the end it's a pretty well known that since keycloakx the path has moved to / and default variables of this role should reflect this.

it's more about verifying what values the .well-known/openid-configuration returns https://github.com/ansible-middleware/keycloak/blob/main/molecule/quarkus/verify.yml#L32 given various combinations of parameters passed to the http- and hostname- variables.

with molecule it's not straightforward to test multiple combinations of the available variables - it requires having dedicated scenarios which always carry some duplication and thus making test slower to run.

For now I would keep the main quarkus scenario as it is (exposing service under /) and then try to have a new scenario with keycloak_quarkus_http_relative_path set to /auth which should reflect changes in .well-known/openid-configuration

Fair enough; lets split work on this: while you rework the role parameters for the default scenario, I'll create a new one for the reverse proxy scenario including an additional container running a proxy, deal?

Please don't forget to include keycloak_quarkus_http_relative_path in:

health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration"
)