[#10608] Password blacklists folder
This commit is contained in:
parent
8454dc5a5d
commit
48565832d4
5 changed files with 94 additions and 4 deletions
|
@ -102,6 +102,7 @@ import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
|||
import org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory;
|
||||
import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProviderFactory;
|
||||
import org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider;
|
||||
import org.keycloak.policy.BlacklistPasswordPolicyProviderFactory;
|
||||
import org.keycloak.protocol.ProtocolMapperSpi;
|
||||
import org.keycloak.protocol.oidc.mappers.DeployedScriptOIDCProtocolMapper;
|
||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||
|
@ -153,7 +154,8 @@ class KeycloakProcessor {
|
|||
DefaultHostnameProviderFactory.class,
|
||||
FixedHostnameProviderFactory.class,
|
||||
RequestHostnameProviderFactory.class,
|
||||
FilesPlainTextVaultProviderFactory.class);
|
||||
FilesPlainTextVaultProviderFactory.class,
|
||||
BlacklistPasswordPolicyProviderFactory.class);
|
||||
|
||||
static {
|
||||
DEPLOYEABLE_SCRIPT_PROVIDERS.put(AUTHENTICATORS, KeycloakProcessor::registerScriptAuthenticator);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2022 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.quarkus.runtime.policy;
|
||||
|
||||
import org.keycloak.policy.BlacklistPasswordPolicyProviderFactory;
|
||||
import org.keycloak.quarkus.runtime.Environment;
|
||||
|
||||
/**
|
||||
* <p>Quarkus implementation of the BlacklistPasswordPolicyProviderFactory. The
|
||||
* default path for the list files is calculated using the quarkus environment
|
||||
* class, in order to obtain the correct <em>data</em> directory.
|
||||
*
|
||||
* @author rmartinc
|
||||
*/
|
||||
public class QuarkusBlacklistPasswordPolicyProviderFactory extends BlacklistPasswordPolicyProviderFactory {
|
||||
|
||||
@Override
|
||||
public String getDefaultBlacklistsBasePath() {
|
||||
return Environment.getDataDir() + "/" + PASSWORD_BLACKLISTS_FOLDER;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright 2022 Red Hat, Inc. and/or its affiliates
|
||||
# and other contributors as indicated by the @author tags.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
org.keycloak.quarkus.runtime.policy.QuarkusBlacklistPasswordPolicyProviderFactory
|
|
@ -33,6 +33,7 @@ import java.nio.file.Paths;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Creates {@link BlacklistPasswordPolicyProvider} instances.
|
||||
|
@ -87,7 +88,7 @@ public class BlacklistPasswordPolicyProviderFactory implements PasswordPolicyPro
|
|||
if (this.blacklistsBasePath == null) {
|
||||
synchronized (this) {
|
||||
if (this.blacklistsBasePath == null) {
|
||||
this.blacklistsBasePath = FileBasedPasswordBlacklist.detectBlacklistsBasePath(config);
|
||||
this.blacklistsBasePath = FileBasedPasswordBlacklist.detectBlacklistsBasePath(config, this::getDefaultBlacklistsBasePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +133,17 @@ public class BlacklistPasswordPolicyProviderFactory implements PasswordPolicyPro
|
|||
return ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to obtain the default location for the list folder. The method
|
||||
* will return the <em>data</em> directory of the installation concatenated
|
||||
* with <em>/password-blacklists/</em>.
|
||||
*
|
||||
* @return The default path used by the provider to lookup the lists
|
||||
* when no other configuration is in place.
|
||||
*/
|
||||
public String getDefaultBlacklistsBasePath() {
|
||||
return System.getProperty(JBOSS_SERVER_DATA_DIR) + "/" + PASSWORD_BLACKLISTS_FOLDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and potentially registers a {@link PasswordBlacklist} for the given {@code blacklistName}.
|
||||
|
@ -302,10 +314,11 @@ public class BlacklistPasswordPolicyProviderFactory implements PasswordPolicyPro
|
|||
* running wildfly instance.
|
||||
*
|
||||
* @param config
|
||||
* @param defaultPathSupplier default path to use if not specified in a system prop or configuration
|
||||
* @return the detected blacklist path
|
||||
* @throws IllegalStateException if no blacklist folder could be detected
|
||||
*/
|
||||
private static Path detectBlacklistsBasePath(Config.Scope config) {
|
||||
private static Path detectBlacklistsBasePath(Config.Scope config, Supplier<String> defaultPathSupplier) {
|
||||
|
||||
String pathFromSysProperty = System.getProperty(SYSTEM_PROPERTY);
|
||||
if (pathFromSysProperty != null) {
|
||||
|
@ -317,7 +330,11 @@ public class BlacklistPasswordPolicyProviderFactory implements PasswordPolicyPro
|
|||
return ensureExists(Paths.get(pathFromSpiConfig));
|
||||
}
|
||||
|
||||
String pathFromJbossDataPath = System.getProperty(JBOSS_SERVER_DATA_DIR) + "/" + PASSWORD_BLACKLISTS_FOLDER;
|
||||
String pathFromJbossDataPath = defaultPathSupplier.get();
|
||||
if (pathFromJbossDataPath == null) {
|
||||
throw new IllegalStateException("Default path for the blacklist folder was null");
|
||||
}
|
||||
|
||||
if (!Files.exists(Paths.get(pathFromJbossDataPath))) {
|
||||
if (!Paths.get(pathFromJbossDataPath).toFile().mkdirs()) {
|
||||
LOG.errorf("Could not create folder for password blacklists: %s", pathFromJbossDataPath);
|
||||
|
|
|
@ -23,8 +23,11 @@ import org.keycloak.models.ModelException;
|
|||
import org.keycloak.models.PasswordPolicy;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.policy.BlacklistPasswordPolicyProvider;
|
||||
import org.keycloak.policy.BlacklistPasswordPolicyProviderFactory;
|
||||
import org.keycloak.policy.MaximumLengthPasswordPolicyProviderFactory;
|
||||
import org.keycloak.policy.PasswordPolicyManagerProvider;
|
||||
import org.keycloak.policy.PasswordPolicyProvider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||
|
@ -34,6 +37,9 @@ import org.keycloak.testsuite.util.RealmBuilder;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
@ -184,6 +190,17 @@ public class PasswordPolicyTest extends AbstractKeycloakTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlacklistPasswordPolicyDefaultPath() throws Exception {
|
||||
testingClient.server("passwordPolicy").run(session -> {
|
||||
ProviderFactory<PasswordPolicyProvider> passPolicyFact = session.getKeycloakSessionFactory().getProviderFactory(
|
||||
PasswordPolicyProvider.class, BlacklistPasswordPolicyProviderFactory.ID);
|
||||
assertThat(passPolicyFact, instanceOf(BlacklistPasswordPolicyProviderFactory.class));
|
||||
assertThat(((BlacklistPasswordPolicyProviderFactory)passPolicyFact).getDefaultBlacklistsBasePath(),
|
||||
endsWith("/data/password-blacklists/"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotUsername() {
|
||||
testingClient.server("passwordPolicy").run(session -> {
|
||||
|
|
Loading…
Reference in a new issue