Reduce number of calls to the storage for clients and realms

Closes #15038
This commit is contained in:
Alexander Schwartz 2022-10-19 22:13:42 +02:00 committed by Hynek Mlnařík
parent d12aef0b43
commit 440077de42
6 changed files with 51 additions and 16 deletions

View file

@ -66,4 +66,20 @@ public interface Identity {
default boolean hasClientRole(String clientId, String roleName) {
return getAttributes().containsValue("kc.client." + clientId + ".roles", roleName);
}
/**
* Indicates if this identity is granted with a client role of one of the given <code>roleNames</code>.
*
* @param clientId the client id
* @param roleNames list
*
* @return true if the identity has any of the given roles. Otherwise, it returns false.
*/
default boolean hasOneClientRole(String clientId, String... roleNames) {
for (String adminRole : roleNames) {
if (hasClientRole(clientId, adminRole)) return true;
}
return false;
}
}

View file

@ -68,4 +68,17 @@ public class ClientModelIdentity implements Identity {
if (role == null) return false;
return serviceAccount.hasRole(role);
}
@Override
public boolean hasOneClientRole(String clientId, String... roleNames) {
if (serviceAccount == null) return false;
ClientModel client = realm.getClientByClientId(clientId);
for (String roleName : roleNames) {
RoleModel role = client.getRole(roleName);
if (role == null) continue;
if (serviceAccount.hasRole(role)) return true;
}
return false;
}
}

View file

@ -56,6 +56,17 @@ public class UserModelIdentity implements Identity {
return user.hasRole(role);
}
@Override
public boolean hasOneClientRole(String clientId, String... roleNames) {
ClientModel client = realm.getClientByClientId(clientId);
for (String roleName : roleNames) {
RoleModel role = client.getRole(roleName);
if (role == null) continue;
if (user.hasRole(role)) return true;
}
return false;
}
@Override
public boolean hasClientRole(String clientId, String roleName) {
ClientModel client = realm.getClientByClientId(clientId);

View file

@ -85,6 +85,10 @@ public class RealmManager {
return getRealmByName(Config.getAdminRealm());
}
public static boolean isAdministrationRealm(RealmModel realm) {
return realm.getName().equals(Config.getAdminRealm());
}
public RealmModel getRealm(String id) {
return model.getRealm(id);
}
@ -773,4 +777,5 @@ public class RealmManager {
}
}
}
}

View file

@ -174,7 +174,7 @@ public class RealmsAdminResource {
RealmModel realm = realmManager.getRealmByName(name);
if (realm == null) throw new NotFoundException("Realm not found.");
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())
if (!RealmManager.isAdministrationRealm(auth.getRealm())
&& !auth.getRealm().equals(realm)) {
throw new ForbiddenException();
}

View file

@ -16,7 +16,6 @@
*/
package org.keycloak.services.resources.admin.permissions;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.AuthorizationProviderFactory;
@ -29,7 +28,6 @@ import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.permission.ResourcePermission;
import org.keycloak.authorization.policy.evaluation.EvaluationContext;
import org.keycloak.authorization.store.ResourceServerStore;
import org.keycloak.common.Profile;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientModel;
@ -52,8 +50,6 @@ import java.util.List;
* @version $Revision: 1 $
*/
class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManagement, RealmsPermissionEvaluator {
private static final Logger logger = Logger.getLogger(MgmtPermissions.class);
protected RealmModel realm;
protected KeycloakSession session;
protected AuthorizationProvider authz;
@ -86,7 +82,7 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
this.admin = auth.getUser();
this.adminsRealm = auth.getRealm();
if (!auth.getRealm().equals(realm)
&& !auth.getRealm().equals(new RealmManager(session).getKeycloakAdminstrationRealm())) {
&& !RealmManager.isAdministrationRealm(auth.getRealm())) {
throw new ForbiddenException();
}
initIdentity(session, auth);
@ -158,7 +154,6 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
}
public boolean hasOneAdminRole(String... adminRoles) {
String clientId;
RealmModel realm = this.realm;
return hasOneAdminRole(realm, adminRoles);
}
@ -166,17 +161,14 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
public boolean hasOneAdminRole(RealmModel realm, String... adminRoles) {
String clientId;
RealmManager realmManager = new RealmManager(session);
if (adminsRealm.equals(realmManager.getKeycloakAdminstrationRealm())) {
if (RealmManager.isAdministrationRealm(adminsRealm)) {
clientId = realm.getMasterAdminClient().getClientId();
} else if (adminsRealm.equals(realm)) {
clientId = realm.getClientByClientId(realmManager.getRealmAdminClientId(realm)).getClientId();
} else {
return false;
}
for (String adminRole : adminRoles) {
if (identity.hasClientRole(clientId, adminRole)) return true;
}
return false;
return identity.hasOneClientRole(clientId, adminRoles);
}
@ -372,8 +364,7 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
@Override
public boolean isAdmin() {
RealmManager realmManager = new RealmManager(session);
if (adminsRealm.equals(realmManager.getKeycloakAdminstrationRealm())) {
if (RealmManager.isAdministrationRealm(adminsRealm)) {
if (identity.hasRealmRole(AdminRoles.ADMIN) || identity.hasRealmRole(AdminRoles.CREATE_REALM)) {
return true;
}
@ -385,8 +376,7 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
@Override
public boolean canCreateRealm() {
RealmManager realmManager = new RealmManager(session);
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
if (!RealmManager.isAdministrationRealm(auth.getRealm())) {
return false;
}
return identity.hasRealmRole(AdminRoles.CREATE_REALM);