brute force protection
This commit is contained in:
1 parent
d8a3025ea1
commit
d58870545f
27 files changed
+987
-173
No files matched your search
@@ -33,6 +33,10 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
||||
|
||||
void setRememberMe(boolean rememberMe);
|
||||
|
||||
boolean isBruteForceProtected();
|
||||
|
||||
void setBruteForceProtected(boolean value);
|
||||
|
||||
boolean isVerifyEmail();
|
||||
|
||||
void setVerifyEmail(boolean verifyEmail);
|
||||
@@ -148,6 +152,9 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
||||
|
||||
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin);
|
||||
|
||||
public UsernameLoginFailureModel getUserLoginFailure(String username);
|
||||
UsernameLoginFailureModel addUserLoginFailure(String username);
|
||||
|
||||
List<UserModel> getUsers();
|
||||
|
||||
List<UserModel> searchForUser(String search);
|
||||
|
||||
@@ -58,6 +58,7 @@ public interface UserModel {
|
||||
int getNotBefore();
|
||||
void setNotBefore(int notBefore);
|
||||
|
||||
|
||||
public static enum RequiredAction {
|
||||
VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.keycloak.models;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface UsernameLoginFailureModel
|
||||
{
|
||||
String getUsername();
|
||||
int getFailedLoginNotBefore();
|
||||
void setFailedLoginNotBefore(int notBefore);
|
||||
int getNumFailures();
|
||||
void incrementFailures();
|
||||
void clearFailures();
|
||||
long getLastFailure();
|
||||
void setLastFailure(long lastFailure);
|
||||
String getLastIPFailure();
|
||||
void setLastIPFailure(String ip);
|
||||
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import org.keycloak.models.AuthenticationLinkModel;
|
||||
import org.keycloak.models.AuthenticationProviderModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.UsernameLoginFailureModel;
|
||||
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
||||
import org.keycloak.models.jpa.entities.ApplicationRoleEntity;
|
||||
import org.keycloak.models.jpa.entities.AuthenticationLinkEntity;
|
||||
@@ -18,6 +19,7 @@ import org.keycloak.models.jpa.entities.ScopeMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.SocialLinkEntity;
|
||||
import org.keycloak.models.jpa.entities.UserEntity;
|
||||
import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.UsernameLoginFailureEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
@@ -122,6 +124,16 @@ public class RealmAdapter implements RealmModel {
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBruteForceProtected() {
|
||||
return realm.isBruteForceProtected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBruteForceProtected(boolean value) {
|
||||
realm.setBruteForceProtected(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVerifyEmail() {
|
||||
return realm.isVerifyEmail();
|
||||
@@ -339,6 +351,27 @@ public class RealmAdapter implements RealmModel {
|
||||
return new UserAdapter(results.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsernameLoginFailureModel getUserLoginFailure(String username) {
|
||||
String id = username + "-" + realm.getId();
|
||||
UsernameLoginFailureEntity entity = em.find(UsernameLoginFailureEntity.class, id);
|
||||
if (entity == null) return null;
|
||||
return new UsernameLoginFailureAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsernameLoginFailureModel addUserLoginFailure(String username) {
|
||||
UsernameLoginFailureModel model = getUserLoginFailure(username);
|
||||
if (model != null) return model;
|
||||
String id = username + "-" + realm.getId();
|
||||
UsernameLoginFailureEntity entity = new UsernameLoginFailureEntity();
|
||||
entity.setId(id);
|
||||
entity.setUsername(username);
|
||||
entity.setRealm(realm);
|
||||
em.persist(entity);
|
||||
return new UsernameLoginFailureAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUserByEmail(String email) {
|
||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByEmail", UserEntity.class);
|
||||
@@ -359,6 +392,9 @@ public class RealmAdapter implements RealmModel {
|
||||
|
||||
@Override
|
||||
public UserModel addUser(String username) {
|
||||
if (getUser(username) != null) {
|
||||
throw new RuntimeException("Username already exists: " + username);
|
||||
}
|
||||
UserEntity entity = new UserEntity();
|
||||
entity.setLoginName(username);
|
||||
entity.setRealm(realm);
|
||||
|
||||
@@ -154,4 +154,7 @@ public class UserAdapter implements UserModel {
|
||||
public void setNotBefore(int notBefore) {
|
||||
user.setNotBefore(notBefore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.UsernameLoginFailureModel;
|
||||
import org.keycloak.models.jpa.entities.UsernameLoginFailureEntity;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UsernameLoginFailureAdapter implements UsernameLoginFailureModel
|
||||
{
|
||||
protected UsernameLoginFailureEntity user;
|
||||
|
||||
public UsernameLoginFailureAdapter(UsernameLoginFailureEntity user)
|
||||
{
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername()
|
||||
{
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFailedLoginNotBefore() {
|
||||
return user.getFailedLoginNotBefore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFailedLoginNotBefore(int notBefore) {
|
||||
user.setFailedLoginNotBefore(notBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFailures() {
|
||||
return user.getNumFailures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementFailures() {
|
||||
user.setNumFailures(getNumFailures() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFailures() {
|
||||
user.setNumFailures(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastFailure() {
|
||||
return user.getLastFailure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastFailure(long lastFailure) {
|
||||
user.setLastFailure(lastFailure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastIPFailure() {
|
||||
return user.getLastIPFailure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastIPFailure(String ip) {
|
||||
user.setLastIPFailure(ip);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ public class RealmEntity {
|
||||
protected boolean resetPasswordAllowed;
|
||||
protected boolean social;
|
||||
protected boolean rememberMe;
|
||||
protected boolean bruteForceProtected;
|
||||
|
||||
@Column(name="updateProfileOnInitSocLogin")
|
||||
protected boolean updateProfileOnInitialSocialLogin;
|
||||
@@ -333,5 +334,13 @@ public class RealmEntity {
|
||||
public void setNotBefore(int notBefore) {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public boolean isBruteForceProtected() {
|
||||
return bruteForceProtected;
|
||||
}
|
||||
|
||||
public void setBruteForceProtected(boolean bruteForceProtected) {
|
||||
this.bruteForceProtected = bruteForceProtected;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public class UserEntity {
|
||||
protected boolean emailVerified;
|
||||
protected int notBefore;
|
||||
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class UsernameLoginFailureEntity {
|
||||
// we manually set the id to be username-realmid
|
||||
// we may have a concurrent creation of the same login failure entry that we want to avoid
|
||||
@Id
|
||||
protected String id;
|
||||
protected String username;
|
||||
protected int failedLoginNotBefore;
|
||||
protected int numFailures;
|
||||
protected long lastFailure;
|
||||
protected String lastIPFailure;
|
||||
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public int getFailedLoginNotBefore() {
|
||||
return failedLoginNotBefore;
|
||||
}
|
||||
|
||||
public void setFailedLoginNotBefore(int failedLoginNotBefore) {
|
||||
this.failedLoginNotBefore = failedLoginNotBefore;
|
||||
}
|
||||
|
||||
public int getNumFailures() {
|
||||
return numFailures;
|
||||
}
|
||||
|
||||
public void setNumFailures(int numFailures) {
|
||||
this.numFailures = numFailures;
|
||||
}
|
||||
|
||||
public long getLastFailure() {
|
||||
return lastFailure;
|
||||
}
|
||||
|
||||
public void setLastFailure(long lastFailure) {
|
||||
this.lastFailure = lastFailure;
|
||||
}
|
||||
|
||||
public String getLastIPFailure() {
|
||||
return lastIPFailure;
|
||||
}
|
||||
|
||||
public void setLastIPFailure(String lastIPFailure) {
|
||||
this.lastIPFailure = lastIPFailure;
|
||||
}
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
}
|
||||
+42
@@ -26,6 +26,7 @@ import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UsernameLoginFailureEntity;
|
||||
import org.keycloak.models.mongo.utils.MongoModelUtils;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
|
||||
@@ -122,6 +123,15 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBruteForceProtected() {
|
||||
return realm.isBruteForceProtected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBruteForceProtected(boolean value) {
|
||||
realm.setBruteForceProtected(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVerifyEmail() {
|
||||
@@ -339,6 +349,38 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsernameLoginFailureAdapter getUserLoginFailure(String name) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("username").is(name)
|
||||
.and("realmId").is(getId())
|
||||
.get();
|
||||
UsernameLoginFailureEntity user = getMongoStore().loadSingleEntity(UsernameLoginFailureEntity.class, query, invocationContext);
|
||||
|
||||
if (user == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new UsernameLoginFailureAdapter(invocationContext, user);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsernameLoginFailureAdapter addUserLoginFailure(String username) {
|
||||
UsernameLoginFailureAdapter userLoginFailure = getUserLoginFailure(username);
|
||||
if (userLoginFailure != null) {
|
||||
return userLoginFailure;
|
||||
}
|
||||
|
||||
UsernameLoginFailureEntity userEntity = new UsernameLoginFailureEntity();
|
||||
userEntity.setUsername(username);
|
||||
// Compatibility with JPA model, which has user disabled by default
|
||||
// userEntity.setEnabled(true);
|
||||
userEntity.setRealmId(getId());
|
||||
|
||||
getMongoStore().insertEntity(userEntity, invocationContext);
|
||||
return new UsernameLoginFailureAdapter(invocationContext, userEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUserByEmail(String email) {
|
||||
DBObject query = new QueryBuilder()
|
||||
|
||||
@@ -170,4 +170,7 @@ public class UserAdapter extends AbstractMongoAdapter<UserEntity> implements Use
|
||||
public UserEntity getMongoEntity() {
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package org.keycloak.models.mongo.keycloak.adapters;
|
||||
|
||||
import org.keycloak.models.UsernameLoginFailureModel;
|
||||
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UsernameLoginFailureEntity;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UsernameLoginFailureAdapter extends AbstractMongoAdapter<UsernameLoginFailureEntity> implements UsernameLoginFailureModel {
|
||||
protected UsernameLoginFailureEntity user;
|
||||
|
||||
public UsernameLoginFailureAdapter(MongoStoreInvocationContext invocationContext, UsernameLoginFailureEntity user) {
|
||||
super(invocationContext);
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UsernameLoginFailureEntity getMongoEntity() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFailedLoginNotBefore() {
|
||||
return user.getFailedLoginNotBefore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFailedLoginNotBefore(int notBefore) {
|
||||
user.setFailedLoginNotBefore(notBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumFailures() {
|
||||
return user.getNumFailures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementFailures() {
|
||||
user.setNumFailures(getNumFailures() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFailures() {
|
||||
user.setNumFailures(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastFailure() {
|
||||
return user.getLastFailure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastFailure(long lastFailure) {
|
||||
user.setLastFailure(lastFailure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastIPFailure() {
|
||||
return user.getLastIPFailure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastIPFailure(String ip) {
|
||||
user.setLastIPFailure(ip);
|
||||
}}
|
||||
+10
@@ -29,6 +29,7 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
|
||||
private boolean social;
|
||||
private boolean updateProfileOnInitialSocialLogin;
|
||||
private String passwordPolicy;
|
||||
private boolean bruteForceProtected;
|
||||
|
||||
private int centralLoginLifespan;
|
||||
private int accessTokenLifespan;
|
||||
@@ -134,6 +135,15 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
|
||||
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public boolean isBruteForceProtected() {
|
||||
return bruteForceProtected;
|
||||
}
|
||||
|
||||
public void setBruteForceProtected(boolean bruteForceProtected) {
|
||||
this.bruteForceProtected = bruteForceProtected;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public String getPasswordPolicy() {
|
||||
return passwordPolicy;
|
||||
|
||||
@@ -24,6 +24,11 @@ public class UserEntity extends AbstractMongoIdentifiableEntity implements Mongo
|
||||
private boolean totp;
|
||||
private boolean enabled;
|
||||
private int notBefore;
|
||||
private int failedLoginNotBefore;
|
||||
private int numFailures;
|
||||
private long lastFailure;
|
||||
private String lastIPFailure;
|
||||
|
||||
|
||||
private String realmId;
|
||||
|
||||
@@ -170,4 +175,41 @@ public class UserEntity extends AbstractMongoIdentifiableEntity implements Mongo
|
||||
public void setAuthenticationLinks(List<AuthenticationLinkEntity> authenticationLinks) {
|
||||
this.authenticationLinks = authenticationLinks;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public int getFailedLoginNotBefore() {
|
||||
return failedLoginNotBefore;
|
||||
}
|
||||
|
||||
public void setFailedLoginNotBefore(int failedLoginNotBefore) {
|
||||
this.failedLoginNotBefore = failedLoginNotBefore;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public int getNumFailures() {
|
||||
return numFailures;
|
||||
}
|
||||
|
||||
public void setNumFailures(int numFailures) {
|
||||
this.numFailures = numFailures;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public long getLastFailure() {
|
||||
return lastFailure;
|
||||
}
|
||||
|
||||
public void setLastFailure(long lastFailure) {
|
||||
this.lastFailure = lastFailure;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public String getLastIPFailure() {
|
||||
return lastIPFailure;
|
||||
}
|
||||
|
||||
public void setLastIPFailure(String lastIPFailure) {
|
||||
this.lastIPFailure = lastIPFailure;
|
||||
}
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package org.keycloak.models.mongo.keycloak.entities;
|
||||
|
||||
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
|
||||
import org.keycloak.models.mongo.api.MongoCollection;
|
||||
import org.keycloak.models.mongo.api.MongoEntity;
|
||||
import org.keycloak.models.mongo.api.MongoField;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@MongoCollection(collectionName = "userFailures")
|
||||
public class UsernameLoginFailureEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
|
||||
private String username;
|
||||
private int failedLoginNotBefore;
|
||||
private int numFailures;
|
||||
private long lastFailure;
|
||||
private String lastIPFailure;
|
||||
|
||||
|
||||
private String realmId;
|
||||
|
||||
@MongoField
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public int getFailedLoginNotBefore() {
|
||||
return failedLoginNotBefore;
|
||||
}
|
||||
|
||||
public void setFailedLoginNotBefore(int failedLoginNotBefore) {
|
||||
this.failedLoginNotBefore = failedLoginNotBefore;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public int getNumFailures() {
|
||||
return numFailures;
|
||||
}
|
||||
|
||||
public void setNumFailures(int numFailures) {
|
||||
this.numFailures = numFailures;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public long getLastFailure() {
|
||||
return lastFailure;
|
||||
}
|
||||
|
||||
public void setLastFailure(long lastFailure) {
|
||||
this.lastFailure = lastFailure;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public String getLastIPFailure() {
|
||||
return lastIPFailure;
|
||||
}
|
||||
|
||||
public void setLastIPFailure(String lastIPFailure) {
|
||||
this.lastIPFailure = lastIPFailure;
|
||||
}
|
||||
|
||||
@MongoField
|
||||
public String getRealmId() {
|
||||
return realmId;
|
||||
}
|
||||
|
||||
public void setRealmId(String realmId) {
|
||||
this.realmId = realmId;
|
||||
}
|
||||
}
|
||||
Regular → Executable
+7
-7
@@ -70,10 +70,10 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
|
||||
MultivaluedMap<String, String> formData = createFormData("john", "password");
|
||||
|
||||
// Authenticate user with realm1
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm1, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm1, formData));
|
||||
|
||||
// Verify that user doesn't exists in realm2 and can't authenticate here
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(realm2, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(null, realm2, formData));
|
||||
Assert.assertNull(realm2.getUser("john"));
|
||||
|
||||
// Add externalModel authenticationProvider into realm2 and point to realm1
|
||||
@@ -84,7 +84,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
|
||||
ResteasyProviderFactory.pushContext(KeycloakSession.class, identitySession);
|
||||
|
||||
// Authenticate john in realm2 and verify that now he exists here.
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm2, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm2, formData));
|
||||
UserModel john2 = realm2.getUser("john");
|
||||
Assert.assertNotNull(john2);
|
||||
Assert.assertEquals("john", john2.getLoginName());
|
||||
@@ -121,8 +121,8 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
|
||||
Assert.fail("Error not expected");
|
||||
}
|
||||
MultivaluedMap<String, String> formData = createFormData("john", "password-updated");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm1, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm2, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm1, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm2, formData));
|
||||
|
||||
|
||||
// Switch to disallow password update propagation to realm1
|
||||
@@ -136,8 +136,8 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
|
||||
Assert.fail("Error not expected");
|
||||
}
|
||||
formData = createFormData("john", "password-updated2");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(realm1, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm2, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm1, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm2, formData));
|
||||
|
||||
|
||||
// Allow passwordUpdate propagation again
|
||||
|
||||
Regular → Executable
+8
-8
@@ -79,14 +79,14 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
|
||||
LdapTestUtils.setLdapPassword(realm, "john", "password");
|
||||
|
||||
// Verify that user doesn't exists in realm2 and can't authenticate here
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(null, realm, formData));
|
||||
Assert.assertNull(realm.getUser("john"));
|
||||
|
||||
// Add ldap authenticationProvider
|
||||
setupAuthenticationProviders();
|
||||
|
||||
// Authenticate john and verify that now he exists in realm
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm, formData));
|
||||
UserModel john = realm.getUser("john");
|
||||
Assert.assertNotNull(john);
|
||||
Assert.assertEquals("john", john.getLoginName());
|
||||
@@ -121,20 +121,20 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
|
||||
|
||||
// User doesn't exists
|
||||
MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("invalid", "invalid");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(null, realm, formData));
|
||||
|
||||
// User exists in ldap
|
||||
formData = AuthProvidersExternalModelTest.createFormData("john", "invalid");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm, formData));
|
||||
|
||||
// User exists in realm
|
||||
formData = AuthProvidersExternalModelTest.createFormData("realmUser", "invalid");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm, formData));
|
||||
|
||||
// User disabled
|
||||
realmUser.setEnabled(false);
|
||||
formData = AuthProvidersExternalModelTest.createFormData("realmUser", "pass");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.ACCOUNT_DISABLED, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.ACCOUNT_DISABLED, am.authenticateForm(null, realm, formData));
|
||||
} finally {
|
||||
ResteasyProviderFactory.clearContextData();
|
||||
}
|
||||
@@ -158,7 +158,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
|
||||
Assert.fail("Error not expected");
|
||||
}
|
||||
MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("john", "password-updated");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm, formData));
|
||||
|
||||
// Password updated just in LDAP, so validating directly in realm should fail
|
||||
Assert.assertFalse(realm.validatePassword(realm.getUser("john"), "password-updated"));
|
||||
@@ -174,7 +174,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
|
||||
Assert.fail("Error not expected");
|
||||
}
|
||||
formData = AuthProvidersExternalModelTest.createFormData("john", "password-updated2");
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(realm, formData));
|
||||
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm, formData));
|
||||
} finally {
|
||||
ResteasyProviderFactory.clearContextData();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
|
||||
@Test
|
||||
public void authForm() {
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
formData.remove(CredentialRepresentation.PASSWORD);
|
||||
formData.add(CredentialRepresentation.PASSWORD, "invalid");
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
public void authFormMissingUsername() {
|
||||
formData.remove("username");
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.INVALID_USER, status);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
public void authFormMissingPassword() {
|
||||
formData.remove(CredentialRepresentation.PASSWORD);
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
realm.addRequiredCredential(CredentialRepresentation.TOTP);
|
||||
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
public void authFormUserDisabled() {
|
||||
user.setEnabled(false);
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
|
||||
formData.add(CredentialRepresentation.TOTP, token);
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
formData.remove(CredentialRepresentation.PASSWORD);
|
||||
formData.add(CredentialRepresentation.PASSWORD, "invalid");
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
formData.remove(CredentialRepresentation.TOTP);
|
||||
formData.add(CredentialRepresentation.TOTP, "invalid");
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
|
||||
|
||||
formData.remove(CredentialRepresentation.TOTP);
|
||||
|
||||
AuthenticationStatus status = am.authenticateForm(realm, formData);
|
||||
AuthenticationStatus status = am.authenticateForm(null, realm, formData);
|
||||
Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user