8000 Backport to add support for service accounts when fetch roles is enabled by Romain7495 · Pull Request #30786 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.jboss.logging.Logger;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.attribute.Attributes.Entry;
import org.keycloak.authorization.identity.Identity;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.policy.evaluation.Evaluation;
Expand All @@ -31,6 +32,8 @@
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.representations.JsonWebToken;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;

/**
Expand Down Expand Up @@ -74,9 +77,8 @@ public void evaluate(Evaluation evaluation) {

private boolean hasRole(Identity identity, RoleModel role, RealmModel realm, AuthorizationProvider authorizationProvider, boolean fetchRoles) {
if (fetchRoles) {
KeycloakSession session = authorizationProvider.getKeycloakSession();
UserModel user = session.users().getUserById(realm, identity.getId());
return user.hasRole(role);
UserModel subject = getSubject(identity, realm, authorizationProvider);
return subject != null && subject.hasRole(role);
}
String roleName = role.getName();
if (role.isClientRole()) {
Expand All @@ -86,8 +88,26 @@ private boolean hasRole(Identity identity, RoleModel role, RealmModel realm, Aut
return identity.hasRealmRole(roleName);
}

private UserModel getSubject(Identity identity, RealmModel realm, AuthorizationProvider authorizationProvider) {
KeycloakSession session = authorizationProvider.getKeycloakSession();
UserProvider users = session.users();
UserModel user = users.getUserById(realm, identity.getId());

if (user == null) {
Entry sub = identity.getAttributes().getValue(JsonWebToken.SUBJECT);

if (sub == null || sub.isEmpty()) {
return null;
}

return users.getUserById(realm, sub.asString(0));
}

return user;
}

@Override
public void close() {

}
}
}
< 6E93 td class="blob-code blob-code-addition js-file-line"> ClientResource clientResource = clients.get(client.getId());
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,29 @@ public void testFetchRoles() {
assertNotNull(authzClient.authorization("kolo", "password").authorize(new AuthorizationRequest(ticket)));
}

@Test
public void testFetchRolesUsingServiceAccount() {
AuthzClient authzClient = getAuthzClient();
RealmResource realm = getRealm();
ClientsResource clients = realm.clients();
ClientRepresentation client = clients.findByClientId(authzClient.getConfiguration().getResource()).get(0);
ClientScopeRepresentation rolesScope = ApiUtil.findClientScopeByName(realm, OIDCLoginProtocolFactory.ROLES_SCOPE).toRepresentation();
clientResource.removeDefaultClientScope(rolesScope.getId());
UserRepresentation serviceAccountUser = clientResource.getServiceAccountUser();
RoleRepresentation roleB = realm.roles().get("Role B").toRepresentation();
realm.users().get(serviceAccountUser.getId()).roles().realmLevel().add(List.of(roleB));
RolePolicyRepresentation roleRep = clientResource.authorization().policies().role().findByName("Role B Policy");
roleRep.setFetchRoles(true);
clientResource.authorization().policies().role().findById(roleRep.getId()).update(roleRep);
getCleanup().addCleanup(() -> {
clientResource.addDefaultClientScope(rolesScope.getId());
roleRep.setFetchRoles(false);
clientResource.authorization().policies().role().findById(roleRep.getId()).update(roleRep);
});
assertNotNull(authzClient.authorization().authorize(new AuthorizationRequest()));
}

private void createRealmRolePolicy(String name, String... roles) {
RolePolicyRepresentation policy = new RolePolicyRepresentation();

Expand Down
0