Skip to content

Support Keycloak Version 17.0.0 #51

@predictap-droscoe

Description

@predictap-droscoe

Version 17.0.0 of keycloak has been released and includes a change which removes auth from the default context path making this library no longer work with that version by default. I'd like to use this library with a version 17.0.0 instance of keycloak without changing the http-relative-path on the server, would you be open to accepting a PR which introduces such support?

My plan for a solution would be to introduce a context_path argument to all relevant classes (KeycloakClient, KeycloakAdminBase, and any class that inherits from WellKnownMixin) which defaults to /auth, change every _paths definition to not include /auth, update the relevant classes to use the context_path when building urls e.g. in KeycloakAdminBase.get_path, and add the context_path argument to KeycloakRealm and pass it to each class returned by a method.

For example, the KeycloakClient.__init__ method would look like this:

class KeycloakClient(object):
    _server_url = None
    _context_path = None
    _session = None
    _headers = None

    def __init__(self, server_url, headers=None, logger=None, context_path='/auth'):
        """
         :param str server_url: The base URL where the Keycloak server can be
            found
        :param dict headers: Optional extra headers to send with requests to
            the server
        :param logging.Logger logger: Optional logger for client
        :param str context_path: Optional context path for building urls (defaults to `/auth`)
        """
        if logger is None:
            if hasattr(self.__class__, '__qualname__'):
                logger_name = self.__class__.__qualname__
            else:
                logger_name = self.__class__.__name__

            logger = logging.getLogger(logger_name)

        self.logger = logger
        self._server_url = server_url
        self._headers = headers or {}
        self._context_path = context_path

The KeycloakAdminBase class would look like:

class KeycloakAdminBase(object):
    _client = None
    _paths = None

    def __init__(self, client):
        """
        :param keycloak.admin.KeycloakAdmin client:
        """
        self._client = client

    def get_path(self, name, **kwargs):
        if self._paths is None:
            raise NotImplementedError()
        formatted_path = self._paths[name].format(**kwargs)
        return self.client._context_path + formatted_path

And the KeycloakRealm class would begin:

class KeycloakRealm(object):

    _server_url = None
    _realm_name = None
    _context_path = None

    _headers = None
    _client = None

    def __init__(self, server_url, realm_name, headers=None, context_path='/auth'):
        """
        :param str server_url: The base URL where the Keycloak server can be
            found
        :param str realm_name: REALM name
        :param dict headers: Optional extra headers to send with requests to
            the server
        :param str context_path: Optional context path for building urls (defaults to `/auth`)
        """
        self._server_url = server_url
        self._realm_name = realm_name
        self._headers = headers
        self._context_path = context_path

    @property
    def client(self):
        """
        :rtype: keycloak.client.KeycloakClient
        """
        if self._client is None:
            self._client = KeycloakClient(server_url=self._server_url,
                                          headers=self._headers, context_path=self._context_path)
        return self._client

And every _paths object would remove the /auth at the beginning.

Then the API stays the same for most users but v17 users can pass context_path='' to remove the /auth part.

Let me know if this plan sounds acceptable to you, and if so I will begin implementing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions