brute force settings
This commit is contained in:
parent
b41bf9f231
commit
54abfb670c
11 changed files with 490 additions and 69 deletions
|
@ -1119,11 +1119,35 @@ module.controller('RealmAuditEventsCtrl', function($scope, RealmAuditEvents, rea
|
||||||
$scope.update();
|
$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');
|
console.log('RealmBruteForceCtrl');
|
||||||
|
|
||||||
$scope.realm = realm;
|
$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);
|
var oldCopy = angular.copy($scope.realm);
|
||||||
$scope.changed = false;
|
$scope.changed = false;
|
||||||
|
|
||||||
|
@ -1135,6 +1159,20 @@ module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $
|
||||||
|
|
||||||
$scope.save = function() {
|
$scope.save = function() {
|
||||||
var realmCopy = angular.copy($scope.realm);
|
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;
|
$scope.changed = false;
|
||||||
Realm.update(realmCopy, function () {
|
Realm.update(realmCopy, function () {
|
||||||
$location.url("/realms/" + realm.realm + "/sessions/brute-force");
|
$location.url("/realms/" + realm.realm + "/sessions/brute-force");
|
||||||
|
@ -1148,3 +1186,4 @@ module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,102 @@
|
||||||
<input ng-model="realm.bruteForceProtected" name="bruteForceProtected" id="bruteForceProtected" onoffswitch />
|
<input ng-model="realm.bruteForceProtected" name="bruteForceProtected" id="bruteForceProtected" onoffswitch />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" data-ng-show="realm.bruteForceProtected">
|
||||||
|
<label class="col-sm-2 control-label" for="failureFactor">Failure Factor</label>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input class="form-control" type="number" min="1" max="31536000" id="failureFactor" name="failureFactor" data-ng-model="realm.failureFactor" autofocus
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
|
||||||
|
<label class="col-sm-2 control-label" for="waitIncrement">Wait Increment</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input class="form-control" type="number" required min="1"
|
||||||
|
max="31536000" data-ng-model="realm.waitIncrement"
|
||||||
|
id="waitIncrement" name="waitIncrement"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 select-kc">
|
||||||
|
<select name="waitIncrementUnit" data-ng-model="realm.waitIncrementUnit" >
|
||||||
|
<option data-ng-selected="!realm.waitIncrementUnit">Seconds</option>
|
||||||
|
<option>Minutes</option>
|
||||||
|
<option>Hours</option>
|
||||||
|
<option>Days</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" data-ng-show="realm.bruteForceProtected">
|
||||||
|
<label class="col-sm-2 control-label" for="quickLoginCheckMilliSeconds">Quick Login Check Milli Seconds</label>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input class="form-control" type="number" min="1" max="31536000" id="quickLoginCheckMilliSeconds" name="quickLoginCheckMilliSeconds" data-ng-model="realm.quickLoginCheckMilliSeconds" autofocus
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
|
||||||
|
<label class="col-sm-2 control-label" for="minimumQuickLoginWait">Minimum Quick Login Wait</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input class="form-control" type="number" required min="1"
|
||||||
|
max="31536000" data-ng-model="realm.minimumQuickLoginWait"
|
||||||
|
id="minimumQuickLoginWait" name="minimumQuickLoginWait"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 select-kc">
|
||||||
|
<select name="minimumQuickLoginWaitUnit" data-ng-model="realm.minimumQuickLoginWaitUnit" >
|
||||||
|
<option data-ng-selected="!realm.minimumQuickLoginWaitUnit">Seconds</option>
|
||||||
|
<option>Minutes</option>
|
||||||
|
<option>Hours</option>
|
||||||
|
<option>Days</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
|
||||||
|
<label class="col-sm-2 control-label" for="maxFailureWait">Max Wait</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input class="form-control" type="number" required min="1"
|
||||||
|
max="31536000" data-ng-model="realm.maxFailureWait"
|
||||||
|
id="maxFailureWait" name="maxFailureWait"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 select-kc">
|
||||||
|
<select name="maxFailureWaitUnit" data-ng-model="realm.maxFailureWaitUnit" >
|
||||||
|
<option data-ng-selected="!realm.maxFailureWaitUnit">Seconds</option>
|
||||||
|
<option>Minutes</option>
|
||||||
|
<option>Hours</option>
|
||||||
|
<option>Days</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
|
||||||
|
<label class="col-sm-2 control-label" for="maxDeltaTime">Failure Reset Time</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input class="form-control" type="number" required min="1"
|
||||||
|
max="31536000" data-ng-model="realm.maxDeltaTime"
|
||||||
|
id="maxDeltaTime" name="maxDeltaTime"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 select-kc">
|
||||||
|
<select name="maxDeltaTimeUnit" data-ng-model="realm.maxDeltaTimeUnit" >
|
||||||
|
<option data-ng-selected="!realm.maxDeltaTimeUnit">Seconds</option>
|
||||||
|
<option>Minutes</option>
|
||||||
|
<option>Hours</option>
|
||||||
|
<option>Days</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div class="pull-right form-actions" data-ng-show="access.manageRealm">
|
<div class="pull-right form-actions" data-ng-show="access.manageRealm">
|
||||||
<button kc-reset data-ng-show="changed">Clear changes</button>
|
<button kc-reset data-ng-show="changed">Clear changes</button>
|
||||||
|
|
|
@ -28,7 +28,16 @@ public class RealmRepresentation {
|
||||||
protected Boolean resetPasswordAllowed;
|
protected Boolean resetPasswordAllowed;
|
||||||
protected Boolean social;
|
protected Boolean social;
|
||||||
protected Boolean updateProfileOnInitialSocialLogin;
|
protected Boolean updateProfileOnInitialSocialLogin;
|
||||||
|
//--- brute force settings
|
||||||
protected Boolean bruteForceProtected;
|
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 privateKey;
|
||||||
protected String publicKey;
|
protected String publicKey;
|
||||||
protected RolesRepresentation roles;
|
protected RolesRepresentation roles;
|
||||||
|
@ -384,4 +393,52 @@ public class RealmRepresentation {
|
||||||
public void setBruteForceProtected(Boolean bruteForceProtected) {
|
public void setBruteForceProtected(Boolean bruteForceProtected) {
|
||||||
this.bruteForceProtected = 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,23 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
||||||
|
|
||||||
void setRememberMe(boolean rememberMe);
|
void setRememberMe(boolean rememberMe);
|
||||||
|
|
||||||
|
//--- brute force settings
|
||||||
boolean isBruteForceProtected();
|
boolean isBruteForceProtected();
|
||||||
|
|
||||||
void setBruteForceProtected(boolean value);
|
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();
|
boolean isVerifyEmail();
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,66 @@ public class RealmAdapter implements RealmModel {
|
||||||
realm.setBruteForceProtected(value);
|
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
|
@Override
|
||||||
public boolean isVerifyEmail() {
|
public boolean isVerifyEmail() {
|
||||||
return realm.isVerifyEmail();
|
return realm.isVerifyEmail();
|
||||||
|
|
|
@ -42,7 +42,16 @@ public class RealmEntity {
|
||||||
protected boolean resetPasswordAllowed;
|
protected boolean resetPasswordAllowed;
|
||||||
protected boolean social;
|
protected boolean social;
|
||||||
protected boolean rememberMe;
|
protected boolean rememberMe;
|
||||||
|
//--- brute force settings
|
||||||
protected boolean bruteForceProtected;
|
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")
|
@Column(name="updateProfileOnInitSocLogin")
|
||||||
protected boolean updateProfileOnInitialSocialLogin;
|
protected boolean updateProfileOnInitialSocialLogin;
|
||||||
|
@ -352,6 +361,54 @@ public class RealmEntity {
|
||||||
this.bruteForceProtected = bruteForceProtected;
|
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() {
|
public boolean isAuditEnabled() {
|
||||||
return auditEnabled;
|
return auditEnabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,68 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
|
||||||
realm.setBruteForceProtected(value);
|
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
|
@Override
|
||||||
public boolean isVerifyEmail() {
|
public boolean isVerifyEmail() {
|
||||||
return realm.isVerifyEmail();
|
return realm.isVerifyEmail();
|
||||||
|
|
|
@ -32,7 +32,15 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
|
||||||
private boolean social;
|
private boolean social;
|
||||||
private boolean updateProfileOnInitialSocialLogin;
|
private boolean updateProfileOnInitialSocialLogin;
|
||||||
private String passwordPolicy;
|
private String passwordPolicy;
|
||||||
|
//--- brute force settings
|
||||||
private boolean bruteForceProtected;
|
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 centralLoginLifespan;
|
||||||
private int accessTokenLifespan;
|
private int accessTokenLifespan;
|
||||||
|
@ -151,6 +159,60 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
|
||||||
this.bruteForceProtected = bruteForceProtected;
|
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
|
@MongoField
|
||||||
public String getPasswordPolicy() {
|
public String getPasswordPolicy() {
|
||||||
return passwordPolicy;
|
return passwordPolicy;
|
||||||
|
|
|
@ -23,13 +23,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
public class BruteForceProtector implements Runnable {
|
public class BruteForceProtector implements Runnable {
|
||||||
protected static Logger logger = Logger.getLogger(BruteForceProtector.class);
|
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 volatile boolean run = true;
|
||||||
|
protected int maxDeltaTimeSeconds = 60 * 60 * 12; // 12 hours
|
||||||
protected KeycloakSessionFactory factory;
|
protected KeycloakSessionFactory factory;
|
||||||
protected CountDownLatch shutdownLatch = new CountDownLatch(1);
|
protected CountDownLatch shutdownLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -83,6 +78,8 @@ public class BruteForceProtector implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void failure(KeycloakSession session, LoginEvent event) {
|
public void failure(KeycloakSession session, LoginEvent event) {
|
||||||
|
RealmModel realm = getRealmModel(session, event);
|
||||||
|
logFailure(event);
|
||||||
UsernameLoginFailureModel user = getUserModel(session, event);
|
UsernameLoginFailureModel user = getUserModel(session, event);
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
user.setLastIPFailure(event.ip);
|
user.setLastIPFailure(event.ip);
|
||||||
|
@ -95,19 +92,19 @@ public class BruteForceProtector implements Runnable {
|
||||||
user.setLastFailure(currentTime);
|
user.setLastFailure(currentTime);
|
||||||
if (deltaTime > 0) {
|
if (deltaTime > 0) {
|
||||||
// if last failure was more than MAX_DELTA clear failures
|
// if last failure was more than MAX_DELTA clear failures
|
||||||
if (deltaTime > maxDeltaTimeMilliSeconds) {
|
if (deltaTime > (long)realm.getMaxDeltaTimeSeconds() *1000L) {
|
||||||
user.clearFailures();
|
user.clearFailures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user.incrementFailures();
|
user.incrementFailures();
|
||||||
|
|
||||||
int waitSeconds = waitIncrementSeconds * (user.getNumFailures() / failureFactor);
|
int waitSeconds = realm.getWaitIncrementSeconds() * (user.getNumFailures() / realm.getFailureFactor());
|
||||||
if (waitSeconds == 0) {
|
if (waitSeconds == 0) {
|
||||||
if (deltaTime > quickLoginCheckMilliSeconds) {
|
if (deltaTime > realm.getQuickLoginCheckMilliSeconds()) {
|
||||||
waitSeconds = minimumQuickLoginWaitSeconds;
|
waitSeconds = realm.getMinimumQuickLoginWaitSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitSeconds = Math.min(maxFailureWaitSeconds, waitSeconds);
|
waitSeconds = Math.min(realm.getMaxFailureWaitSeconds(), waitSeconds);
|
||||||
if (waitSeconds > 0) {
|
if (waitSeconds > 0) {
|
||||||
user.setFailedLoginNotBefore((int) (currentTime / 1000) + waitSeconds);
|
user.setFailedLoginNotBefore((int) (currentTime / 1000) + waitSeconds);
|
||||||
}
|
}
|
||||||
|
@ -153,14 +150,6 @@ public class BruteForceProtector implements Runnable {
|
||||||
try {
|
try {
|
||||||
events.add(take);
|
events.add(take);
|
||||||
queue.drainTo(events, TRANSACTION_SIZE);
|
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.
|
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
|
||||||
KeycloakSession session = factory.createSession();
|
KeycloakSession session = factory.createSession();
|
||||||
try {
|
try {
|
||||||
|
@ -203,7 +192,7 @@ public class BruteForceProtector implements Runnable {
|
||||||
long delta = 0;
|
long delta = 0;
|
||||||
if (lastFailure > 0) {
|
if (lastFailure > 0) {
|
||||||
delta = System.currentTimeMillis() - lastFailure;
|
delta = System.currentTimeMillis() - lastFailure;
|
||||||
if (delta > maxDeltaTimeMilliSeconds) {
|
if (delta > (long)maxDeltaTimeSeconds * 1000L) {
|
||||||
totalTime = 0;
|
totalTime = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -255,51 +244,5 @@ public class BruteForceProtector implements Runnable {
|
||||||
return lastFailure;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,12 @@ public class ModelToRepresentation {
|
||||||
rep.setRegistrationAllowed(realm.isRegistrationAllowed());
|
rep.setRegistrationAllowed(realm.isRegistrationAllowed());
|
||||||
rep.setRememberMe(realm.isRememberMe());
|
rep.setRememberMe(realm.isRememberMe());
|
||||||
rep.setBruteForceProtected(realm.isBruteForceProtected());
|
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.setVerifyEmail(realm.isVerifyEmail());
|
||||||
rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
|
rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
|
||||||
rep.setAccessTokenLifespan(realm.getAccessTokenLifespan());
|
rep.setAccessTokenLifespan(realm.getAccessTokenLifespan());
|
||||||
|
|
|
@ -79,7 +79,9 @@ public class RealmManager {
|
||||||
if (id == null) id = KeycloakModelUtils.generateId();
|
if (id == null) id = KeycloakModelUtils.generateId();
|
||||||
RealmModel realm = identitySession.createRealm(id, name);
|
RealmModel realm = identitySession.createRealm(id, name);
|
||||||
realm.setName(name);
|
realm.setName(name);
|
||||||
realm.setBruteForceProtected(false); // default settings off for now todo set it on
|
|
||||||
|
// setup defaults
|
||||||
|
setupRealmDefaults(realm);
|
||||||
|
|
||||||
setupAdminManagement(realm);
|
setupAdminManagement(realm);
|
||||||
setupAccountManagement(realm);
|
setupAccountManagement(realm);
|
||||||
|
@ -89,6 +91,17 @@ public class RealmManager {
|
||||||
return realm;
|
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) {
|
public boolean removeRealm(RealmModel realm) {
|
||||||
boolean removed = identitySession.removeRealm(realm.getId());
|
boolean removed = identitySession.removeRealm(realm.getId());
|
||||||
|
|
||||||
|
@ -123,6 +136,12 @@ public class RealmManager {
|
||||||
if (rep.isEnabled() != null) realm.setEnabled(rep.isEnabled());
|
if (rep.isEnabled() != null) realm.setEnabled(rep.isEnabled());
|
||||||
if (rep.isSocial() != null) realm.setSocial(rep.isSocial());
|
if (rep.isSocial() != null) realm.setSocial(rep.isSocial());
|
||||||
if (rep.isBruteForceProtected() != null) realm.setBruteForceProtected(rep.isBruteForceProtected());
|
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.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
|
||||||
if (rep.isRememberMe() != null) realm.setRememberMe(rep.isRememberMe());
|
if (rep.isRememberMe() != null) realm.setRememberMe(rep.isRememberMe());
|
||||||
if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
|
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.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
|
||||||
if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
|
if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
|
||||||
if (rep.isBruteForceProtected() != null) newRealm.setBruteForceProtected(rep.isBruteForceProtected());
|
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());
|
if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue