[keycloak-user] UserStorageProvider for an external database

Steffen Kreutz brushmate at gmail.com
Mon Dec 10 03:40:39 EST 2018


Hi,

that's surely possible, but I absolutely don't want to have the
configuration in my code (especially not the password). Thus I somehow have
to inject the configuration 'from the outside'.

Best,

Steffen

Am So., 9. Dez. 2018 um 13:27 Uhr schrieb Bart Lievens <
bart.lievens at unifiedpost.com>:

> Hello,
>
> I solved the problem not by adding a datasource to WildFly but by adding
> the configuration parameters to the UserStorageProviderFactory
> and creating the EntityManager inside the UserStorageProviderFactory and
> then passing it on when creating a UserStorageProvider.
>
> My UserStorageProviderFactory looks something like (with 4.6.0.Final &
> 4.7.0.Final) :
> public class ExternalUserStorageProviderFactory implements
> UserStorageProviderFactory<ExternalUserStorageProvider> {
>     private static final transient Logger logger =
> LoggerFactory.getLogger(ExternalUserStorageProviderFactory.class);
>     private static final String CONF_NAME_JDBC_URL = "jdbcUrl";
>     private static final String CONF_NAME_JDBC_USER = "user";
>     private static final String CONF_NAME_JDBC_PASSWORD = "password";
>
>     protected static final List<ProviderConfigProperty> configMetadata;
>     private Map<String, EntityManager> entityManagers = new HashMap<>();
>
>     static {
>         ProviderConfigurationBuilder builder =
> ProviderConfigurationBuilder.create();
>
> builder.property().name(CONF_NAME_JDBC_URL).type(ProviderConfigProperty.STRING_TYPE).label("Jdbc
> Url")
>                .defaultValue("jdbc:postgresql://host:port/database")
>                .helpText("Postgres JDBC Connection URL to external user
> db")
>                .add();
>
> builder.property().name(CONF_NAME_JDBC_USER).type(ProviderConfigProperty.STRING_TYPE).label("Jdbc
> User")
>                .helpText("JDBC Connection User")
>                .add();
>
> builder.property().name(CONF_NAME_JDBC_PASSWORD).type(ProviderConfigProperty.PASSWORD).label("Jdbc
> Password")
>                .helpText("JDBC Connection Password")
>                .add();
>         configMetadata = builder.build();
>     }
>
>     @Override
>     public List<ProviderConfigProperty> getConfigProperties() {
>         return configMetadata;
>     }
>
>     @Override
>     public void validateConfiguration(KeycloakSession session, RealmModel
> realm, ComponentModel componentModel) throws ComponentValidationException {
>         if (componentModel.getConfig().getFirst(CONF_NAME_JDBC_URL) == null
>             || componentModel.getConfig().getFirst(CONF_NAME_JDBC_USER) ==
> null
>             ||
> componentModel.getConfig().getFirst(CONF_NAME_JDBC_PASSWORD) == null) {
>             throw new ComponentValidationException("The jdbc Url, User and
> Password are requirec");
>         }
>         try {
>             createEntityManager(componentModel);
>         } catch (Exception e) {
>             logger.warn("Invalid configuration {}", e.getCause() == null ?
> e.getMessage() : e.getCause().getMessage());
>             throw new ComponentValidationException("Could not setup jdbc
> connection : " + (e.getCause() == null ? e.getMessage() :
> e.getCause().getMessage()));
>         }
>     }
>
>     @Override
>     public ExternalUserStorageProvider create(KeycloakSession session,
> ComponentModel model) {
>         try {
>             if (entityManagers.get(model.getId()) == null) {
>                 createEntityManager(model);
>             }
>             return new
> ExternalUserStorageProvider(entityManagers.get(model.getId()), model,
> session);
>         } catch (Exception e) {
>             throw new RuntimeException(e);
>         }
>     }
>
>     @Override
>     public String getId() {
>         return "external-user-db";
>     }
>
>     @Override
>     public String getHelpText() {
>         return "External User Database Storage Provider";
>     }
>
>     private void createEntityManager(ComponentModel model) {
>         logger.info("creating entityManager for {}", model.getName());
>         Properties properties = getProperties(model);
>         EntityManagerFactory entityManagerFactory =
> Persistence.createEntityManagerFactory("external-user-storage", properties);
>         entityManagers.put(model.getId(),
> entityManagerFactory.createEntityManager());
>     }
>
>     private Properties getProperties(ComponentModel model) {
>         Properties properties = new Properties();
>         // Add class loader needed to find persistence.xml
>         properties.put(AvailableSettings.CLASSLOADERS,
> Arrays.asList(this.getClass().getClassLoader()));
>         // Set JPA properties
>         properties.put(AvailableSettings.JPA_PERSISTENCE_PROVIDER,
> HibernatePersistenceProvider.class.getName());
>         properties.put(AvailableSettings.JPA_TRANSACTION_TYPE,
> PersistenceUnitTransactionType.JTA.name());
>         // postgresql jdbc connection config
>         properties.put(AvailableSettings.JPA_JDBC_DRIVER,
> "org.postgresql.Driver");
>         properties.put(AvailableSettings.JPA_JDBC_URL,
> EnvUtil.replace(model.getConfig().getFirst(CONF_NAME_JDBC_URL)));
>         properties.put(AvailableSettings.JPA_JDBC_USER,
> EnvUtil.replace(model.getConfig().getFirst(CONF_NAME_JDBC_USER)));
>         properties.put(AvailableSettings.JPA_JDBC_PASSWORD,
> EnvUtil.replace(model.getConfig().getFirst(CONF_NAME_JDBC_PASSWORD)));
>         // hibernate
>         properties.put(AvailableSettings.DIALECT,
> org.hibernate.dialect.PostgreSQL95Dialect.class.getName());
>         properties.put(AvailableSettings.SHOW_SQL, Boolean.FALSE);
>         // set JTA properties
>         properties.put(AvailableSettings.JTA_PLATFORM,
> JBossAppServerJtaPlatform.class.getName());
>         return properties;
>     }
> }
>
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>


More information about the keycloak-user mailing list