diff --git a/README.md b/README.md index 8911e95..3ed3bab 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,8 @@ Instructions for specific OpenID Connect backends below. You will need to use the following command line arguments: ```bash ---backend MicrosoftEntra --entra-tenant-id "" +--backend MicrosoftEntra \ +--entra-tenant-id "" ``` You will need to register an application to interact with `Microsoft Entra`. @@ -200,12 +201,30 @@ Do this as follows: You will need to use the following command line arguments: ```bash ---backend Keycloak --keycloak-base-url "/" --keycloak-realm "" +--backend Keycloak \ +--keycloak-base-url "/" \ +--keycloak-domain-attribute "" \ +--keycloak-realm "" ``` You will need to register an application to interact with `Keycloak`. Do this as follows: +- Under the realm option `Client scopes` create a new scope, e.g. `domainScope` with: + - Type: `Default` + - Include in token scope: `true` + - Save +- In the created scope click `Mappers` > `Configure new mapper` and now create either + - `Hardcoded claim` + - => Every user gets the same domain + - name: `domain` + - token claim name: `domain` + - claim value: `` + - `User attribute` + - => Every user has an attribute for the domain + - name: `domain` + - user attribute: `` + - token claim name: `domain` - Create a new `Client` in your `Keycloak` instance. - Set the name to whatever you choose (e.g. `apricot`) - Enable `Client authentication` @@ -220,3 +239,4 @@ Do this as follows: - `realm-management` > `manage-users` - `realm-management` > `query-groups` - `realm-management` > `query-users` +- Under `Client scopes` click `Add client scope` > `domainScope`. Make sure to select type `Default` diff --git a/apricot/oauth/keycloak_client.py b/apricot/oauth/keycloak_client.py index 3555610..54ddaaa 100644 --- a/apricot/oauth/keycloak_client.py +++ b/apricot/oauth/keycloak_client.py @@ -16,15 +16,18 @@ class KeycloakClient(OAuthClient): def __init__( self: Self, keycloak_base_url: str, + keycloak_domain_attribute: str, keycloak_realm: str, **kwargs: Any, ) -> None: """Initialise a KeycloakClient. @param keycloak_base_url: Base URL for Keycloak server + @param keycloak_domain_attribute: Keycloak attribute used to define your domain @param keycloak_realm: Realm for Keycloak server """ self.base_url = keycloak_base_url + self.domain_attribute = keycloak_domain_attribute self.realm = keycloak_realm redirect_uri = "urn:ietf:wg:oauth:2.0:oob" # this is the "no redirect" URL @@ -151,16 +154,20 @@ def users(self: Self) -> list[JSONDict]: username = user_dict.get("username") attributes: JSONDict = {} attributes["cn"] = username - attributes["uid"] = username - attributes["oauth_username"] = username - attributes["displayName"] = full_name - attributes["mail"] = user_dict.get("email") attributes["description"] = "" + attributes["displayName"] = full_name + attributes["domain"] = user_dict["attributes"].get( + self.domain_attribute, + [None], + )[0] attributes["gidNumber"] = user_dict["attributes"]["uid"][0] attributes["givenName"] = first_name or "" attributes["homeDirectory"] = f"/home/{username}" if username else None + attributes["mail"] = user_dict.get("email") attributes["oauth_id"] = user_dict.get("id", None) + attributes["oauth_username"] = username attributes["sn"] = last_name or "" + attributes["uid"] = username attributes["uidNumber"] = user_dict["attributes"]["uid"][0] output.append(attributes) except KeyError: diff --git a/run.py b/run.py index cd1b1a5..9df97e4 100644 --- a/run.py +++ b/run.py @@ -82,6 +82,12 @@ type=str, help="Keycloak Realm.", ) + keycloak_group.add_argument( + "--keycloak-domain-attribute", + type=str, + default="domain", + help="The attribute in Keycloak that contains the users' domain.", + ) # Options for Redis cache redis_group = parser.add_argument_group("Redis") redis_group.add_argument(