diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
index 04be1273b1..a08236d7ce 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
@@ -1119,11 +1119,35 @@ module.controller('RealmAuditEventsCtrl', function($scope, RealmAuditEvents, rea
$scope.update();
});
-module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications) {
+module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, TimeUnit) {
console.log('RealmBruteForceCtrl');
$scope.realm = realm;
+ $scope.realm.waitIncrementUnit = TimeUnit.autoUnit(realm.waitIncrementSeconds);
+ $scope.realm.waitIncrement = TimeUnit.toUnit(realm.waitIncrementSeconds, $scope.realm.waitIncrementUnit);
+ $scope.$watch('realm.waitIncrementUnit', function(to, from) {
+ $scope.realm.waitIncrement = TimeUnit.convert($scope.realm.waitIncrement, from, to);
+ });
+
+ $scope.realm.minimumQuickLoginWaitUnit = TimeUnit.autoUnit(realm.minimumQuickLoginWaitSeconds);
+ $scope.realm.minimumQuickLoginWait = TimeUnit.toUnit(realm.minimumQuickLoginWaitSeconds, $scope.realm.minimumQuickLoginWaitUnit);
+ $scope.$watch('realm.minimumQuickLoginWaitUnit', function(to, from) {
+ $scope.realm.minimumQuickLoginWait = TimeUnit.convert($scope.realm.minimumQuickLoginWait, from, to);
+ });
+
+ $scope.realm.maxFailureWaitUnit = TimeUnit.autoUnit(realm.maxFailureWaitSeconds);
+ $scope.realm.maxFailureWait = TimeUnit.toUnit(realm.maxFailureWaitSeconds, $scope.realm.maxFailureWaitUnit);
+ $scope.$watch('realm.maxFailureWaitUnit', function(to, from) {
+ $scope.realm.maxFailureWait = TimeUnit.convert($scope.realm.maxFailureWait, from, to);
+ });
+
+ $scope.realm.maxDeltaTimeUnit = TimeUnit.autoUnit(realm.maxDeltaTimeSeconds);
+ $scope.realm.maxDeltaTime = TimeUnit.toUnit(realm.maxDeltaTimeSeconds, $scope.realm.maxDeltaTimeUnit);
+ $scope.$watch('realm.maxDeltaTimeUnit', function(to, from) {
+ $scope.realm.maxDeltaTime = TimeUnit.convert($scope.realm.maxDeltaTime, from, to);
+ });
+
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
@@ -1135,6 +1159,20 @@ module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $
$scope.save = function() {
var realmCopy = angular.copy($scope.realm);
+ delete realmCopy["waitIncrementUnit"];
+ delete realmCopy["waitIncrement"];
+ delete realmCopy["minimumQuickLoginWaitUnit"];
+ delete realmCopy["minimumQuickLoginWait"];
+ delete realmCopy["maxFailureWaitUnit"];
+ delete realmCopy["maxFailureWait"];
+ delete realmCopy["maxDeltaTimeUnit"];
+ delete realmCopy["maxDeltaTime"];
+
+ realmCopy.waitIncrementSeconds = TimeUnit.toSeconds($scope.realm.waitIncrement, $scope.realm.waitIncrementUnit)
+ realmCopy.minimumQuickLoginWaitSeconds = TimeUnit.toSeconds($scope.realm.minimumQuickLoginWait, $scope.realm.minimumQuickLoginWaitUnit)
+ realmCopy.maxFailureWaitSeconds = TimeUnit.toSeconds($scope.realm.maxFailureWait, $scope.realm.maxFailureWaitUnit)
+ realmCopy.maxDeltaTimeSeconds = TimeUnit.toSeconds($scope.realm.maxDeltaTime, $scope.realm.maxDeltaTimeUnit)
+
$scope.changed = false;
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.realm + "/sessions/brute-force");
@@ -1148,3 +1186,4 @@ module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $
};
});
+
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/session-brute-force.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/session-brute-force.html
index ae4571284f..a2c7f4704f 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/session-brute-force.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/session-brute-force.html
@@ -20,6 +20,102 @@
+
+
+
+
+
+
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 0228a8ba7f..2812fc41d2 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -28,7 +28,16 @@ public class RealmRepresentation {
protected Boolean resetPasswordAllowed;
protected Boolean social;
protected Boolean updateProfileOnInitialSocialLogin;
+ //--- brute force settings
protected Boolean bruteForceProtected;
+ protected Integer maxFailureWaitSeconds;
+ protected Integer minimumQuickLoginWaitSeconds;
+ protected Integer waitIncrementSeconds;
+ protected Long quickLoginCheckMilliSeconds;
+ protected Integer maxDeltaTimeSeconds;
+ protected Integer failureFactor;
+ //--- end brute force settings
+
protected String privateKey;
protected String publicKey;
protected RolesRepresentation roles;
@@ -384,4 +393,52 @@ public class RealmRepresentation {
public void setBruteForceProtected(Boolean bruteForceProtected) {
this.bruteForceProtected = bruteForceProtected;
}
+
+ public Integer getMaxFailureWaitSeconds() {
+ return maxFailureWaitSeconds;
+ }
+
+ public void setMaxFailureWaitSeconds(Integer maxFailureWaitSeconds) {
+ this.maxFailureWaitSeconds = maxFailureWaitSeconds;
+ }
+
+ public Integer getMinimumQuickLoginWaitSeconds() {
+ return minimumQuickLoginWaitSeconds;
+ }
+
+ public void setMinimumQuickLoginWaitSeconds(Integer minimumQuickLoginWaitSeconds) {
+ this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
+ }
+
+ public Integer getWaitIncrementSeconds() {
+ return waitIncrementSeconds;
+ }
+
+ public void setWaitIncrementSeconds(Integer waitIncrementSeconds) {
+ this.waitIncrementSeconds = waitIncrementSeconds;
+ }
+
+ public Long getQuickLoginCheckMilliSeconds() {
+ return quickLoginCheckMilliSeconds;
+ }
+
+ public void setQuickLoginCheckMilliSeconds(Long quickLoginCheckMilliSeconds) {
+ this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
+ }
+
+ public Integer getMaxDeltaTimeSeconds() {
+ return maxDeltaTimeSeconds;
+ }
+
+ public void setMaxDeltaTimeSeconds(Integer maxDeltaTimeSeconds) {
+ this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
+ }
+
+ public Integer getFailureFactor() {
+ return failureFactor;
+ }
+
+ public void setFailureFactor(Integer failureFactor) {
+ this.failureFactor = failureFactor;
+ }
}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 6e2060505f..eda8e30d97 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -33,9 +33,23 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
void setRememberMe(boolean rememberMe);
+ //--- brute force settings
boolean isBruteForceProtected();
-
void setBruteForceProtected(boolean value);
+ int getMaxFailureWaitSeconds();
+ void setMaxFailureWaitSeconds(int val);
+ int getWaitIncrementSeconds();
+ void setWaitIncrementSeconds(int val);
+ int getMinimumQuickLoginWaitSeconds();
+ void setMinimumQuickLoginWaitSeconds(int val);
+ long getQuickLoginCheckMilliSeconds();
+ void setQuickLoginCheckMilliSeconds(long val);
+ int getMaxDeltaTimeSeconds();
+ void setMaxDeltaTimeSeconds(int val);
+ int getFailureFactor();
+ void setFailureFactor(int failureFactor);
+ //--- end brute force settings
+
boolean isVerifyEmail();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index fce9a3d9f2..2833c64601 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -136,6 +136,66 @@ public class RealmAdapter implements RealmModel {
realm.setBruteForceProtected(value);
}
+ @Override
+ public int getMaxFailureWaitSeconds() {
+ return realm.getMaxFailureWaitSeconds();
+ }
+
+ @Override
+ public void setMaxFailureWaitSeconds(int val) {
+ realm.setMaxFailureWaitSeconds(val);
+ }
+
+ @Override
+ public int getWaitIncrementSeconds() {
+ return realm.getWaitIncrementSeconds();
+ }
+
+ @Override
+ public void setWaitIncrementSeconds(int val) {
+ realm.setWaitIncrementSeconds(val);
+ }
+
+ @Override
+ public long getQuickLoginCheckMilliSeconds() {
+ return realm.getQuickLoginCheckMilliSeconds();
+ }
+
+ @Override
+ public void setQuickLoginCheckMilliSeconds(long val) {
+ realm.setQuickLoginCheckMilliSeconds(val);
+ }
+
+ @Override
+ public int getMinimumQuickLoginWaitSeconds() {
+ return realm.getMinimumQuickLoginWaitSeconds();
+ }
+
+ @Override
+ public void setMinimumQuickLoginWaitSeconds(int val) {
+ realm.setMinimumQuickLoginWaitSeconds(val);
+ }
+
+ @Override
+ public int getMaxDeltaTimeSeconds() {
+ return realm.getMaxDeltaTimeSeconds();
+ }
+
+ @Override
+ public void setMaxDeltaTimeSeconds(int val) {
+ realm.setMaxDeltaTimeSeconds(val);
+ }
+
+ @Override
+ public int getFailureFactor() {
+ return realm.getFailureFactor();
+ }
+
+ @Override
+ public void setFailureFactor(int failureFactor) {
+ realm.setFailureFactor(failureFactor);
+ }
+
@Override
public boolean isVerifyEmail() {
return realm.isVerifyEmail();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index 6885a7006f..556065f41d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -42,7 +42,16 @@ public class RealmEntity {
protected boolean resetPasswordAllowed;
protected boolean social;
protected boolean rememberMe;
+ //--- brute force settings
protected boolean bruteForceProtected;
+ protected int maxFailureWaitSeconds;
+ protected int minimumQuickLoginWaitSeconds;
+ protected int waitIncrementSeconds;
+ protected long quickLoginCheckMilliSeconds;
+ protected int maxDeltaTimeSeconds;
+ protected int failureFactor;
+ //--- end brute force settings
+
@Column(name="updateProfileOnInitSocLogin")
protected boolean updateProfileOnInitialSocialLogin;
@@ -352,6 +361,54 @@ public class RealmEntity {
this.bruteForceProtected = bruteForceProtected;
}
+ public int getMaxFailureWaitSeconds() {
+ return maxFailureWaitSeconds;
+ }
+
+ public void setMaxFailureWaitSeconds(int maxFailureWaitSeconds) {
+ this.maxFailureWaitSeconds = maxFailureWaitSeconds;
+ }
+
+ public int getMinimumQuickLoginWaitSeconds() {
+ return minimumQuickLoginWaitSeconds;
+ }
+
+ public void setMinimumQuickLoginWaitSeconds(int minimumQuickLoginWaitSeconds) {
+ this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
+ }
+
+ public int getWaitIncrementSeconds() {
+ return waitIncrementSeconds;
+ }
+
+ public void setWaitIncrementSeconds(int waitIncrementSeconds) {
+ this.waitIncrementSeconds = waitIncrementSeconds;
+ }
+
+ public long getQuickLoginCheckMilliSeconds() {
+ return quickLoginCheckMilliSeconds;
+ }
+
+ public void setQuickLoginCheckMilliSeconds(long quickLoginCheckMilliSeconds) {
+ this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
+ }
+
+ public int getMaxDeltaTimeSeconds() {
+ return maxDeltaTimeSeconds;
+ }
+
+ public void setMaxDeltaTimeSeconds(int maxDeltaTimeSeconds) {
+ this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
+ }
+
+ public int getFailureFactor() {
+ return failureFactor;
+ }
+
+ public void setFailureFactor(int failureFactor) {
+ this.failureFactor = failureFactor;
+ }
+
public boolean isAuditEnabled() {
return auditEnabled;
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 3fc43f24d4..2052967b53 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -134,6 +134,68 @@ public class RealmAdapter extends AbstractMongoAdapter implements R
realm.setBruteForceProtected(value);
}
+ @Override
+ public int getMaxFailureWaitSeconds() {
+ return realm.getMaxFailureWaitSeconds();
+ }
+
+ @Override
+ public void setMaxFailureWaitSeconds(int val) {
+ realm.setMaxFailureWaitSeconds(val);
+ }
+
+ @Override
+ public int getWaitIncrementSeconds() {
+ return realm.getWaitIncrementSeconds();
+ }
+
+ @Override
+ public void setWaitIncrementSeconds(int val) {
+ realm.setWaitIncrementSeconds(val);
+ }
+
+ @Override
+ public long getQuickLoginCheckMilliSeconds() {
+ return realm.getQuickLoginCheckMilliSeconds();
+ }
+
+ @Override
+ public void setQuickLoginCheckMilliSeconds(long val) {
+ realm.setQuickLoginCheckMilliSeconds(val);
+ }
+
+ @Override
+ public int getMinimumQuickLoginWaitSeconds() {
+ return realm.getMinimumQuickLoginWaitSeconds();
+ }
+
+ @Override
+ public void setMinimumQuickLoginWaitSeconds(int val) {
+ realm.setMinimumQuickLoginWaitSeconds(val);
+ }
+
+
+ @Override
+ public int getMaxDeltaTimeSeconds() {
+ return realm.getMaxDeltaTimeSeconds();
+ }
+
+ @Override
+ public void setMaxDeltaTimeSeconds(int val) {
+ realm.setMaxDeltaTimeSeconds(val);
+ }
+
+ @Override
+ public int getFailureFactor() {
+ return realm.getFailureFactor();
+ }
+
+ @Override
+ public void setFailureFactor(int failureFactor) {
+ realm.setFailureFactor(failureFactor);
+ }
+
+
@Override
public boolean isVerifyEmail() {
return realm.isVerifyEmail();
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java
index 6786c9013f..fc0ee56a82 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java
@@ -32,7 +32,15 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
private boolean social;
private boolean updateProfileOnInitialSocialLogin;
private String passwordPolicy;
+ //--- brute force settings
private boolean bruteForceProtected;
+ private int maxFailureWaitSeconds;
+ private int minimumQuickLoginWaitSeconds;
+ private int waitIncrementSeconds;
+ private long quickLoginCheckMilliSeconds;
+ private int maxDeltaTimeSeconds;
+ private int failureFactor;
+ //--- end brute force settings
private int centralLoginLifespan;
private int accessTokenLifespan;
@@ -151,6 +159,60 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
this.bruteForceProtected = bruteForceProtected;
}
+ @MongoField
+ public int getMaxFailureWaitSeconds() {
+ return maxFailureWaitSeconds;
+ }
+
+ public void setMaxFailureWaitSeconds(int maxFailureWaitSeconds) {
+ this.maxFailureWaitSeconds = maxFailureWaitSeconds;
+ }
+
+ @MongoField
+ public int getMinimumQuickLoginWaitSeconds() {
+ return minimumQuickLoginWaitSeconds;
+ }
+
+ public void setMinimumQuickLoginWaitSeconds(int minimumQuickLoginWaitSeconds) {
+ this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
+ }
+
+ @MongoField
+ public int getWaitIncrementSeconds() {
+ return waitIncrementSeconds;
+ }
+
+ public void setWaitIncrementSeconds(int waitIncrementSeconds) {
+ this.waitIncrementSeconds = waitIncrementSeconds;
+ }
+
+ @MongoField
+ public long getQuickLoginCheckMilliSeconds() {
+ return quickLoginCheckMilliSeconds;
+ }
+
+ public void setQuickLoginCheckMilliSeconds(long quickLoginCheckMilliSeconds) {
+ this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
+ }
+
+ @MongoField
+ public int getMaxDeltaTimeSeconds() {
+ return maxDeltaTimeSeconds;
+ }
+
+ public void setMaxDeltaTimeSeconds(int maxDeltaTimeSeconds) {
+ this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
+ }
+
+ @MongoField
+ public int getFailureFactor() {
+ return failureFactor;
+ }
+
+ public void setFailureFactor(int failureFactor) {
+ this.failureFactor = failureFactor;
+ }
+
@MongoField
public String getPasswordPolicy() {
return passwordPolicy;
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 8692bf183b..5645c57c04 100755
--- a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
+++ b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
@@ -23,13 +23,8 @@ import java.util.concurrent.TimeUnit;
public class BruteForceProtector implements Runnable {
protected static Logger logger = Logger.getLogger(BruteForceProtector.class);
- protected int maxFailureWaitSeconds = 900;
- protected int minimumQuickLoginWaitSeconds = 60;
- protected int waitIncrementSeconds = 60;
- protected long quickLoginCheckMilliSeconds = 1000;
- protected long maxDeltaTimeMilliSeconds = 60 * 60 * 12 * 1000; // 12 hours
- protected int failureFactor = 30;
protected volatile boolean run = true;
+ protected int maxDeltaTimeSeconds = 60 * 60 * 12; // 12 hours
protected KeycloakSessionFactory factory;
protected CountDownLatch shutdownLatch = new CountDownLatch(1);
@@ -83,6 +78,8 @@ public class BruteForceProtector implements Runnable {
}
public void failure(KeycloakSession session, LoginEvent event) {
+ RealmModel realm = getRealmModel(session, event);
+ logFailure(event);
UsernameLoginFailureModel user = getUserModel(session, event);
if (user == null) return;
user.setLastIPFailure(event.ip);
@@ -95,19 +92,19 @@ public class BruteForceProtector implements Runnable {
user.setLastFailure(currentTime);
if (deltaTime > 0) {
// if last failure was more than MAX_DELTA clear failures
- if (deltaTime > maxDeltaTimeMilliSeconds) {
+ if (deltaTime > (long)realm.getMaxDeltaTimeSeconds() *1000L) {
user.clearFailures();
}
}
user.incrementFailures();
- int waitSeconds = waitIncrementSeconds * (user.getNumFailures() / failureFactor);
+ int waitSeconds = realm.getWaitIncrementSeconds() * (user.getNumFailures() / realm.getFailureFactor());
if (waitSeconds == 0) {
- if (deltaTime > quickLoginCheckMilliSeconds) {
- waitSeconds = minimumQuickLoginWaitSeconds;
+ if (deltaTime > realm.getQuickLoginCheckMilliSeconds()) {
+ waitSeconds = realm.getMinimumQuickLoginWaitSeconds();
}
}
- waitSeconds = Math.min(maxFailureWaitSeconds, waitSeconds);
+ waitSeconds = Math.min(realm.getMaxFailureWaitSeconds(), waitSeconds);
if (waitSeconds > 0) {
user.setFailedLoginNotBefore((int) (currentTime / 1000) + waitSeconds);
}
@@ -153,14 +150,6 @@ public class BruteForceProtector implements Runnable {
try {
events.add(take);
queue.drainTo(events, TRANSACTION_SIZE);
- for (LoginEvent event : events) {
- if (event instanceof FailedLogin) {
- logFailure(event);
- } else if (event instanceof SuccessfulLogin) {
- logSuccess(event);
- }
- }
-
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
KeycloakSession session = factory.createSession();
try {
@@ -203,7 +192,7 @@ public class BruteForceProtector implements Runnable {
long delta = 0;
if (lastFailure > 0) {
delta = System.currentTimeMillis() - lastFailure;
- if (delta > maxDeltaTimeMilliSeconds) {
+ if (delta > (long)maxDeltaTimeSeconds * 1000L) {
totalTime = 0;
} else {
@@ -255,51 +244,5 @@ public class BruteForceProtector implements Runnable {
return lastFailure;
}
- public int getMaxFailureWaitSeconds() {
- return maxFailureWaitSeconds;
- }
- public void setMaxFailureWaitSeconds(int maxFailureWaitSeconds) {
- this.maxFailureWaitSeconds = maxFailureWaitSeconds;
- }
-
- public int getMinimumQuickLoginWaitSeconds() {
- return minimumQuickLoginWaitSeconds;
- }
-
- public void setMinimumQuickLoginWaitSeconds(int minimumQuickLoginWaitSeconds) {
- this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
- }
-
- public int getWaitIncrementSeconds() {
- return waitIncrementSeconds;
- }
-
- public void setWaitIncrementSeconds(int waitIncrementSeconds) {
- this.waitIncrementSeconds = waitIncrementSeconds;
- }
-
- public long getQuickLoginCheckMilliSeconds() {
- return quickLoginCheckMilliSeconds;
- }
-
- public void setQuickLoginCheckMilliSeconds(long quickLoginCheckMilliSeconds) {
- this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
- }
-
- public long getMaxDeltaTimeMilliSeconds() {
- return maxDeltaTimeMilliSeconds;
- }
-
- public void setMaxDeltaTimeMilliSeconds(long maxDeltaTimeMilliSeconds) {
- this.maxDeltaTimeMilliSeconds = maxDeltaTimeMilliSeconds;
- }
-
- public int getFailureFactor() {
- return failureFactor;
- }
-
- public void setFailureFactor(int failureFactor) {
- this.failureFactor = failureFactor;
- }
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
index 24c09b2016..197046b3ea 100755
--- a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
+++ b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
@@ -79,6 +79,12 @@ public class ModelToRepresentation {
rep.setRegistrationAllowed(realm.isRegistrationAllowed());
rep.setRememberMe(realm.isRememberMe());
rep.setBruteForceProtected(realm.isBruteForceProtected());
+ rep.setMaxFailureWaitSeconds(realm.getMaxFailureWaitSeconds());
+ rep.setMinimumQuickLoginWaitSeconds(realm.getMinimumQuickLoginWaitSeconds());
+ rep.setWaitIncrementSeconds(realm.getWaitIncrementSeconds());
+ rep.setQuickLoginCheckMilliSeconds(realm.getQuickLoginCheckMilliSeconds());
+ rep.setMaxDeltaTimeSeconds(realm.getMaxDeltaTimeSeconds());
+ rep.setFailureFactor(realm.getFailureFactor());
rep.setVerifyEmail(realm.isVerifyEmail());
rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
rep.setAccessTokenLifespan(realm.getAccessTokenLifespan());
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index b710af6cc4..f6e9bebf8e 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -79,7 +79,9 @@ public class RealmManager {
if (id == null) id = KeycloakModelUtils.generateId();
RealmModel realm = identitySession.createRealm(id, name);
realm.setName(name);
- realm.setBruteForceProtected(false); // default settings off for now todo set it on
+
+ // setup defaults
+ setupRealmDefaults(realm);
setupAdminManagement(realm);
setupAccountManagement(realm);
@@ -89,6 +91,17 @@ public class RealmManager {
return realm;
}
+ protected void setupRealmDefaults(RealmModel realm) {
+ // brute force
+ realm.setBruteForceProtected(false); // default settings off for now todo set it on
+ realm.setMaxFailureWaitSeconds(900);
+ realm.setMinimumQuickLoginWaitSeconds(60);
+ realm.setWaitIncrementSeconds(60);
+ realm.setQuickLoginCheckMilliSeconds(1000);
+ realm.setMaxDeltaTimeSeconds(60 * 60 * 12); // 12 hours
+ realm.setFailureFactor(30);
+ }
+
public boolean removeRealm(RealmModel realm) {
boolean removed = identitySession.removeRealm(realm.getId());
@@ -123,6 +136,12 @@ public class RealmManager {
if (rep.isEnabled() != null) realm.setEnabled(rep.isEnabled());
if (rep.isSocial() != null) realm.setSocial(rep.isSocial());
if (rep.isBruteForceProtected() != null) realm.setBruteForceProtected(rep.isBruteForceProtected());
+ if (rep.getMaxFailureWaitSeconds() != null) realm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
+ if (rep.getMinimumQuickLoginWaitSeconds() != null) realm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
+ if (rep.getWaitIncrementSeconds() != null) realm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
+ if (rep.getQuickLoginCheckMilliSeconds() != null) realm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
+ if (rep.getMaxDeltaTimeSeconds() != null) realm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
+ if (rep.getFailureFactor() != null) realm.setFailureFactor(rep.getFailureFactor());
if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
if (rep.isRememberMe() != null) realm.setRememberMe(rep.isRememberMe());
if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
@@ -230,6 +249,12 @@ public class RealmManager {
if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
if (rep.isBruteForceProtected() != null) newRealm.setBruteForceProtected(rep.isBruteForceProtected());
+ if (rep.getMaxFailureWaitSeconds() != null) newRealm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
+ if (rep.getMinimumQuickLoginWaitSeconds() != null) newRealm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
+ if (rep.getWaitIncrementSeconds() != null) newRealm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
+ if (rep.getQuickLoginCheckMilliSeconds() != null) newRealm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
+ if (rep.getMaxDeltaTimeSeconds() != null) newRealm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
+ if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());