brute force fixes
This commit is contained in:
parent
80f3a3152c
commit
541e865fe8
4 changed files with 16 additions and 8 deletions
|
@ -7,7 +7,6 @@
|
|||
"sslNotRequired": true,
|
||||
"registrationAllowed": false,
|
||||
"social": false,
|
||||
"bruteForceProtected": true,
|
||||
"updateProfileOnInitialSocialLogin": false,
|
||||
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.keycloak.services.managers;
|
||||
|
||||
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
@ -78,10 +78,13 @@ public class BruteForceProtector implements Runnable {
|
|||
}
|
||||
|
||||
public void failure(KeycloakSession session, LoginEvent event) {
|
||||
logger.debug("failure");
|
||||
RealmModel realm = getRealmModel(session, event);
|
||||
logFailure(event);
|
||||
UsernameLoginFailureModel user = getUserModel(session, event);
|
||||
if (user == null) return;
|
||||
if (user == null) {
|
||||
user = realm.addUserLoginFailure(event.username);
|
||||
}
|
||||
user.setLastIPFailure(event.ip);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long last = user.getLastFailure();
|
||||
|
@ -97,16 +100,22 @@ public class BruteForceProtector implements Runnable {
|
|||
}
|
||||
}
|
||||
user.incrementFailures();
|
||||
logger.debugv("new num failures: {0}" , user.getNumFailures());
|
||||
|
||||
int waitSeconds = realm.getWaitIncrementSeconds() * (user.getNumFailures() / realm.getFailureFactor());
|
||||
logger.debugv("waitSeconds: {0}", waitSeconds);
|
||||
logger.debugv("deltaTime: {0}", deltaTime);
|
||||
if (waitSeconds == 0) {
|
||||
if (deltaTime > realm.getQuickLoginCheckMilliSeconds()) {
|
||||
if (last > 0 && deltaTime < realm.getQuickLoginCheckMilliSeconds()) {
|
||||
logger.debugv("quick login, set min wait seconds");
|
||||
waitSeconds = realm.getMinimumQuickLoginWaitSeconds();
|
||||
}
|
||||
}
|
||||
waitSeconds = Math.min(realm.getMaxFailureWaitSeconds(), waitSeconds);
|
||||
if (waitSeconds > 0) {
|
||||
user.setFailedLoginNotBefore((int) (currentTime / 1000) + waitSeconds);
|
||||
waitSeconds = Math.min(realm.getMaxFailureWaitSeconds(), waitSeconds);
|
||||
int notBefore = (int) (currentTime / 1000) + waitSeconds;
|
||||
logger.debugv("set notBefore: {0}", notBefore);
|
||||
user.setFailedLoginNotBefore(notBefore);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +161,7 @@ public class BruteForceProtector implements Runnable {
|
|||
queue.drainTo(events, TRANSACTION_SIZE);
|
||||
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
|
||||
KeycloakSession session = factory.createSession();
|
||||
session.getTransaction().begin();
|
||||
try {
|
||||
for (LoginEvent event : events) {
|
||||
if (event instanceof FailedLogin) {
|
||||
|
@ -231,6 +241,7 @@ public class BruteForceProtector implements Runnable {
|
|||
|
||||
int currTime = (int)(System.currentTimeMillis()/1000);
|
||||
if (currTime < failure.getFailedLoginNotBefore()) {
|
||||
logger.debugv("Current: {0} notBefore: {1}", currTime , failure.getFailedLoginNotBefore());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
"accessCodeLifespan": 600,
|
||||
"accessCodeLifespanUserAction": 600,
|
||||
"sslNotRequired": true,
|
||||
"bruteForceProtected": true,
|
||||
"registrationAllowed": true,
|
||||
"resetPasswordAllowed": true,
|
||||
"requiredCredentials": [ "password" ],
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
"sslNotRequired": true,
|
||||
"registrationAllowed": true,
|
||||
"resetPasswordAllowed": true,
|
||||
"bruteForceProtected": true,
|
||||
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"requiredCredentials": [ "password" ],
|
||||
|
|
Loading…
Reference in a new issue