mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Fix permissions for view-members and manage-members
Closes #38013 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
2b245059e3
commit
b200ab0792
@ -17,6 +17,7 @@
|
||||
|
||||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.authorization.AdminPermissionsSchema;
|
||||
import org.keycloak.authorization.jpa.entities.ResourceEntity;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
@ -1078,7 +1079,14 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
||||
List<Predicate> subs = new ArrayList<>();
|
||||
|
||||
Expression<String> groupId = from.get("groupId");
|
||||
subs.add(cb.like(from1.get("name"), cb.concat("group.resource.", groupId)));
|
||||
|
||||
RealmModel realm = session.getContext().getRealm();
|
||||
|
||||
if (AdminPermissionsSchema.SCHEMA.isAdminPermissionsEnabled(realm)) {
|
||||
subs.add(cb.like(from1.get("name"), groupId));
|
||||
} else {
|
||||
subs.add(cb.like(from1.get("name"), cb.concat("group.resource.", groupId)));
|
||||
}
|
||||
|
||||
subquery1.where(subs.toArray(Predicate[]::new));
|
||||
|
||||
|
||||
@ -225,8 +225,8 @@ public class AvailableRoleMappingResource extends RoleMappingResource {
|
||||
}
|
||||
|
||||
private Set<String> getRoleIdsWithPermissions(String roleResourceScope, String clientResourceScope) {
|
||||
Set<String> roleIds = this.auth.roles().getRolesWithPermission(roleResourceScope);
|
||||
Set<String> clientIds = this.auth.clients().getClientsWithPermission(clientResourceScope);
|
||||
Set<String> roleIds = this.auth.roles().getRoleIdsWithViewPermission(roleResourceScope);
|
||||
Set<String> clientIds = this.auth.clients().getClientIdsWithViewPermission(clientResourceScope);
|
||||
clientIds.stream().flatMap(cid -> realm.getClientById(cid).getRolesStream()).forEach(role -> roleIds.add(role.getId()));
|
||||
return roleIds;
|
||||
}
|
||||
|
||||
@ -191,5 +191,11 @@ public interface ClientPermissionEvaluator {
|
||||
|
||||
Map<String, Boolean> getAccess(ClientModel client);
|
||||
|
||||
Set<String> getClientsWithPermission(String scope);
|
||||
/**
|
||||
* Returns the IDs of the clients that the current user can view..
|
||||
*
|
||||
* @return Stream of IDs of clients with view permission.
|
||||
*/
|
||||
|
||||
Set<String> getClientIdsWithViewPermission(String scope);
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ 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.PolicyStore;
|
||||
import org.keycloak.authorization.store.ResourceStore;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.ClientModel;
|
||||
@ -63,6 +64,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM
|
||||
protected final AuthorizationProvider authz;
|
||||
protected final MgmtPermissions root;
|
||||
protected final ResourceStore resourceStore;
|
||||
protected final PolicyStore policyStore;
|
||||
|
||||
private static final String RESOURCE_NAME_PREFIX = "client.resource.";
|
||||
|
||||
@ -73,8 +75,10 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM
|
||||
this.root = root;
|
||||
if (authz != null) {
|
||||
resourceStore = authz.getStoreFactory().getResourceStore();
|
||||
policyStore = authz.getStoreFactory().getPolicyStore();
|
||||
} else {
|
||||
resourceStore = null;
|
||||
policyStore = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,7 +668,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getClientsWithPermission(String scope) {
|
||||
public Set<String> getClientIdsWithViewPermission(String scope) {
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.keycloak.services.resources.admin.permissions.AdminPermissionManagement.TOKEN_EXCHANGE;
|
||||
|
||||
@ -122,7 +124,7 @@ public class ClientPermissionsV2 extends ClientPermissions {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getClientsWithPermission(String scope) {
|
||||
public Set<String> getClientIdsWithViewPermission(String scope) {
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
@ -135,11 +137,13 @@ public class ClientPermissionsV2 extends ClientPermissions {
|
||||
|
||||
Set<String> granted = new HashSet<>();
|
||||
|
||||
resourceStore.findByType(server, AdminPermissionsSchema.CLIENTS_RESOURCE_TYPE, resource -> {
|
||||
if (hasGrantedPermission(resource, scope)) {
|
||||
granted.add(resource.getName());
|
||||
}
|
||||
});
|
||||
policyStore.findByResourceType(server, AdminPermissionsSchema.CLIENTS_RESOURCE_TYPE).stream()
|
||||
.flatMap((Function<Policy, Stream<Resource>>) policy -> policy.getResources().stream())
|
||||
.forEach(resource -> {
|
||||
if (hasGrantedPermission(resource, scope)) {
|
||||
granted.add(resource.getName());
|
||||
}
|
||||
});
|
||||
|
||||
return granted;
|
||||
}
|
||||
@ -224,9 +228,11 @@ public class ClientPermissionsV2 extends ClientPermissions {
|
||||
Collection<Permission> permissions = root.evaluatePermission(new ResourcePermission(resource, resource.getScopes(), server), server);
|
||||
List<String> expectedScopes = Arrays.asList(scope);
|
||||
for (Permission permission : permissions) {
|
||||
for (String s : permission.getScopes()) {
|
||||
if (expectedScopes.contains(s)) {
|
||||
return true;
|
||||
if (permission.getResourceId().equals(resource.getId())) {
|
||||
for (String s : permission.getScopes()) {
|
||||
if (expectedScopes.contains(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,25 +265,15 @@ public class ClientPermissionsV2 extends ClientPermissions {
|
||||
return false;
|
||||
}
|
||||
|
||||
private EvaluationContext getEvaluationContext(ClientModel authorizedClient, AccessToken token) {
|
||||
ClientModelIdentity identity = new ClientModelIdentity(session, authorizedClient, token);
|
||||
return new DefaultEvaluationContext(identity, session) {
|
||||
@Override
|
||||
public Map<String, Collection<String>> getBaseAttributes() {
|
||||
Map<String, Collection<String>> attributes = super.getBaseAttributes();
|
||||
attributes.put("kc.client.id", List.of(authorizedClient.getClientId()));
|
||||
return attributes;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean hasGrantedPermission(Resource resource, String scope) {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
Collection<Permission> permissions = root.evaluatePermission(new ResourcePermission(resource, resource.getScopes(), server), server);
|
||||
for (Permission permission : permissions) {
|
||||
for (String s : permission.getScopes()) {
|
||||
if (scope.equals(s)) {
|
||||
return true;
|
||||
if (permission.getResourceId().equals(resource.getId())) {
|
||||
for (String s : permission.getScopes()) {
|
||||
if (scope.equals(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,9 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.keycloak.authorization.AdminPermissionsSchema;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
@ -118,9 +121,11 @@ class GroupPermissionsV2 extends GroupPermissions {
|
||||
|
||||
Set<String> granted = new HashSet<>();
|
||||
|
||||
resourceStore.findByType(server, AdminPermissionsSchema.GROUPS_RESOURCE_TYPE, groupResource -> {
|
||||
if (hasPermission(groupResource.getId(), AdminPermissionsSchema.VIEW_MEMBERS, AdminPermissionsSchema.MANAGE_MEMBERS)) {
|
||||
granted.add(groupResource.getId());
|
||||
policyStore.findByResourceType(server, AdminPermissionsSchema.GROUPS_RESOURCE_TYPE).stream()
|
||||
.flatMap((Function<Policy, Stream<Resource>>) policy -> policy.getResources().stream())
|
||||
.forEach(gr -> {
|
||||
if (hasPermission(gr.getName(), AdminPermissionsSchema.VIEW_MEMBERS, AdminPermissionsSchema.MANAGE_MEMBERS)) {
|
||||
granted.add(gr.getName());
|
||||
}
|
||||
});
|
||||
|
||||
@ -154,9 +159,11 @@ class GroupPermissionsV2 extends GroupPermissions {
|
||||
List<String> expectedScopes = Arrays.asList(scopes);
|
||||
|
||||
for (Permission permission : permissions) {
|
||||
for (String scope : permission.getScopes()) {
|
||||
if (expectedScopes.contains(scope)) {
|
||||
return true;
|
||||
if (permission.getResourceId().equals(resource.getId())) {
|
||||
for (String scope : permission.getScopes()) {
|
||||
if (expectedScopes.contains(scope)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,5 +141,10 @@ public interface RolePermissionEvaluator {
|
||||
*/
|
||||
void requireView(RoleContainerModel container);
|
||||
|
||||
Set<String> getRolesWithPermission(String scope);
|
||||
/**
|
||||
* Returns the IDs of the roles that the current user can view..
|
||||
*
|
||||
* @return Stream of IDs of roles with view permission.
|
||||
*/
|
||||
Set<String> getRoleIdsWithViewPermission(String scope);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.ResourceStore;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.ClientModel;
|
||||
@ -55,6 +56,7 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
||||
protected final AuthorizationProvider authz;
|
||||
protected final MgmtPermissions root;
|
||||
protected final ResourceStore resourceStore;
|
||||
protected final PolicyStore policyStore;
|
||||
private static final String RESOURCE_NAME_PREFIX = "role.resource.";
|
||||
|
||||
public RolePermissions(KeycloakSession session, RealmModel realm, AuthorizationProvider authz, MgmtPermissions root) {
|
||||
@ -64,8 +66,10 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
||||
this.root = root;
|
||||
if (authz != null) {
|
||||
resourceStore = authz.getStoreFactory().getResourceStore();
|
||||
policyStore = authz.getStoreFactory().getPolicyStore();
|
||||
} else {
|
||||
resourceStore = null;
|
||||
policyStore = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -540,7 +544,7 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRolesWithPermission(String scope) {
|
||||
public Set<String> getRoleIdsWithViewPermission(String scope) {
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@ -35,6 +35,8 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RolePermissionsV2 extends RolePermissions {
|
||||
|
||||
@ -76,7 +78,7 @@ public class RolePermissionsV2 extends RolePermissions {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRolesWithPermission(String scope) {
|
||||
public Set<String> getRoleIdsWithViewPermission(String scope) {
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
@ -89,11 +91,13 @@ public class RolePermissionsV2 extends RolePermissions {
|
||||
|
||||
Set<String> granted = new HashSet<>();
|
||||
|
||||
resourceStore.findByType(server, AdminPermissionsSchema.ROLES_RESOURCE_TYPE, resource -> {
|
||||
if (hasGrantedPermission(server, resource, scope)) {
|
||||
granted.add(resource.getName());
|
||||
}
|
||||
});
|
||||
policyStore.findByResourceType(server, AdminPermissionsSchema.ROLES_RESOURCE_TYPE).stream()
|
||||
.flatMap((Function<Policy, Stream<Resource>>) policy -> policy.getResources().stream())
|
||||
.forEach(gr -> {
|
||||
if (hasGrantedPermission(server, gr, scope)) {
|
||||
granted.add(gr.getName());
|
||||
}
|
||||
});
|
||||
|
||||
return granted;
|
||||
}
|
||||
@ -121,11 +125,13 @@ public class RolePermissionsV2 extends RolePermissions {
|
||||
private boolean hasGrantedPermission(ResourceServer server, Resource resource, String scope) {
|
||||
Collection<Permission> permissions = root.evaluatePermission(new ResourcePermission(resource, resource.getScopes(), server), server);
|
||||
for (Permission permission : permissions) {
|
||||
for (String s : permission.getScopes()) {
|
||||
if (scope.equals(s)) {
|
||||
return true;
|
||||
if (permission.getResourceId().equals(resource.getId())) {
|
||||
for (String s : permission.getScopes()) {
|
||||
if (scope.equals(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user