Update realm: Remove browser security header attributes from the list of attributes to remove if missing (#32922)

Closes #32921

Signed-off-by: Johannes Knutsen <johannes@knutsen.me>
Co-authored-by: Marek Posolda <mposolda@gmail.com>
This commit is contained in:
Johannes Knutsen 2025-01-23 10:37:56 +01:00 committed by GitHub
parent 3356b9bfea
commit c889c6a79b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 2 deletions

View File

@ -128,6 +128,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import static org.keycloak.models.utils.DefaultRequiredActions.getDefaultRequiredActionCaseInsensitively;
import static org.keycloak.models.utils.ModelToRepresentation.stripRealmAttributesIncludedAsFields;
import static org.keycloak.models.utils.RepresentationToModel.createCredentials;
import static org.keycloak.models.utils.RepresentationToModel.createFederatedIdentities;
import static org.keycloak.models.utils.RepresentationToModel.createGroups;
@ -738,9 +739,8 @@ public class DefaultExportImportManager implements ExportImportManager {
// Import attributes first, so the stuff saved directly on representation (displayName, bruteForce etc) has bigger priority
if (rep.getAttributes() != null) {
Set<String> attrsToRemove = new HashSet<>(realm.getAttributes().keySet());
Set<String> attrsToRemove = stripRealmAttributesIncludedAsFields(realm.getAttributes()).keySet();
attrsToRemove.removeAll(rep.getAttributes().keySet());
attrsToRemove.removeAll(ModelToRepresentation.REALM_EXCLUDED_ATTRIBUTES);
for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
realm.setAttribute(entry.getKey(), entry.getValue());

View File

@ -38,6 +38,7 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.events.log.JBossLoggingEventListenerProviderFactory;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.models.CibaConfig;
import org.keycloak.models.Constants;
import org.keycloak.models.OAuth2DeviceConfig;
@ -105,6 +106,7 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
@ -332,6 +334,13 @@ public class RealmTest extends AbstractAdminTest {
public void testFieldNotErased() {
Long dummyLong = Long.valueOf(999);
Integer dummyInt = Integer.valueOf(999);
Map<String, String> browserSecurityHeaders = new HashMap<>(Arrays.stream(
BrowserSecurityHeaders.values()).collect(Collectors.toMap(
BrowserSecurityHeaders::getKey,
headerValue -> headerValue.getDefaultValue().isBlank()
? "non-null-to-test"
: headerValue.getDefaultValue()
)));
RealmRepresentation rep = new RealmRepresentation();
rep.setRealm("attributes");
@ -350,6 +359,7 @@ public class RealmTest extends AbstractAdminTest {
rep.setActionTokenGeneratedByUserLifespan(dummyInt);
rep.setOfflineSessionMaxLifespanEnabled(true);
rep.setOfflineSessionMaxLifespan(dummyInt);
rep.setBrowserSecurityHeaders(browserSecurityHeaders);
rep.setWebAuthnPolicyRpEntityName("RP_ENTITY_NAME");
rep.setWebAuthnPolicySignatureAlgorithms(Collections.singletonList("RS256"));
@ -418,6 +428,8 @@ public class RealmTest extends AbstractAdminTest {
assertEquals(dummyInt, rep.getWebAuthnPolicyPasswordlessCreateTimeout());
assertTrue(rep.isWebAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister());
assertEquals(Collections.singletonList("00000000-0000-0000-0000-000000000000"), rep.getWebAuthnPolicyPasswordlessAcceptableAaguids());
assertEquals(browserSecurityHeaders, rep.getBrowserSecurityHeaders());
}
@Test