Remove user credentials from admin event representation (#21561)

Closes #17470
This commit is contained in:
Pedro Igor 2023-07-11 03:26:29 -03:00 committed by GitHub
parent ebf878e1f0
commit 376d20c285
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 2 deletions

View file

@ -29,6 +29,8 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.StripSecretsUtils;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.ServicesLogger; import org.keycloak.services.ServicesLogger;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
@ -250,6 +252,11 @@ public class AdminEventBuilder {
if (value == null || value.equals("")) { if (value == null || value.equals("")) {
return this; return this;
} }
if (value instanceof UserRepresentation) {
StripSecretsUtils.strip((UserRepresentation) value);
}
try { try {
adminEvent.setRepresentation(JsonSerialization.writeValueAsString(value)); adminEvent.setRepresentation(JsonSerialization.writeValueAsString(value));
} catch (IOException e) { } catch (IOException e) {

View file

@ -167,7 +167,7 @@ public class UsersResource {
RepresentationToModel.createGroups(rep, realm, user); RepresentationToModel.createGroups(rep, realm, user);
RepresentationToModel.createCredentials(rep, session, realm, user, true); RepresentationToModel.createCredentials(rep, session, realm, user, true);
adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), user.getId()).representation(StripSecretsUtils.strip(rep)).success(); adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), user.getId()).representation(rep).success();
if (session.getTransactionManager().isActive()) { if (session.getTransactionManager().isActive()) {
session.getTransactionManager().commit(); session.getTransactionManager().commit();

View file

@ -209,7 +209,9 @@ public class UserTest extends AbstractAdminTest {
private void updateUser(UserResource user, UserRepresentation userRep) { private void updateUser(UserResource user, UserRepresentation userRep) {
user.update(userRep); user.update(userRep);
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(userRep.getId()), userRep, ResourceType.USER); List<CredentialRepresentation> credentials = userRep.getCredentials();
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.userResourcePath(userRep.getId()), StripSecretsUtils.strip(userRep), ResourceType.USER);
userRep.setCredentials(credentials);
} }
@Test @Test

View file

@ -20,6 +20,7 @@ package org.keycloak.testsuite.admin.event;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.OperationType;
import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.AuthDetailsRepresentation; import org.keycloak.representations.idm.AuthDetailsRepresentation;
@ -27,7 +28,10 @@ import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.util.JsonSerialization;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -41,6 +45,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNull;
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER; import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
/** /**
@ -65,6 +70,7 @@ public class AdminEventTest extends AbstractEventTest {
private String createUser(String username) { private String createUser(String username) {
UserRepresentation user = createUserRepresentation(username, username + "@foo.com", "foo", "bar", true); UserRepresentation user = createUserRepresentation(username, username + "@foo.com", "foo", "bar", true);
UserBuilder.edit(user).password("password");
String userId = ApiUtil.createUserWithAdminClient(testRealmResource(), user); String userId = ApiUtil.createUserWithAdminClient(testRealmResource(), user);
getCleanup().addUserId(userId); getCleanup().addUserId(userId);
return userId; return userId;
@ -259,4 +265,23 @@ public class AdminEventTest extends AbstractEventTest {
assertThat(deleteEvent.getResourceType(), is(equalTo("REALM"))); assertThat(deleteEvent.getResourceType(), is(equalTo("REALM")));
assertThat(deleteEvent.getResourcePath(), is(equalTo("test-realm"))); assertThat(deleteEvent.getResourcePath(), is(equalTo("test-realm")));
} }
@Test
public void testStripOutUserSensitiveData() throws IOException {
configRep.setAdminEventsDetailsEnabled(Boolean.TRUE);
configRep.setAdminEventsEnabled(Boolean.TRUE);
saveConfig();
UserResource user = testRealmResource().users().get(createUser("sensitive"));
List<AdminEventRepresentation> events = events();
UserRepresentation eventUserRep = JsonSerialization.readValue(events.get(0).getRepresentation(), UserRepresentation.class);
assertNull(eventUserRep.getCredentials());
UserRepresentation userRep = user.toRepresentation();
UserBuilder.edit(userRep).password("password");
user.update(userRep);
events = events();
eventUserRep = JsonSerialization.readValue(events.get(0).getRepresentation(), UserRepresentation.class);
assertNull(eventUserRep.getCredentials());
}
} }