Skip to content

Commit 8aca3c0

Browse files
committed
feat: initial commit
0 parents  commit 8aca3c0

40 files changed

+2375
-0
lines changed

.gitattributes

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
* text eol=lf
2+
3+
.gitignore text
4+
.htaccess text
5+
6+
*.php text
7+
*.css text
8+
*.js text
9+
*.htm text
10+
*.html text
11+
*.xml text
12+
*.txt text
13+
*.ini text
14+
*.inc text
15+
16+
*.png binary
17+
*.jpg binary
18+
*.jpeg binary
19+
*.gif binary
20+
*.ico binary
21+
*.mov binary
22+
*.mp4 binary
23+
*.mp3 binary
24+
*.gz binary
25+
*.zip binary
26+
*.7z binary
27+
*.webp binary
28+
29+
*.pdf binary
30+
*.md text diff=markdown
31+
32+
*.ttf binary
33+
*.woff binary

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# IDEA Code Style
2+
.idea/*
3+
!.idea/copyright/
4+
!.idea/copyright/*
5+
!.idea/codeStyles/
6+
!.idea/codeStyles/*
7+
8+
# Env files
9+
.env
10+
11+
.maven/*
12+
target/*
13+
!target/hawk-auth-server-extension.jar
14+
!target/hawk-auth-server-extension-sources.jar

README.md

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
# HAWK - Auth Server - Keycloak Extension
2+
3+
This keycloak extension is a companion for the [HAWK Auth client](https://github.com/HAWK-Digital-Environments/hawk-auth-client),
4+
which aims to create a simple way of working with keycloak as an authentication and authorization backend for microservices.
5+
While keycloak is a really powerful tool, the REST api and the fine grained access control on it's own resources
6+
can be a bit cumbersome to work with. This extension provides multiple new endpoints to make it easier
7+
and more efficient. It also provides a (currently rather simple) logic to invalidate client caches when
8+
data of the realm changes.
9+
10+
## Installation
11+
12+
To install the extension you may copy the `target/cache-buster-extension.jar` and place it in the `standalone/deployments` folder of your keycloak server.
13+
14+
### Configure access
15+
16+
After the installation of the extension you need to restart the keycloak server.
17+
With the restart the extension will create a bunch of new roles you need to assign to your clients.
18+
To make your life easier, we have created a new role `hawk-client` that combines all the roles needed to access the new endpoints.
19+
20+
Create a new client, or use an existing one, and assign the `hawk-client` role to the "Service account roles" of the client.
21+
This will give your client read-only access to the new endpoints.
22+
23+
If you want to do management operations (like updating the profile structure or managing resource permissions),
24+
you need to assign the corresponding roles to your client: `hawk-manage-profile-structure`, `hawk-manage-profile-data`, `hawk-manage-resource-permissions`.
25+
26+
## What's in the box?
27+
28+
### New routes
29+
#### GET Users
30+
`/realms/{realm}/hawk/users`
31+
32+
This route is more or less a drop-in replacement for the built-in keycloak user search endpoint (`/admin/realms/{realm}/users`),
33+
however it has some notable differences:
34+
35+
* The response data mirrors the data structure of the `/realms/{realm}/protocol/openid-connect/token/introspect` endpoint (without the token related fields "exp", "iat", etc).
36+
* You can request multiple users at once by providing a list of user ids in the query parameter `ids`. The response will be a list of users in the same order as the ids.
37+
* You can request ONLY the user ids by providing the query parameter `idsOnly=true`. The response will be a list of user ids.
38+
* You can request ONLY users that are considered "online" by providing the query parameter `onlineOnly=true`. The response will be a list of users that have a session with activity in the last 10 minutes.
39+
40+
Supported query parameters:
41+
* **search** - A String contained in username, first or last name, or email. Default search behavior is prefix-based (e.g., foo or foo*). Use *foo* for infix search and "foo" for exact search.
42+
* **attributes** - A query to search for custom attributes, in the format `key1:value2 key2:value2`
43+
* **ids** - A list of user ids to search for, in the format `id1,id2`. If provided, the search and attributes parameters CAN NOT be used.
44+
* **onlineOnly** - If true, only users with an active session (in any client of the realm) will be returned
45+
* **idsOnly** - If true, only the user ids will be returned
46+
* **first** - The first result to return (0-based)
47+
* **max** - The maximum number of results to return (default 100)
48+
49+
Required roles: `query-users` and `view-users` (the latter is required if "idsOnly" is not set to true)
50+
51+
#### GET User Count
52+
`/realms/{realm}/hawk/users/count`
53+
54+
This route is a simple count of the users in the realm. Works similar to `/admin/realms/{realm}/users/count`, but allows specific filtering for online users.
55+
56+
Supported query parameters:
57+
* **onlineOnly** - If true, only users with an active session (in any client of the realm) will be counted
58+
* **search** - A String contained in username, first or last name, or email. Default search behavior is prefix-based (e.g., foo or foo*). Use *foo* for infix search and "foo" for exact search.
59+
* **attributes** - A query to search for custom attributes, in the format `key1:value2 key2:value2`
60+
61+
Required roles: `query-users`
62+
63+
#### GET Client Resources
64+
`/realms/{realm}/hawk/resources`
65+
66+
Returns a list of authorization resource definitions for the client requesting the endpoint. This is a custom implementation of: `/realms/{realm}/authz/protection/resource_set`
67+
that can be used to filter resources based on their ids.
68+
69+
Supported query parameters:
70+
* **ids** - A list of resource ids to search for, in the format `id1,id2`. If provided, the search and attributes parameters CAN NOT be used.
71+
* **first** - The first result to return (0-based)
72+
* **max** - The maximum number of results to return (default 100)
73+
74+
Required roles: `hawk-view-resource-permissions` or `hawk-manage-resource-permissions` or both.
75+
76+
#### GET Client Resource Users
77+
`/realms/{realm}/hawk/resources/{resourceId}/users`
78+
79+
Returns a list of users that have been granted permissions (does not include the owner) for the specified resource.
80+
The response contains both the user id and the allowed scopes.
81+
82+
Required roles: `hawk-view-resource-permissions` or `hawk-manage-resource-permissions` or both.
83+
84+
#### PUT Allow Resource to User
85+
`/realms/{realm}/hawk/resources/{resourceId}/users/{userId}`
86+
87+
Grants the user the provided scopes for the specified resource.
88+
If the list of scopes is empty, the user will be granted all scopes for the resource (if the user does not have any scope yet),
89+
or remove all scopes from the user (if the user has any scope). This basically an endpoint that allows the "share"
90+
functionality provided by the "account" frontend but with custom roles.
91+
92+
Required roles: `hawk-manage-resource-permissions`
93+
94+
Expected body:
95+
```json
96+
{
97+
"scopes": ["scope1", "scope2"]
98+
}
99+
```
100+
101+
#### GET Resources shared with User
102+
`/realms/{realm}/hawk/resources/shared-with/{userId}`
103+
104+
Returns a list of resource ids that have been shared with the specified user. (Shared means, the resources
105+
have been specifically allowed to the user by a UMA ticket or using the "Allow Resource to User" endpoint).
106+
107+
Supported query parameters:
108+
* **first** - The first result to return (0-based)
109+
* **max** - The maximum number of results to return (default 100)
110+
111+
Required roles: `hawk-view-resource-permissions` or `hawk-manage-resource-permissions` or both.
112+
113+
#### GET Resources shared by User
114+
`/realms/{realm}/hawk/resources/shared-by/{userId}`
115+
116+
Returns a list of resource ids that have been shared by the specified user. (Shared means, the resources
117+
have been specifically allowed to the user by a UMA ticket or using the "Allow Resource to User" endpoint).
118+
119+
Supported query parameters:
120+
* **first** - The first result to return (0-based)
121+
* **max** - The maximum number of results to return (default 100)
122+
123+
Required roles: `hawk-view-resource-permissions` or `hawk-manage-resource-permissions` or both.
124+
125+
#### GET Roles
126+
`/realms/{realm}/hawk/roles`
127+
128+
This endpoint has the same output as the `/admin/realms/{realm}/roles` endpoint, but has some differences:
129+
130+
* Built-In roles (e.g., `offline_access`, `uma_authorization`) are not included in the response.
131+
* The response contains `Realm roles` and `Client roles` in the same list.
132+
133+
Supported query parameters:
134+
* **first** - The first result to return (0-based)
135+
* **max** - The maximum number of results to return (default 100)
136+
137+
Required roles: `hawk-view-roles`
138+
139+
#### GET Role Members
140+
`/realms/{realm}/hawk/roles/{roleName}/members`
141+
142+
Returns a list of user ids that have the specified role.
143+
The response is a list of user ids.
144+
145+
Supported query parameters:
146+
* **first** - The first result to return (0-based)
147+
* **max** - The maximum number of results to return (default 100)
148+
149+
Required roles: `hawk-view-roles` AND `view-users`
150+
151+
#### GET Profile structure
152+
`/realms/{realm}/hawk/profile/structure`
153+
154+
Returns the structure of the user profile in the realm. This is a custom endpoint that
155+
allows clients to get the profile structure without having read access to the whole realm.
156+
157+
The response is a [UPConfig](https://www.keycloak.org/docs-api/latest/rest-api/index.html#UPConfig) representation.
158+
159+
Required roles: `hawk-view-profile-structure`
160+
161+
#### PUT Profile structure
162+
`/realms/{realm}/hawk/profile/structure`
163+
164+
Allows your client to update the profile structure of the realm. This is a custom endpoint that
165+
allows clients to update the profile structure without having write access to the whole realm.
166+
167+
The body of the request should be a [UPConfig](https://www.keycloak.org/docs-api/latest/rest-api/index.html#UPConfig) representation.
168+
169+
Required roles: `hawk-manage-profile-structure`
170+
171+
#### POST User Profile Data
172+
`/realms/{realm}/hawk/profile/{userId}`
173+
174+
Allows your client to update the profile data of a user. This is a custom endpoint that
175+
allows clients to update the profile without having global write access to the user or
176+
using impersonation to update the user.
177+
178+
The body of the request should be a [UserRepresentation](https://www.keycloak.org/docs-api/latest/rest-api/index.html#UserRepresentation)
179+
180+
Required roles: `hawk-manage-profile-data`
181+
182+
#### GET Cache Buster
183+
`/realms/{realm}/hawk/cache-buster`
184+
185+
This endpoint returns a single timestamp value. The timestamp is updated whenever a write operation
186+
is performed on the realm. This can be used by clients to invalidate their cache of realm data.
187+
188+
**Beware of dragons:** The current approach is not the most efficient one, as it invalidates the cache of the whole realm
189+
on each write event. This is a simple approach that works for small realms, but it may not be the best
190+
solution for large realms. We are open to suggestions and PRs to improve this extension.
191+
192+
Required roles: `hawk-view-cache-buster`
193+
194+
#### GET Connection Info
195+
`/realms/{realm}/hawk/connection-info`
196+
197+
This endpoint returns information about the connection to the keycloak server required
198+
for a smooth client experience.
199+
200+
The response contains the following fields:
201+
* keycloakVersion - The version of the keycloak server (Used for compatibility checks on the client side)
202+
* extensionVersion - The version of the hawk keycloak extension
203+
* clientId - The client id of the client that requested the endpoint
204+
* clientUuid - The uuid of the client that requested the endpoint
205+
206+
Required roles `hawk-client`
207+
208+
### New roles
209+
210+
The extension introduces new roles that can be used to control access to the new endpoints.
211+
All roles are created on the `realm-management` client of all realms (except the master realm).
212+
The roles are automatically installed on startup of the extension.
213+
214+
- `hawk-view-cache-buster` - Allows the client to request the cache buster timestamp
215+
- `hawk-view-roles` - Allows the client to request the roles of the realm and clients
216+
- `hawk-manage-profile-structure` - Allows the client to update the profile structure of the realm
217+
- `hawk-view-profile-structure` - Allows the client to request the profile structure of the realm
218+
- `hawk-manage-profile-data` - Allows the client to update the profile data of a user
219+
- `hawk-view-resource-permissions` - Allows the client to request the resources of itself and the permissions of the resources
220+
- `hawk-manage-resource-permissions` - Allows the client to manage the permissions of the resources
221+
222+
There is also a new convience role `hawk-client` that combines the following
223+
roles to create a read-only client:
224+
225+
- `hawk-client`
226+
- (account) `view-groups`
227+
- (account) `view-profile`
228+
- (realm-management) `view-users`
229+
- (realm-management) `query-users`
230+
- (realm-management) `view-authorization`
231+
- (realm-management) `query-groups`
232+
- (realm-management) `hawk-view-roles`
233+
- (realm-management) `hawk-view-cache-buster`
234+
- (realm-management) `hawk-view-profile-structure`
235+
236+
## Building
237+
238+
To build the extension you may run the following command:
239+
```bash
240+
./build.sh
241+
```
242+
243+
It will generate the `target/cache-buster-extension.jar` file.
244+
245+
## Postcardware
246+
You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.
247+
248+
HAWK Fakultät Gestaltung
249+
Interaction Design Lab
250+
Renatastraße 11
251+
31134 Hildesheim
252+
253+
Thank you :D

build.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
SCRIPT_FILE=$(realpath ${BASH_SOURCE%/*})
4+
cd $SCRIPT_FILE
5+
docker run --rm \
6+
-v "$PWD":/usr/src/mymaven \
7+
-v "$PWD/.maven":/root/.m2 \
8+
-w /usr/src/mymaven \
9+
maven:3 mvn clean install

0 commit comments

Comments
 (0)