<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>Hi,</div><div><br></div><div>While developing a complex production-grade KeyCloak extension I've faced the following problem. Let's say the extension provides several custom realm resources plus the relevant parts of admin console GUI. A user should be able to access this functionality only if he/she has corresponding roles: one role for read-only access, another one for full operation. The "domain-extension" example does solve the similar problem, but in a very simplistic way: the user is only checked against the built-in "admin" role. A real-world example would likely feature at least two custom roles, different from the built-in ones. Implementing this with the current KeyCloak version turned out to be a rather complex problem. To demonstrate it, I've created the following example. Throughout the example, two custom roles are used, "view-hello" and "manage-hello":</div><div><br></div><div><a href="https://github.com/dteleguin/custom-admin-roles">https://github.com/dteleguin/custom-admin-roles</a></div><div><br></div><div>The problem could be broken down into three parts:</div><div><br></div><div>1. <u>Creating roles.</u> Imagine the instructions: "After you have installed the extension, please go to Clients, select the master-realm client, add view-hello and manage-hello roles, then go to Roles, select admin, add the above roles to it. Repeat for each and every realm you've already created, but this time also with the realm-management client and realm-admin role. Don't forget to do the same for every new realm you add" - this is totally unacceptable if we are speaking of high quality software. In the example, this is fully automated (see HelloResourceProviderFactory::postInit). Adding roles to the newly created realms has become possible with the recent introduction of RealmPostCreateEvent.</div><div><br></div><div>2. <u>Client-side authorization.</u> The GUI elements in the admin console should be shown only to the users having corresponding roles. There is the global "access" AngularJS object, instantiated by GlobalCtrl and used everywhere in the admin console; it would be quite natural to use the same semantics for custom roles. In the example, AngularJS decorator mechanism is used to augment the "access" object with additional getters, reflecting custom role grants. Unfortunately, by some reason decorating GlobalCtrl directly doesn't work, so we have to decorate all the controllers (as "$controller") and then select GlobalCtrl. I'm not sure if it's a KeyCloak or AngularJS issue, since there's not much information on the net about using decorators with GlobalCtrl.</div><div><br></div><div>3. <u>Server-side authorization</u>, i.e. checking user roles in service methods of realm REST resources. This is particularly cumbersome, and imposes an ugly restriction on resource methods - all of them are required to have @Context HttpHeaders in the argument list. Otherwise it would be impossible to extract a JWS token and to deduce a realm to authorize against. The only workaround I see is to move all the service methods into a sub-resource, so that processing HttpHeaders and auth setup could be done once, while instantiating sub-resource (like this is done in o.k.services.resources.admin.AdminRoot). This is especially frustrating because any custom realm resource is a sub-resource by default, so there is no reason why it couldn't obtain a HttpHeaders object from its parent resource upon construction.</div><div><br></div><div>Conclusion: a simple and natural requirement for an extension, which is to have custom admin roles, turns into a lot of boilerplate code, most of which is present in either form in KeyCloak. Could this functionality be simply exposed to extensions? Ideally, this should be a one-liner for extension authors, since the only information needed is the name of the role(s). I could see it like this:</div><div><br></div><div>- an extension declares the roles. Considering possible introduction of @KeyloakProvider annotation, this could be an annotation parameter, or a separate annotation;</div><div>- KeyCloak takes responsibility for creating roles in both existing and newly added realms;</div><div>- GlobalCtrl augments the "access" object with the relevant getters;</div><div>- upon creation, realm resources receive an&nbsp;o.k.services.resources.admin.AdminAuth-like object, which could be further decorated, or used as is.</div><div><br></div><div>What do you think?</div><div>Dmitry</div><div><br></div></body></html>