From dc7923c436042679f007f00fb30e1d1ab2bed38f Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Mon, 19 May 2014 10:33:49 -0400 Subject: [PATCH] fix brute shutdown --- core/src/main/java/org/keycloak/Config.java | 258 +++++++++--------- .../managers/BruteForceProtector.java | 78 +++--- .../resources/KeycloakApplication.java | 2 +- 3 files changed, 171 insertions(+), 167 deletions(-) mode change 100644 => 100755 core/src/main/java/org/keycloak/Config.java diff --git a/core/src/main/java/org/keycloak/Config.java b/core/src/main/java/org/keycloak/Config.java old mode 100644 new mode 100755 index 34d0fa4518..9af395b214 --- a/core/src/main/java/org/keycloak/Config.java +++ b/core/src/main/java/org/keycloak/Config.java @@ -1,129 +1,129 @@ -package org.keycloak; - -/** - * @author Stian Thorgersen - */ -public class Config { - - private static ConfigProvider configProvider = new SystemPropertiesConfigProvider(); - - public static void init(ConfigProvider configProvider) { - Config.configProvider = configProvider; - } - - public static String getAdminRealm() { - return configProvider.scope("admin").get("realm", "keycloak-admin"); - } - - public static String getProvider(String spi) { - return configProvider.getProvider(spi); - } - - public static Scope scope(String... scope) { - return configProvider.scope(scope); - } - - public static interface ConfigProvider { - - String getProvider(String spi); - - Scope scope(String... scope); - - } - - public static class SystemPropertiesConfigProvider implements ConfigProvider { - - @Override - public String getProvider(String spi) { - return System.getProperties().getProperty("keycloak." + spi + ".provider"); - } - - @Override - public Scope scope(String... scope) { - StringBuilder sb = new StringBuilder(); - sb.append("keycloak."); - for (String s : scope) { - sb.append(s); - sb.append("."); - } - return new SystemPropertiesScope(sb.toString()); - } - - } - - public static class SystemPropertiesScope implements Scope { - - private String prefix; - - public SystemPropertiesScope(String prefix) { - this.prefix = prefix; - } - - @Override - public String get(String key) { - return get(key, null); - } - - @Override - public String get(String key, String defaultValue) { - return System.getProperty(prefix + key, defaultValue); - } - - @Override - public Integer getInt(String key) { - return getInt(key, null); - } - - @Override - public Integer getInt(String key, Integer defaultValue) { - String v = get(key, null); - return v != null ? Integer.parseInt(v) : defaultValue; - } - - @Override - public Long getLong(String key) { - return getLong(key, null); - } - - @Override - public Long getLong(String key, Long defaultValue) { - String v = get(key, null); - return v != null ? Long.parseLong(v) : defaultValue; - } - - @Override - public Boolean getBoolean(String key) { - return getBoolean(key, null); - } - - @Override - public Boolean getBoolean(String key, Boolean defaultValue) { - String v = get(key, null); - return v != null ? Boolean.parseBoolean(v) : defaultValue; - } - - } - - /** - * @author Stian Thorgersen - */ - public static interface Scope { - - String get(String key); - - String get(String key, String defaultValue); - - Integer getInt(String key); - - Integer getInt(String key, Integer defaultValue); - - Long getLong(String key); - - Long getLong(String key, Long defaultValue); - - Boolean getBoolean(String key); - - Boolean getBoolean(String key, Boolean defaultValue); - - } -} +package org.keycloak; + +/** + * @author Stian Thorgersen + */ +public class Config { + + private static ConfigProvider configProvider = new SystemPropertiesConfigProvider(); + + public static void init(ConfigProvider configProvider) { + Config.configProvider = configProvider; + } + + public static String getAdminRealm() { + return configProvider.scope("admin").get("realm", "keycloak-admin"); + } + + public static String getProvider(String spi) { + return configProvider.getProvider(spi); + } + + public static Scope scope(String... scope) { + return configProvider.scope(scope); + } + + public static interface ConfigProvider { + + String getProvider(String spi); + + Scope scope(String... scope); + + } + + public static class SystemPropertiesConfigProvider implements ConfigProvider { + + @Override + public String getProvider(String spi) { + return System.getProperties().getProperty("keycloak." + spi + ".provider"); + } + + @Override + public Scope scope(String... scope) { + StringBuilder sb = new StringBuilder(); + sb.append("keycloak."); + for (String s : scope) { + sb.append(s); + sb.append("."); + } + return new SystemPropertiesScope(sb.toString()); + } + + } + + public static class SystemPropertiesScope implements Scope { + + private String prefix; + + public SystemPropertiesScope(String prefix) { + this.prefix = prefix; + } + + @Override + public String get(String key) { + return get(key, null); + } + + @Override + public String get(String key, String defaultValue) { + return System.getProperty(prefix + key, defaultValue); + } + + @Override + public Integer getInt(String key) { + return getInt(key, null); + } + + @Override + public Integer getInt(String key, Integer defaultValue) { + String v = get(key, null); + return v != null ? Integer.parseInt(v) : defaultValue; + } + + @Override + public Long getLong(String key) { + return getLong(key, null); + } + + @Override + public Long getLong(String key, Long defaultValue) { + String v = get(key, null); + return v != null ? Long.parseLong(v) : defaultValue; + } + + @Override + public Boolean getBoolean(String key) { + return getBoolean(key, null); + } + + @Override + public Boolean getBoolean(String key, Boolean defaultValue) { + String v = get(key, null); + return v != null ? Boolean.parseBoolean(v) : defaultValue; + } + + } + + /** + * @author Stian Thorgersen + */ + public static interface Scope { + + String get(String key); + + String get(String key, String defaultValue); + + Integer getInt(String key); + + Integer getInt(String key, Integer defaultValue); + + Long getLong(String key); + + Long getLong(String key, Long defaultValue); + + Boolean getBoolean(String key); + + Boolean getBoolean(String key, Boolean defaultValue); + + } +} diff --git a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java index f231825ee7..80dc5111a8 100755 --- a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java +++ b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java @@ -143,7 +143,7 @@ public class BruteForceProtector implements Runnable { run = false; try { queue.offer(new ShutdownEvent()); - shutdownLatch.await(5, TimeUnit.SECONDS); + shutdownLatch.await(10, TimeUnit.SECONDS); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -152,46 +152,50 @@ public class BruteForceProtector implements Runnable { public void run() { final ArrayList events = new ArrayList(TRANSACTION_SIZE + 1); - while (run) { - try { - LoginEvent take = queue.poll(2, TimeUnit.SECONDS); - if (take == null) { - continue; - } + try { + while (run) { try { - events.add(take); - queue.drainTo(events, TRANSACTION_SIZE); - Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this. - ProviderSession providerSession = factory.createSession(); - KeycloakSession session = providerSession.getProvider(KeycloakSession.class); - session.getTransaction().begin(); - try { - for (LoginEvent event : events) { - if (event instanceof FailedLogin) { - failure(session, event); - } - } - session.getTransaction().commit(); - } catch (Exception e) { - session.getTransaction().rollback(); - throw e; - } finally { - for (LoginEvent event : events) { - if (event instanceof FailedLogin) { - ((FailedLogin) event).latch.countDown(); - } - } - events.clear(); - providerSession.close(); + LoginEvent take = queue.poll(2, TimeUnit.SECONDS); + if (take == null) { + continue; } - } catch (Exception e) { - logger.error("Failed processing event", e); + try { + events.add(take); + queue.drainTo(events, TRANSACTION_SIZE); + Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this. + ProviderSession providerSession = factory.createSession(); + KeycloakSession session = providerSession.getProvider(KeycloakSession.class); + session.getTransaction().begin(); + try { + for (LoginEvent event : events) { + if (event instanceof FailedLogin) { + failure(session, event); + } else if (event instanceof ShutdownEvent) { + run = false; + } + } + session.getTransaction().commit(); + } catch (Exception e) { + session.getTransaction().rollback(); + throw e; + } finally { + for (LoginEvent event : events) { + if (event instanceof FailedLogin) { + ((FailedLogin) event).latch.countDown(); + } + } + events.clear(); + providerSession.close(); + } + } catch (Exception e) { + logger.error("Failed processing event", e); + } + } catch (InterruptedException e) { + break; } - } catch (InterruptedException e) { - break; - } finally { - shutdownLatch.countDown(); } + } finally { + shutdownLatch.countDown(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java index dec47523fc..c677aa868c 100755 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -133,7 +133,7 @@ public class KeycloakApplication extends Application { } public static void setupScheduledTasks(final ProviderSessionFactory providerSessionFactory) { - long interval = Config.scope("scheduled").getLong("interval") * 1000; + long interval = Config.scope("scheduled").getLong("interval", 60L) * 1000; TimerProvider timer = providerSessionFactory.createSession().getProvider(TimerProvider.class); timer.schedule(new ScheduledTaskRunner(providerSessionFactory, new ClearExpiredAuditEvents()), interval);