fixes
This commit is contained in:
parent
8e65356891
commit
a1bcd0651d
3 changed files with 4 additions and 65 deletions
|
@ -64,7 +64,7 @@ public class Pbkdf2PasswordHashProvider implements PasswordHashProviderFactory,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean policyCheck(PasswordPolicy policy, CredentialModel credential) {
|
public boolean policyCheck(PasswordPolicy policy, CredentialModel credential) {
|
||||||
return credential.getHashIterations() == policy.getHashIterations() && PBKDF2_ALGORITHM.equals(credential.getAlgorithm());
|
return credential.getHashIterations() == policy.getHashIterations() && ID.equals(credential.getAlgorithm());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -53,19 +53,6 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
protected LinkedBlockingQueue<LoginEvent> queue = new LinkedBlockingQueue<LoginEvent>();
|
protected LinkedBlockingQueue<LoginEvent> queue = new LinkedBlockingQueue<LoginEvent>();
|
||||||
public static final int TRANSACTION_SIZE = 20;
|
public static final int TRANSACTION_SIZE = 20;
|
||||||
|
|
||||||
public static volatile int markNotBefore = -1;
|
|
||||||
public static volatile int markCheck = -1;
|
|
||||||
public static volatile int testCount = 0;
|
|
||||||
public static volatile int clearCount = 0;
|
|
||||||
public static volatile int nullFailureCount = 0;
|
|
||||||
public static volatile int logFailureCalled = 0;
|
|
||||||
public static volatile int logFailure = 0;
|
|
||||||
public static volatile int didntWait = 0;
|
|
||||||
public static volatile int exception = 0;
|
|
||||||
public static volatile Exception exceptionObject = null;
|
|
||||||
public static volatile String notFoundUserId = null;
|
|
||||||
|
|
||||||
|
|
||||||
protected abstract class LoginEvent implements Comparable<LoginEvent> {
|
protected abstract class LoginEvent implements Comparable<LoginEvent> {
|
||||||
protected final String realmId;
|
protected final String realmId;
|
||||||
protected final String userId;
|
protected final String userId;
|
||||||
|
@ -103,7 +90,6 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
|
|
||||||
public void failure(KeycloakSession session, LoginEvent event) {
|
public void failure(KeycloakSession session, LoginEvent event) {
|
||||||
logger.debug("failure");
|
logger.debug("failure");
|
||||||
logFailureCalled++;
|
|
||||||
RealmModel realm = getRealmModel(session, event);
|
RealmModel realm = getRealmModel(session, event);
|
||||||
logFailure(event);
|
logFailure(event);
|
||||||
|
|
||||||
|
@ -111,7 +97,6 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
UserModel user = session.users().getUserById(userId, realm);
|
UserModel user = session.users().getUserById(userId, realm);
|
||||||
UserLoginFailureModel userLoginFailure = getUserModel(session, event);
|
UserLoginFailureModel userLoginFailure = getUserModel(session, event);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
logFailure++;
|
|
||||||
if (userLoginFailure == null) {
|
if (userLoginFailure == null) {
|
||||||
userLoginFailure = session.sessions().addUserLoginFailure(realm, userId);
|
userLoginFailure = session.sessions().addUserLoginFailure(realm, userId);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +111,6 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
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 > (long) realm.getMaxDeltaTimeSeconds() * 1000L) {
|
if (deltaTime > (long) realm.getMaxDeltaTimeSeconds() * 1000L) {
|
||||||
clearCount++;
|
|
||||||
userLoginFailure.clearFailures();
|
userLoginFailure.clearFailures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,12 +131,8 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
waitSeconds = Math.min(realm.getMaxFailureWaitSeconds(), waitSeconds);
|
waitSeconds = Math.min(realm.getMaxFailureWaitSeconds(), waitSeconds);
|
||||||
int notBefore = (int) (currentTime / 1000) + waitSeconds;
|
int notBefore = (int) (currentTime / 1000) + waitSeconds;
|
||||||
logger.debugv("set notBefore: {0}", notBefore);
|
logger.debugv("set notBefore: {0}", notBefore);
|
||||||
markNotBefore = notBefore;
|
|
||||||
userLoginFailure.setFailedLoginNotBefore(notBefore);
|
userLoginFailure.setFailedLoginNotBefore(notBefore);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
notFoundUserId = event.userId;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,8 +190,6 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
}
|
}
|
||||||
session.getTransactionManager().commit();
|
session.getTransactionManager().commit();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exception++;
|
|
||||||
exceptionObject = e;
|
|
||||||
session.getTransactionManager().rollback();
|
session.getTransactionManager().rollback();
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -258,13 +236,8 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
// wait a minimum of seconds for type to process so that a hacker
|
// wait a minimum of seconds for type to process so that a hacker
|
||||||
// cannot flood with failed logins and overwhelm the queue and not have notBefore updated to block next requests
|
// cannot flood with failed logins and overwhelm the queue and not have notBefore updated to block next requests
|
||||||
// todo failure HTTP responses should be queued via async HTTP
|
// todo failure HTTP responses should be queued via async HTTP
|
||||||
boolean awaited =
|
|
||||||
event.latch.await(5, TimeUnit.SECONDS);
|
event.latch.await(5, TimeUnit.SECONDS);
|
||||||
if (!awaited) {
|
|
||||||
didntWait++;
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
didntWait++;
|
|
||||||
}
|
}
|
||||||
logger.trace("sent failure event");
|
logger.trace("sent failure event");
|
||||||
}
|
}
|
||||||
|
@ -274,19 +247,12 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
|
||||||
UserLoginFailureModel failure = session.sessions().getUserLoginFailure(realm, user.getId());
|
UserLoginFailureModel failure = session.sessions().getUserLoginFailure(realm, user.getId());
|
||||||
|
|
||||||
if (failure != null) {
|
if (failure != null) {
|
||||||
int currTime = markCheck = (int) (Time.currentTimeMillis() / 1000);
|
int currTime = (int) (Time.currentTimeMillis() / 1000);
|
||||||
int failedLoginNotBefore = failure.getFailedLoginNotBefore();
|
int failedLoginNotBefore = failure.getFailedLoginNotBefore();
|
||||||
testCount++;
|
|
||||||
if (currTime < failedLoginNotBefore) {
|
if (currTime < failedLoginNotBefore) {
|
||||||
logger.debugv("Current: {0} notBefore: {1}", currTime, failedLoginNotBefore);
|
logger.debugv("Current: {0} notBefore: {1}", currTime, failedLoginNotBefore);
|
||||||
return true;
|
return true;
|
||||||
} else if (failedLoginNotBefore > 0){
|
|
||||||
logger.debugv("failedLoginNotBefore > 0 Current: {0} notBefore: {1}", currTime, failedLoginNotBefore);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
logger.debugv("failure was null");
|
|
||||||
nullFailureCount++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,6 @@ public class BruteForceTest extends TestRealmKeycloakTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGrantInvalidOtp() throws Exception {
|
public void testGrantInvalidOtp() throws Exception {
|
||||||
clearVariables();
|
|
||||||
{
|
{
|
||||||
String totpSecret = totp.generateTOTP("totpSecret");
|
String totpSecret = totp.generateTOTP("totpSecret");
|
||||||
OAuthClient.AccessTokenResponse response = getTestToken("password", totpSecret);
|
OAuthClient.AccessTokenResponse response = getTestToken("password", totpSecret);
|
||||||
|
@ -215,40 +214,14 @@ public class BruteForceTest extends TestRealmKeycloakTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearVariables() {
|
|
||||||
DefaultBruteForceProtector.testCount = 0;
|
|
||||||
DefaultBruteForceProtector.markNotBefore = -1;
|
|
||||||
DefaultBruteForceProtector.markCheck = -1;
|
|
||||||
DefaultBruteForceProtector.testCount = 0;
|
|
||||||
DefaultBruteForceProtector.clearCount = 0;
|
|
||||||
DefaultBruteForceProtector.logFailure = 0;
|
|
||||||
DefaultBruteForceProtector.logFailureCalled = 0;
|
|
||||||
DefaultBruteForceProtector.didntWait = 0;
|
|
||||||
DefaultBruteForceProtector.nullFailureCount = 0;
|
|
||||||
DefaultBruteForceProtector.notFoundUserId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertTokenNull(OAuthClient.AccessTokenResponse response) {
|
public void assertTokenNull(OAuthClient.AccessTokenResponse response) {
|
||||||
if (response.getAccessToken() != null) {
|
Assert.assertNull(response.getAccessToken());
|
||||||
if (DefaultBruteForceProtector.exceptionObject != null) {
|
|
||||||
DefaultBruteForceProtector.exceptionObject.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert.assertNull("was mark set: " + DefaultBruteForceProtector.markNotBefore + " time test: " + DefaultBruteForceProtector.markCheck
|
|
||||||
+ " test count " + DefaultBruteForceProtector.testCount
|
|
||||||
+ " nullFailure: " + DefaultBruteForceProtector.nullFailureCount
|
|
||||||
+ " logFailureCalled: " + DefaultBruteForceProtector.logFailureCalled
|
|
||||||
+ " logFailure: " + DefaultBruteForceProtector.logFailure
|
|
||||||
+ " notFoundUserId: " + DefaultBruteForceProtector.notFoundUserId
|
|
||||||
+ " exception: " + DefaultBruteForceProtector.exception
|
|
||||||
, response.getAccessToken());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGrantMissingOtp() throws Exception {
|
public void testGrantMissingOtp() throws Exception {
|
||||||
clearVariables();
|
|
||||||
{
|
{
|
||||||
String totpSecret = totp.generateTOTP("totpSecret");
|
String totpSecret = totp.generateTOTP("totpSecret");
|
||||||
OAuthClient.AccessTokenResponse response = getTestToken("password", totpSecret);
|
OAuthClient.AccessTokenResponse response = getTestToken("password", totpSecret);
|
||||||
|
|
Loading…
Reference in a new issue