Skip to content

Commit 6dcd420

Browse files
authored
Merge pull request #51 from Shirkanesi/fix/domain-keycloak
Allow specification of attribute for domain in KeycloakClient
2 parents 5fe8ddd + 62d8b6f commit 6dcd420

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ Instructions for specific OpenID Connect backends below.
174174
You will need to use the following command line arguments:
175175

176176
```bash
177-
--backend MicrosoftEntra --entra-tenant-id "<your tenant ID>"
177+
--backend MicrosoftEntra \
178+
--entra-tenant-id "<your tenant ID>"
178179
```
179180

180181
You will need to register an application to interact with `Microsoft Entra`.
@@ -200,12 +201,30 @@ Do this as follows:
200201
You will need to use the following command line arguments:
201202

202203
```bash
203-
--backend Keycloak --keycloak-base-url "<your hostname>/<path to keycloak>" --keycloak-realm "<your realm>"
204+
--backend Keycloak \
205+
--keycloak-base-url "<your hostname>/<path to keycloak>" \
206+
--keycloak-domain-attribute "<the attribute used as your domain>" \
207+
--keycloak-realm "<your realm>"
204208
```
205209

206210
You will need to register an application to interact with `Keycloak`.
207211
Do this as follows:
208212

213+
- Under the realm option `Client scopes` create a new scope, e.g. `domainScope` with:
214+
- Type: `Default`
215+
- Include in token scope: `true`
216+
- Save
217+
- In the created scope click `Mappers` > `Configure new mapper` and now create either
218+
- `Hardcoded claim`
219+
- => Every user gets the same domain
220+
- name: `domain`
221+
- token claim name: `domain`
222+
- claim value: `<your domain>`
223+
- `User attribute`
224+
- => Every user has an attribute for the domain
225+
- name: `domain`
226+
- user attribute: `<the attribute used as your domain>`
227+
- token claim name: `domain`
209228
- Create a new `Client` in your `Keycloak` instance.
210229
- Set the name to whatever you choose (e.g. `apricot`)
211230
- Enable `Client authentication`
@@ -220,3 +239,4 @@ Do this as follows:
220239
- `realm-management` > `manage-users`
221240
- `realm-management` > `query-groups`
222241
- `realm-management` > `query-users`
242+
- Under `Client scopes` click `Add client scope` > `domainScope`. Make sure to select type `Default`

apricot/oauth/keycloak_client.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ class KeycloakClient(OAuthClient):
1616
def __init__(
1717
self: Self,
1818
keycloak_base_url: str,
19+
keycloak_domain_attribute: str,
1920
keycloak_realm: str,
2021
**kwargs: Any,
2122
) -> None:
2223
"""Initialise a KeycloakClient.
2324
2425
@param keycloak_base_url: Base URL for Keycloak server
26+
@param keycloak_domain_attribute: Keycloak attribute used to define your domain
2527
@param keycloak_realm: Realm for Keycloak server
2628
"""
2729
self.base_url = keycloak_base_url
30+
self.domain_attribute = keycloak_domain_attribute
2831
self.realm = keycloak_realm
2932

3033
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]:
151154
username = user_dict.get("username")
152155
attributes: JSONDict = {}
153156
attributes["cn"] = username
154-
attributes["uid"] = username
155-
attributes["oauth_username"] = username
156-
attributes["displayName"] = full_name
157-
attributes["mail"] = user_dict.get("email")
158157
attributes["description"] = ""
158+
attributes["displayName"] = full_name
159+
attributes["domain"] = user_dict["attributes"].get(
160+
self.domain_attribute,
161+
[None],
162+
)[0]
159163
attributes["gidNumber"] = user_dict["attributes"]["uid"][0]
160164
attributes["givenName"] = first_name or ""
161165
attributes["homeDirectory"] = f"/home/{username}" if username else None
166+
attributes["mail"] = user_dict.get("email")
162167
attributes["oauth_id"] = user_dict.get("id", None)
168+
attributes["oauth_username"] = username
163169
attributes["sn"] = last_name or ""
170+
attributes["uid"] = username
164171
attributes["uidNumber"] = user_dict["attributes"]["uid"][0]
165172
output.append(attributes)
166173
except KeyError:

run.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@
8282
type=str,
8383
help="Keycloak Realm.",
8484
)
85+
keycloak_group.add_argument(
86+
"--keycloak-domain-attribute",
87+
type=str,
88+
default="domain",
89+
help="The attribute in Keycloak that contains the users' domain.",
90+
)
8591
# Options for Redis cache
8692
redis_group = parser.add_argument_group("Redis")
8793
redis_group.add_argument(

0 commit comments

Comments
 (0)