remove AuthenticationProvider/Link

This commit is contained in:
Bill Burke
2014-08-01 18:03:48 -04:00
parent c9851f1c05
commit 101a72cd65
90 changed files with 62 additions and 3341 deletions

View File

@@ -1,48 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-authentication-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-authentication-api</artifactId>
<name>Keycloak Authentication SPI</name>
<description />
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,15 +0,0 @@
package org.keycloak.authentication;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthProviderConstants {
// Model is default provider. See AuthenticationProviderModel.DEFAULT_PROVIDER
public static final String PROVIDER_NAME_MODEL = "model";
public static final String PROVIDER_NAME_EXTERNAL_MODEL = "externalModel";
public static final String PROVIDER_NAME_PICKETLINK = "picketlink";
// Used in external-model provider
public static final String EXTERNAL_REALM_ID = "externalRealmId";
}

View File

@@ -1,12 +0,0 @@
package org.keycloak.authentication;
/**
* Result of authentication by AuthenticationProvider
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public enum AuthProviderStatus {
SUCCESS, INVALID_CREDENTIALS, FAILED
}

View File

@@ -1,83 +0,0 @@
package org.keycloak.authentication;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthUser {
private String id;
private String username;
private String firstName;
private String lastName;
private String email;
private String providerName;
public AuthUser(String id, String username, String providerName) {
this.id = id;
this.username = username;
this.providerName = providerName;
}
public String getId() {
return id;
}
public AuthUser setId(String id) {
this.id = id;
return this;
}
public String getUsername() {
return username;
}
public AuthUser setUsername(String username) {
this.username = username;
return this;
}
public String getFirstName() {
return firstName;
}
public AuthUser setName(String name) {
int i = name.lastIndexOf(' ');
if (i != -1) {
firstName = name.substring(0, i);
lastName = name.substring(i + 1);
} else {
firstName = name;
}
return this;
}
public AuthUser setName(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
return this;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public AuthUser setEmail(String email) {
this.email = email;
return this;
}
public String getProviderName() {
return providerName;
}
public AuthUser setProviderName(String providerName) {
this.providerName = providerName;
return this;
}
}

View File

@@ -1,69 +0,0 @@
package org.keycloak.authentication;
import java.util.List;
import java.util.Map;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.provider.Provider;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface AuthenticationProvider extends Provider {
String getName();
/**
* Get names of all available configuration options of current provider
*
* @return options or empty list if no options available
*/
List<String> getAvailableOptions();
/**
* Get user by given username or email. Return user instance or null if user doesn't exists in this authentication provider
*
* @param realm
* @param configuration
* @param username or email
* @return found user or null if user with given username doesn't exists
* @throws AuthenticationProviderException
*/
AuthUser getUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException;
/**
* Try to register user with this authentication provider
*
* @param realm
* @param configuration
* @param user Keycloak user, which will be registered on authentication provider side
* @return ID of newly created user (For example ID from LDAP)
* @throws AuthenticationProviderException if user creation couldn't happen
*/
String registerUser(RealmModel realm, Map<String, String> configuration, UserModel user) throws AuthenticationProviderException;
/**
* Standard Authentication flow
*
* @param username
* @param password
* @return result of authentication, which might eventually encapsulate info about authenticated user and provider which successfully authenticated
*/
AuthProviderStatus validatePassword(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException;
/**
* Update credential
*
* @param realm
* @param configuration
* @param username
* @param password
* @return true if credential has been successfully updated
* @throws AuthenticationProviderException
*/
boolean updateCredential(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException;
}

View File

@@ -1,24 +0,0 @@
package org.keycloak.authentication;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationProviderException extends Exception {
private static final long serialVersionUID = 15L;
protected AuthenticationProviderException() {
}
public AuthenticationProviderException(String message) {
super(message);
}
public AuthenticationProviderException(Throwable cause) {
super(cause);
}
public AuthenticationProviderException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,9 +0,0 @@
package org.keycloak.authentication;
import org.keycloak.provider.ProviderFactory;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface AuthenticationProviderFactory extends ProviderFactory<AuthenticationProvider> {
}

View File

@@ -1,218 +0,0 @@
package org.keycloak.authentication;
import org.jboss.logging.Logger;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Access point to authentication SPI. It finds configured and available {@link AuthenticationProvider} instances for current realm
* and then delegates method call to them.
*
* Example of usage: AuthenticationProviderManager.getManager(realm).validateUser("joe", "password");
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationProviderManager {
private static final Logger logger = Logger.getLogger(AuthenticationProviderManager.class);
private final RealmModel realm;
private final Map<String, AuthenticationProvider> delegates;
public static AuthenticationProviderManager getManager(RealmModel realm, KeycloakSession session) {
Iterable<AuthenticationProvider> providers = session.getAllProviders(AuthenticationProvider.class);
Map<String, AuthenticationProvider> providersMap = new HashMap<String, AuthenticationProvider>();
for (AuthenticationProvider provider : providers) {
providersMap.put(provider.getName(), provider);
}
return new AuthenticationProviderManager(realm, providersMap);
}
public AuthenticationProviderManager(RealmModel realm, Map<String, AuthenticationProvider> delegates) {
this.realm = realm;
this.delegates = delegates;
}
public AuthUser getUser(String username) {
List<AuthenticationProviderModel> authProviderModels = getConfiguredProviderModels(realm);
for (AuthenticationProviderModel providerModel : authProviderModels) {
AuthenticationProvider delegate = getProvider(providerModel.getProviderName());
if (delegate == null) {
continue;
}
try {
AuthUser authUser = delegate.getUser(realm, providerModel.getConfig(), username);
if (authUser != null) {
logger.debugf("User '%s' found with provider '%s'", username, providerModel.getProviderName());
return authUser;
}
} catch (AuthenticationProviderException ape) {
logger.warn(ape.getMessage(), ape);
}
}
logger.debugf("User '%s' not found with any provider", username);
return null;
}
public AuthProviderStatus validatePassword(UserModel user, String password) {
AuthenticationLinkModel authLink = user.getAuthenticationLink();
if (authLink == null) {
// User not yet linked with any authenticationProvider. Find provider with biggest priority where he is and link
AuthUser authUser = getUser(user.getUsername());
authLink = new AuthenticationLinkModel(authUser.getProviderName(), authUser.getId());
user.setAuthenticationLink(authLink);
logger.infof("User '%s' linked with provider '%s'", authUser.getUsername(), authUser.getProviderName());
}
String providerName = authLink.getAuthProvider();
AuthenticationProviderModel providerModel = getConfiguredProviderModel(realm, providerName);
AuthenticationProvider delegate = getProvider(providerName);
if (delegate == null || providerModel == null) {
return AuthProviderStatus.FAILED;
}
try {
checkCorrectAuthLink(delegate, providerModel, authLink, user.getUsername());
AuthProviderStatus currentResult = delegate.validatePassword(realm, providerModel.getConfig(), user.getUsername(), password);
logger.debugf("Authentication provider '%s' finished with '%s' for authentication of '%s'", delegate.getName(), currentResult.toString(), user.getUsername());
return currentResult;
} catch (AuthenticationProviderException ape) {
logger.warn(ape.getMessage(), ape);
return AuthProviderStatus.FAILED;
}
}
public boolean updatePassword(UserModel user, String password) throws AuthenticationProviderException {
AuthenticationLinkModel authLink = user.getAuthenticationLink();
if (authLink == null) {
// Find provider with biggest priority where password update is supported. Then register user here and link him
List<AuthenticationProviderModel> configuredProviders = getConfiguredProviderModels(realm);
for (AuthenticationProviderModel providerModel : configuredProviders) {
if (providerModel.isPasswordUpdateSupported()) {
AuthenticationProvider delegate = getProvider(providerModel.getProviderName());
if (delegate != null) {
AuthUser authUser = delegate.getUser(realm, providerModel.getConfig(), user.getUsername());
if (authUser != null) {
// Linking existing user supported just for "model" provider. In other cases throw exception
if (providerModel.getProviderName().equals(AuthenticationProviderModel.DEFAULT_PROVIDER.getProviderName())) {
authLink = new AuthenticationLinkModel(providerModel.getProviderName(), authUser.getId());
user.setAuthenticationLink(authLink);
logger.infof("User '%s' linked with provider '%s'", authUser.getUsername(), authUser.getProviderName());
} else {
throw new AuthenticationProviderException("User " + authUser.getUsername() + " exists in provider "
+ authUser.getProviderName() + " but is not linked with model user");
}
} else {
String userIdInProvider = delegate.registerUser(realm, providerModel.getConfig(), user);
authLink = new AuthenticationLinkModel(providerModel.getProviderName(), userIdInProvider);
user.setAuthenticationLink(authLink);
logger.infof("User '%s' registered in provider '%s' and linked", user.getUsername(), providerModel.getProviderName());
}
break;
}
}
}
if (authLink == null) {
logger.warnf("No providers found where password update is supported for user '%s'", user.getUsername());
return false;
}
}
String providerName = authLink.getAuthProvider();
AuthenticationProviderModel providerModel = getConfiguredProviderModel(realm, providerName);
if (providerModel == null) {
return false;
}
String username = user.getUsername();
// Update just if password update is supported
if (providerModel.isPasswordUpdateSupported()) {
try {
AuthenticationProvider delegate = getProvider(providerName);
if (delegate == null) {
return false;
}
checkCorrectAuthLink(delegate, providerModel, authLink, username);
if (delegate.updateCredential(realm,providerModel.getConfig(), user.getUsername(), password)) {
logger.debugf("Updated password in authentication provider '%s' for user '%s'", providerName, username);
return true;
} else {
logger.warnf("Password not updated in authentication provider '%s' for user '%s'", providerName, username);
return false;
}
} catch (AuthenticationProviderException ape) {
// Rethrow it to upper layer
logger.warn("Failed to update password: " + ape.getMessage());
throw ape;
}
} else {
logger.warnf("Skip password update for authentication provider '%s' for user '%s'", providerName, username);
return false;
}
}
private AuthenticationProvider getProvider(String providerName) {
AuthenticationProvider delegate = delegates.get(providerName);
if (delegate == null) {
logger.warnf("Provider '%s' not available on classpath", providerName);
}
return delegate;
}
private static List<AuthenticationProviderModel> getConfiguredProviderModels(RealmModel realm) {
List<AuthenticationProviderModel> configuredProviders = realm.getAuthenticationProviders();
// Use model based authentication of current realm by default
if (configuredProviders == null || configuredProviders.isEmpty()) {
configuredProviders = Collections.EMPTY_LIST;
logger.warnf("No authentication providers found");
}
return configuredProviders;
}
public static AuthenticationProviderModel getConfiguredProviderModel(RealmModel realm, String providerName) {
List<AuthenticationProviderModel> providers = getConfiguredProviderModels(realm);
for (AuthenticationProviderModel provider : providers) {
if (providerName.equals(provider.getProviderName())) {
return provider;
}
}
logger.warnf("Provider '%s' not configured in realm", providerName);
return null;
}
// Check if ID of linked AuthUser is same as expected ID from authenticationLink . It should catch the case when for example user "john" was deleted in LDAP
// and then user "john" has been created again, but it's actually different user with different ID
private void checkCorrectAuthLink(AuthenticationProvider authProvider, AuthenticationProviderModel providerModel,
AuthenticationLinkModel authLinkModel, String username) throws AuthenticationProviderException {
AuthUser authUser = authProvider.getUser(realm, providerModel.getConfig(), username);
if (authUser == null) {
throw new AuthenticationProviderException("User " + username + " not found in authentication provider " + providerModel.getProviderName());
}
String userExternalId = authUser.getId();
if (!userExternalId.equals(authLinkModel.getAuthUserId())) {
throw new AuthenticationProviderException("ID did not match! ID from provider: " + userExternalId + ", ID from authentication link: " + authLinkModel.getAuthUserId());
}
}
}

View File

@@ -1,27 +0,0 @@
package org.keycloak.authentication;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AuthenticationSpi implements Spi {
@Override
public String getName() {
return "authentication";
}
@Override
public Class<? extends Provider> getProviderClass() {
return AuthenticationProvider.class;
}
@Override
public Class<? extends ProviderFactory> getProviderFactoryClass() {
return AuthenticationProviderFactory.class;
}
}

View File

@@ -1 +0,0 @@
org.keycloak.authentication.AuthenticationSpi

View File

@@ -1,74 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-authentication-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-authentication-model</artifactId>
<name>Keycloak Authentication Model Based</name>
<description />
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,94 +0,0 @@
package org.keycloak.authentication.model;
import java.util.Map;
import org.jboss.logging.Logger;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.authentication.AuthProviderStatus;
import org.keycloak.authentication.AuthUser;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.authentication.AuthenticationProviderException;
/**
* Authentication provider, which delegates calling of all methods to specified realm
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public abstract class AbstractModelAuthenticationProvider implements AuthenticationProvider {
private static final Logger logger = Logger.getLogger(AbstractModelAuthenticationProvider.class);
protected KeycloakSession keycloakSession;
protected AbstractModelAuthenticationProvider(KeycloakSession keycloakSession) {
this.keycloakSession = keycloakSession;
}
@Override
public AuthUser getUser(RealmModel currentRealm, Map<String, String> config, String username) throws AuthenticationProviderException {
RealmModel realm = getRealm(currentRealm, config);
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
return user == null ? null : createAuthenticatedUserInstance(user);
}
@Override
public String registerUser(RealmModel currentRealm, Map<String, String> config, UserModel user) throws AuthenticationProviderException {
RealmModel realm = getRealm(currentRealm, config);
UserModel newUser = keycloakSession.users().addUser(realm, user.getUsername());
newUser.setFirstName(user.getFirstName());
newUser.setLastName(user.getLastName());
newUser.setEmail(user.getEmail());
newUser.setEnabled(true);
return newUser.getId();
}
@Override
public AuthProviderStatus validatePassword(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
RealmModel realm = getRealm(currentRealm, config);
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
boolean result = keycloakSession.users().validCredentials(realm, user, UserCredentialModel.password(password));
return result ? AuthProviderStatus.SUCCESS : AuthProviderStatus.INVALID_CREDENTIALS;
}
@Override
public boolean updateCredential(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
RealmModel realm = getRealm(currentRealm, config);
// Validate password policy
String error = realm.getPasswordPolicy().validate(password);
if (error != null) {
throw new AuthenticationProviderException(error);
}
UserModel user = keycloakSession.users().getUserByUsername(username, realm);
if (user == null) {
logger.warnf("User '%s' doesn't exists. Skip password update", username);
return false;
}
UserCredentialModel cred = new UserCredentialModel();
cred.setType(CredentialRepresentation.PASSWORD);
cred.setValue(password);
user.updateCredential(cred);
return true;
}
@Override
public void close() {
}
protected abstract RealmModel getRealm(RealmModel currentRealm, Map<String, String> config) throws AuthenticationProviderException;
protected AuthUser createAuthenticatedUserInstance(UserModel user) {
return new AuthUser(user.getId(), user.getUsername(), getName())
.setName(user.getFirstName(), user.getLastName())
.setEmail(user.getEmail());
}
}

View File

@@ -1,47 +0,0 @@
package org.keycloak.authentication.model;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* AbstractModelAuthenticationProvider, which delegates authentication operations to different (external) realm
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ExternalModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
public ExternalModelAuthenticationProvider(KeycloakSession session) {
super(session);
}
@Override
public String getName() {
return AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL;
}
@Override
public List<String> getAvailableOptions() {
return Arrays.asList(AuthProviderConstants.EXTERNAL_REALM_ID);
}
@Override
public RealmModel getRealm(RealmModel currentRealm, Map<String, String> configuration) throws AuthenticationProviderException {
String realmId = configuration.get(AuthProviderConstants.EXTERNAL_REALM_ID);
if (realmId == null) {
throw new AuthenticationProviderException("Option '" + AuthProviderConstants.EXTERNAL_REALM_ID + "' not specified in configuration");
}
RealmModel realm = keycloakSession.realms().getRealm(realmId);
if (realm == null) {
throw new AuthenticationProviderException("Realm with id '" + realmId + "' doesn't exists");
}
return realm;
}
}

View File

@@ -1,32 +0,0 @@
package org.keycloak.authentication.model;
import org.keycloak.Config;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.authentication.AuthenticationProviderFactory;
import org.keycloak.models.KeycloakSession;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ExternalModelAuthenticationProviderFactory implements AuthenticationProviderFactory {
@Override
public AuthenticationProvider create(KeycloakSession session) {
return new ExternalModelAuthenticationProvider(session);
}
@Override
public void init(Config.Scope config) {
}
@Override
public void close() {
}
@Override
public String getId() {
return AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL;
}
}

View File

@@ -1,36 +0,0 @@
package org.keycloak.authentication.model;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.authentication.AuthProviderConstants;
/**
* AbstractModelAuthenticationProvider, which uses current realm to call operations on
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
public ModelAuthenticationProvider(KeycloakSession keycloakSession) {
super(keycloakSession);
}
@Override
public String getName() {
return AuthProviderConstants.PROVIDER_NAME_MODEL;
}
@Override
public List<String> getAvailableOptions() {
return Collections.EMPTY_LIST;
}
@Override
protected RealmModel getRealm(RealmModel currentRealm, Map<String, String> config) {
return currentRealm;
}
}

View File

@@ -1,32 +0,0 @@
package org.keycloak.authentication.model;
import org.keycloak.Config;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.authentication.AuthenticationProviderFactory;
import org.keycloak.models.KeycloakSession;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ModelAuthenticationProviderFactory implements AuthenticationProviderFactory {
@Override
public AuthenticationProvider create(KeycloakSession session) {
return new ModelAuthenticationProvider(session);
}
@Override
public void init(Config.Scope config) {
}
@Override
public void close() {
}
@Override
public String getId() {
return AuthProviderConstants.PROVIDER_NAME_MODEL;
}
}

View File

@@ -1,2 +0,0 @@
org.keycloak.authentication.model.ModelAuthenticationProviderFactory
org.keycloak.authentication.model.ExternalModelAuthenticationProviderFactory

View File

@@ -1,101 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-authentication-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-authentication-picketlink</artifactId>
<name>Keycloak Authentication Picketlink Based</name>
<description />
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-picketlink-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-idm-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-idm-impl</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-idm-simple-schema</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,140 +0,0 @@
package org.keycloak.authentication.picketlink;
import org.jboss.logging.Logger;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthProviderStatus;
import org.keycloak.authentication.AuthUser;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.picketlink.IdentityManagerProvider;
import org.picketlink.idm.IdentityManagementException;
import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.credential.Credentials;
import org.picketlink.idm.credential.Password;
import org.picketlink.idm.credential.UsernamePasswordCredentials;
import org.picketlink.idm.model.basic.BasicModel;
import org.picketlink.idm.model.basic.User;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* AuthenticationProvider, which delegates authentication to picketlink
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class PicketlinkAuthenticationProvider implements AuthenticationProvider {
private static final Logger logger = Logger.getLogger(PicketlinkAuthenticationProvider.class);
private final IdentityManagerProvider identityManagerProvider;
public PicketlinkAuthenticationProvider(IdentityManagerProvider identityManagerProvider) {
this.identityManagerProvider = identityManagerProvider;
}
@Override
public String getName() {
return AuthProviderConstants.PROVIDER_NAME_PICKETLINK;
}
@Override
public List<String> getAvailableOptions() {
return Collections.EMPTY_LIST;
}
@Override
public AuthUser getUser(RealmModel realm, Map<String, String> configuration, String username) throws AuthenticationProviderException {
IdentityManager identityManager = getIdentityManager(realm);
try {
User picketlinkUser = BasicModel.getUser(identityManager, username);
if (picketlinkUser == null) {
return null;
}
String email = (picketlinkUser.getEmail() != null && picketlinkUser.getEmail().trim().length() > 0) ? picketlinkUser.getEmail() : null;
return new AuthUser(picketlinkUser.getId(), picketlinkUser.getLoginName(), getName())
.setName(picketlinkUser.getFirstName(), picketlinkUser.getLastName())
.setEmail(email)
.setProviderName(getName());
} catch (IdentityManagementException ie) {
throw convertIDMException(ie);
}
}
@Override
public String registerUser(RealmModel realm, Map<String, String> configuration, UserModel user) throws AuthenticationProviderException {
IdentityManager identityManager = getIdentityManager(realm);
try {
User picketlinkUser = new User(user.getUsername());
picketlinkUser.setFirstName(user.getFirstName());
picketlinkUser.setLastName(user.getLastName());
picketlinkUser.setEmail(user.getEmail());
identityManager.add(picketlinkUser);
return picketlinkUser.getId();
} catch (IdentityManagementException ie) {
throw convertIDMException(ie);
}
}
@Override
public AuthProviderStatus validatePassword(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException {
IdentityManager identityManager = getIdentityManager(realm);
try {
UsernamePasswordCredentials credential = new UsernamePasswordCredentials();
credential.setUsername(username);
credential.setPassword(new Password(password.toCharArray()));
identityManager.validateCredentials(credential);
if (credential.getStatus() == Credentials.Status.VALID) {
return AuthProviderStatus.SUCCESS;
} else {
return AuthProviderStatus.INVALID_CREDENTIALS;
}
} catch (IdentityManagementException ie) {
throw convertIDMException(ie);
}
}
@Override
public boolean updateCredential(RealmModel realm, Map<String, String> configuration, String username, String password) throws AuthenticationProviderException {
IdentityManager identityManager = getIdentityManager(realm);
try {
User picketlinkUser = BasicModel.getUser(identityManager, username);
if (picketlinkUser == null) {
logger.debugf("User '%s' doesn't exists. Skip password update", username);
return false;
}
identityManager.updateCredential(picketlinkUser, new Password(password.toCharArray()));
return true;
} catch (IdentityManagementException ie) {
throw convertIDMException(ie);
}
}
@Override
public void close() {
}
public IdentityManager getIdentityManager(RealmModel realm) throws AuthenticationProviderException {
return identityManagerProvider.getIdentityManager(realm);
}
private AuthenticationProviderException convertIDMException(IdentityManagementException ie) {
Throwable realCause = ie;
while (realCause.getCause() != null) {
realCause = realCause.getCause();
}
// Use the message from the realCause
return new AuthenticationProviderException(realCause.getMessage(), ie);
}
}

View File

@@ -1,33 +0,0 @@
package org.keycloak.authentication.picketlink;
import org.keycloak.Config;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.authentication.AuthenticationProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.picketlink.IdentityManagerProvider;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class PicketlinkAuthenticationProviderFactory implements AuthenticationProviderFactory {
@Override
public AuthenticationProvider create(KeycloakSession session) {
return new PicketlinkAuthenticationProvider(session.getProvider(IdentityManagerProvider.class));
}
@Override
public void init(Config.Scope config) {
}
@Override
public void close() {
}
@Override
public String getId() {
return AuthProviderConstants.PROVIDER_NAME_PICKETLINK;
}
}

View File

@@ -1 +0,0 @@
org.keycloak.authentication.picketlink.PicketlinkAuthenticationProviderFactory

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<artifactId>keycloak-authentication-parent</artifactId>
<name>Keycloak Authentication</name>
<description />
<modules>
<module>authentication-api</module>
<module>authentication-model</module>
<module>authentication-picketlink</module>
</modules>
</project>

View File

@@ -8,11 +8,9 @@
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
<class>org.keycloak.models.jpa.entities.AuthenticationProviderEntity</class>
<class>org.keycloak.models.jpa.entities.UserFederationProviderEntity</class>
<class>org.keycloak.models.jpa.entities.RoleEntity</class>
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
<class>org.keycloak.models.jpa.entities.AuthenticationLinkEntity</class>
<class>org.keycloak.models.jpa.entities.UserEntity</class>
<class>org.keycloak.models.jpa.entities.UserRequiredActionEntity</class>
<class>org.keycloak.models.jpa.entities.UserAttributeEntity</class>

View File

@@ -1,26 +0,0 @@
package org.keycloak.representations.idm;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationLinkRepresentation {
private String authProvider;
private String authUserId;
public String getAuthProvider() {
return authProvider;
}
public void setAuthProvider(String authProvider) {
this.authProvider = authProvider;
}
public String getAuthUserId() {
return authUserId;
}
public void setAuthUserId(String authUserId) {
this.authUserId = authUserId;
}
}

View File

@@ -1,56 +0,0 @@
package org.keycloak.representations.idm;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationProviderRepresentation {
private String providerName;
private boolean passwordUpdateSupported = true;
private Map<String, String> config;
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public boolean isPasswordUpdateSupported() {
return passwordUpdateSupported;
}
public void setPasswordUpdateSupported(boolean passwordUpdateSupported) {
this.passwordUpdateSupported = passwordUpdateSupported;
}
public Map<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AuthenticationProviderRepresentation that = (AuthenticationProviderRepresentation) o;
if (passwordUpdateSupported != that.passwordUpdateSupported) return false;
if (config != null ? !config.equals(that.config) : that.config != null) return false;
if (!providerName.equals(that.providerName)) return false;
return true;
}
@Override
public int hashCode() {
return providerName.hashCode();
}
}

View File

@@ -54,8 +54,6 @@ public class RealmRepresentation {
protected List<OAuthClientRepresentation> oauthClients;
protected Map<String, String> socialProviders;
protected Map<String, String> smtpServer;
protected Map<String, String> ldapServer;
protected List<AuthenticationProviderRepresentation> authenticationProviders;
protected List<UserFederationProviderRepresentation> userFederationProviders;
protected String loginTheme;
protected String accountTheme;
@@ -309,22 +307,6 @@ public class RealmRepresentation {
this.smtpServer = smtpServer;
}
public Map<String, String> getLdapServer() {
return ldapServer;
}
public void setLdapServer(Map<String, String> ldapServer) {
this.ldapServer = ldapServer;
}
public List<AuthenticationProviderRepresentation> getAuthenticationProviders() {
return authenticationProviders;
}
public void setAuthenticationProviders(List<AuthenticationProviderRepresentation> authenticationProviders) {
this.authenticationProviders = authenticationProviders;
}
public List<OAuthClientRepresentation> getOauthClients() {
return oauthClients;
}

View File

@@ -20,7 +20,6 @@ public class UserRepresentation {
protected String firstName;
protected String lastName;
protected String email;
protected AuthenticationLinkRepresentation authenticationLink;
protected String federationLink;
protected Map<String, String> attributes;
protected List<CredentialRepresentation> credentials;
@@ -101,14 +100,6 @@ public class UserRepresentation {
this.emailVerified = emailVerified;
}
public AuthenticationLinkRepresentation getAuthenticationLink() {
return authenticationLink;
}
public void setAuthenticationLink(AuthenticationLinkRepresentation authenticationLink) {
this.authenticationLink = authenticationLink;
}
public Map<String, String> getAttributes() {
return attributes;
}

View File

@@ -89,11 +89,6 @@
</dependency>
<!-- authentication api -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-picketlink</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-common</artifactId>
@@ -117,11 +112,6 @@
<artifactId>keycloak-picketlink-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-picketlink-realm</artifactId>
<version>${project.version}</version>
</dependency>
<!-- mongo -->
<dependency>

View File

@@ -112,18 +112,6 @@
<version>${project.version}</version>
</dependency>
<!-- authentication api -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-model</artifactId>
<version>${project.version}</version>
</dependency>
<!-- timer -->
<dependency>
<groupId>org.keycloak</groupId>

View File

@@ -27,6 +27,5 @@
<modules>
<module>audit-listener-sysout</module>
<module>audit-provider-mem</module>
<module>authentication-properties</module>
</modules>
</project>

View File

@@ -2,7 +2,6 @@ package org.keycloak.exportimport.util;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -18,9 +17,7 @@ import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.keycloak.exportimport.Strategy;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
@@ -32,7 +29,6 @@ import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
@@ -255,13 +251,6 @@ public class ExportUtils {
public static UserRepresentation exportUser(KeycloakSession session, RealmModel realm, UserModel user) {
UserRepresentation userRep = ModelToRepresentation.toRepresentation(user);
// AuthenticationLink
AuthenticationLinkModel authLink = user.getAuthenticationLink();
if (authLink != null) {
AuthenticationLinkRepresentation authLinkRepresentation = exportAuthLink(authLink);
userRep.setAuthenticationLink(authLinkRepresentation);
}
// Social links
Set<SocialLinkModel> socialLinks = session.users().getSocialLinks(user, realm);
List<SocialLinkRepresentation> socialLinkReps = new ArrayList<SocialLinkRepresentation>();
@@ -313,13 +302,6 @@ public class ExportUtils {
return userRep;
}
public static AuthenticationLinkRepresentation exportAuthLink(AuthenticationLinkModel authLinkModel) {
AuthenticationLinkRepresentation authLinkRep = new AuthenticationLinkRepresentation();
authLinkRep.setAuthProvider(authLinkModel.getAuthProvider());
authLinkRep.setAuthUserId(authLinkModel.getAuthUserId());
return authLinkRep;
}
public static SocialLinkRepresentation exportSocialLink(SocialLinkModel socialLink) {
SocialLinkRepresentation socialLinkRep = new SocialLinkRepresentation();
socialLinkRep.setSocialProvider(socialLink.getSocialProvider());

View File

@@ -47,7 +47,7 @@ public class PartitionManagerRegistry {
* @param ldapConfig from realm
* @return PartitionManager instance based on LDAP store
*/
protected PartitionManager createPartitionManager(Map<String,String> ldapConfig) {
public static PartitionManager createPartitionManager(Map<String,String> ldapConfig) {
IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
Properties connectionProps = new Properties();
@@ -114,13 +114,13 @@ public class PartitionManagerRegistry {
return new DefaultPartitionManager(identityConfigs);
}
private void checkSystemProperty(String name, String defaultValue) {
private static void checkSystemProperty(String name, String defaultValue) {
if (System.getProperty(name) == null) {
System.setProperty(name, defaultValue);
}
}
private String getNameOfLDAPAttribute(String systemPropertyName, String defaultAttrName, String defaultAttrNameInActiveDirectory, boolean activeDirectory) {
private static String getNameOfLDAPAttribute(String systemPropertyName, String defaultAttrName, String defaultAttrNameInActiveDirectory, boolean activeDirectory) {
// System property has biggest priority if available
String sysProperty = System.getProperty(systemPropertyName);
if (sysProperty != null) {
@@ -131,7 +131,7 @@ public class PartitionManagerRegistry {
}
// Parse array of strings like [ "inetOrgPerson", "organizationalPerson" ] from the string like: "inetOrgPerson, organizationalPerson"
private String[] getUserObjectClasses(Map<String,String> ldapConfig) {
private static String[] getUserObjectClasses(Map<String,String> ldapConfig) {
String objClassesCfg = ldapConfig.get(LDAPConstants.USER_OBJECT_CLASSES);
String objClassesStr = (objClassesCfg != null && objClassesCfg.length() > 0) ? objClassesCfg.trim() : "inetOrgPerson, organizationalPerson";

View File

@@ -1,12 +1,8 @@
package org.keycloak.federation.ldap;
import org.jboss.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.UserModelDelegate;
import org.picketlink.idm.IdentityManagementException;
@@ -16,10 +12,6 @@ import org.picketlink.idm.credential.TOTPCredential;
import org.picketlink.idm.model.basic.BasicModel;
import org.picketlink.idm.model.basic.User;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $

View File

@@ -53,7 +53,7 @@ public class AccountSocialBean {
}
// Removing last social provider is not possible if you don't have other possibility to authenticate
this.removeLinkPossible = availableLinks > 1 || user.getAuthenticationLink() != null;
this.removeLinkPossible = availableLinks > 1 || user.getFederationLink() != null;
}
private SocialLinkModel getSocialLink(Set<SocialLinkModel> userSocialLinks, String socialProviderId) {

View File

@@ -161,15 +161,6 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'RealmSMTPSettingsCtrl'
})
.when('/realms/:realm/ldap-settings', {
templateUrl : 'partials/realm-ldap.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
}
},
controller : 'RealmLDAPSettingsCtrl'
})
.when('/realms/:realm/audit', {
templateUrl : 'partials/realm-audit.html',
resolve : {
@@ -194,39 +185,6 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'RealmAuditCtrl'
})
.when('/realms/:realm/auth-settings', {
templateUrl : 'partials/realm-auth-list.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
}
},
controller : 'RealmAuthSettingsCtrl'
})
.when('/realms/:realm/auth-settings/create', {
templateUrl : 'partials/realm-auth-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'RealmAuthSettingsDetailCtrl'
})
.when('/realms/:realm/auth-settings/:index', {
templateUrl : 'partials/realm-auth-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
}
},
controller : 'RealmAuthSettingsDetailCtrl'
})
.when('/create/user/:realm', {
templateUrl : 'partials/user-detail.html',
resolve : {

View File

@@ -891,185 +891,6 @@ module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, real
}
});
module.controller('RealmLDAPSettingsCtrl', function($scope, $location, Notifications, Realm, realm, RealmLDAPConnectionTester) {
console.log('RealmLDAPSettingsCtrl');
$scope.ldapVendors = [
{ "id": "ad", "name": "Active Directory" },
{ "id": "rhds", "name": "Red Hat Directory Server" },
{ "id": "other", "name": "Other" }
];
$scope.usernameLDAPAttributes = [
"uid", "cn", "sAMAccountName"
];
$scope.realm = realm;
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
$scope.lastVendor = realm.ldapServer.vendor;
$scope.$watch('realm', function() {
if (!angular.equals($scope.realm, oldCopy)) {
$scope.changed = true;
}
if (!angular.equals($scope.realm.ldapServer.vendor, $scope.lastVendor)) {
console.log("LDAP vendor changed");
$scope.lastVendor = $scope.realm.ldapServer.vendor;
if ($scope.lastVendor === "ad") {
$scope.realm.ldapServer.usernameLDAPAttribute = "cn";
$scope.realm.ldapServer.userObjectClasses = "person, organizationalPerson";
} else {
$scope.realm.ldapServer.usernameLDAPAttribute = "uid";
$scope.realm.ldapServer.userObjectClasses = "inetOrgPerson, organizationalPerson";
}
}
}, true);
$scope.save = function() {
var realmCopy = angular.copy($scope.realm);
$scope.changed = false;
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.realm + "/ldap-settings");
Notifications.success("Your changes have been saved to the realm.");
});
};
$scope.reset = function() {
$scope.realm = angular.copy(oldCopy);
$scope.changed = false;
$scope.lastVendor = $scope.realm.ldapServer.vendor;
};
var initConnectionTest = function(testAction, ldapConfig) {
return {
action: testAction,
realm: $scope.realm.realm,
connectionUrl: ldapConfig.connectionUrl,
bindDn: ldapConfig.bindDn,
bindCredential: ldapConfig.bindCredential
};
};
$scope.testConnection = function() {
console.log('RealmLDAPSettingsCtrl: testConnection');
RealmLDAPConnectionTester.get(initConnectionTest("testConnection", $scope.realm.ldapServer), function() {
Notifications.success("LDAP connection successful.");
}, function() {
Notifications.error("Error when trying to connect to LDAP. See server.log for details.");
});
}
$scope.testAuthentication = function() {
console.log('RealmLDAPSettingsCtrl: testAuthentication');
RealmLDAPConnectionTester.get(initConnectionTest("testAuthentication", $scope.realm.ldapServer), function() {
Notifications.success("LDAP authentication successful.");
}, function() {
Notifications.error("LDAP authentication failed. See server.log for details");
});
}
});
module.controller('RealmAuthSettingsCtrl', function($scope, realm) {
console.log('RealmAuthSettingsCtrl');
$scope.realm = realm;
$scope.authenticationProviders = realm.authenticationProviders;
});
module.controller('RealmAuthSettingsDetailCtrl', function($scope, $routeParams, $location, Notifications, Dialog, Realm, realm, serverInfo) {
console.log('RealmAuthSettingsDetailCtrl');
$scope.realm = realm;
$scope.availableProviders = serverInfo.authProviders;
$scope.availableProviderNames = Object.keys(serverInfo.authProviders);
$scope.create = !$routeParams.index;
$scope.changed = false;
if ($scope.create) {
$scope.authProvider = {
passwordUpdateSupported: true,
config: {}
};
$scope.authProviderOptionNames = [];
} else {
$scope.authProvider = realm.authenticationProviders[ $routeParams.index ];
if (!$scope.authProvider.config) {
$scope.authProvider.config = {};
}
$scope.authProviderOptionNames = serverInfo.authProviders[ $scope.authProvider.providerName ];
$scope.authProviderIndex = $routeParams.index;
}
var oldCopy = angular.copy($scope.authProvider);
$scope.$watch('authProvider', function() {
if (!angular.equals($scope.authProvider, oldCopy)) {
$scope.changed = true;
}
}, true);
$scope.changeAuthProvider = function() {
console.log('RealmAuthSettingsDetailCtrl: provider changed to ' + $scope.authProvider.providerName);
$scope.authProviderOptionNames = serverInfo.authProviders[ $scope.authProvider.providerName ];
}
$scope.cancel = function() {
$location.url("/realms/" + realm.realm + "/auth-settings");
}
$scope.reset = function() {
$scope.authProvider = angular.copy(oldCopy);
$scope.changed = false;
}
$scope.save = function() {
if (!$scope.authProvider.providerName) {
console.log('RealmAuthSettingsDetailCtrl: no provider selected. Skip creation');
return;
}
console.log('RealmAuthSettingsDetailCtrl: creating provider ' + $scope.authProvider.providerName);
var realmCopy = angular.copy($scope.realm);
if (!realmCopy.authenticationProviders) {
realmCopy.authenticationProviders = [];
}
if ($scope.create) {
realmCopy.authenticationProviders.push($scope.authProvider);
} else {
realmCopy.authenticationProviders[ $scope.authProviderIndex ] = $scope.authProvider;
}
$scope.changed = false;
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.realm + "/auth-settings");
Notifications.success("Authentication provider has been saved.");
});
};
$scope.remove = function() {
Dialog.confirmDelete($scope.realm.authenticationProviders.providerName, 'authentication Provider', function() {
console.log('RealmAuthSettingsDetailCtrl: deleting provider ' + $scope.authProvider.providerName);
var realmCopy = angular.copy($scope.realm);
realmCopy.authenticationProviders.splice($scope.authProviderIndex, 1);
$scope.changed = false;
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.realm + "/auth-settings");
Notifications.success("Authentication provider has been deleted.");
});
});
};
});
module.controller('RealmAuditCtrl', function($scope, auditConfig, RealmAudit, RealmAuditEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
$scope.realm = realm;

View File

@@ -564,7 +564,7 @@ module.controller('LDAPCtrl', function($scope, $location, Notifications, Dialog,
$scope.testAuthentication = function() {
console.log('LDAPCtrl: testAuthentication');
RealmLDAPConnectionTester.get(initConnectionTest("testAuthentication", $scope.realm.ldapServer), function() {
RealmLDAPConnectionTester.get(initConnectionTest("testAuthentication", $scope.instance.config), function() {
Notifications.success("LDAP authentication successful.");
}, function() {
Notifications.error("LDAP authentication failed. See server.log for details");

View File

@@ -1,70 +0,0 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<data-kc-navigation data-kc-current="auth-settings" data-kc-realm="realm.realm" data-kc-social="realm.social"></data-kc-navigation>
<div id="content">
<ol class="breadcrumb" data-ng-show="create">
<li><a href="#/realms/{{realm.realm}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.realm}}">Settings</a></li>
<li><a href="#/realms/{{realm.realm}}/auth-settings">Authentication</a></li>
<li class="active">Add</li>
</ol>
<h2 data-ng-show="create"><span>{{realm.realm}}</span> Add Authentication provider</h2>
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.realm}}">Settings</a></li>
<li><a href="#/realms/{{realm.realm}}/auth-settings">Authentication</a></li>
<li class="active">{{authProviderIndex}}</li>
</ol>
<h2 data-ng-hide="create"><span>{{authProvider.providerName|capitalize}}'s</span> Attributes</h2>
<form class="form-horizontal" name="userForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="border-top">
<div class="form-group input-select">
<label class="col-sm-2 control-label" for="authProviders">Provider Name</label>
<div class="col-sm-4">
<div class="input-group">
<div class="select-kc">
<select id="authProviders" name="authProviders"
data-ng-change="changeAuthProvider()"
data-ng-model="authProvider.providerName"
data-ng-options="(p|capitalize) for p in availableProviderNames"
data-ng-disabled="!create">
<option value="" selected> Select Authentication Provider...</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group clearfix block" data-ng-show="authProvider.providerName">
<label class="col-sm-2 control-label" for="passwordUpdateSupported">Password Update Supported</label>
<div class="col-sm-4">
<input ng-model="authProvider.passwordUpdateSupported" name="passwordUpdateSupported" id="passwordUpdateSupported" onoffswitch />
</div>
</div>
<div data-ng-repeat="option in authProviderOptionNames" class="form-group">
<label class="col-sm-2 control-label">{{option|capitalize}} </label>
<div class="col-sm-4">
<input class="form-control" type="text" data-ng-model="authProvider.config[ option ]" >
</div>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="create && access.manageRealm">
<button kc-cancel data-ng-click="cancel()">Cancel</button>
<button kc-save data-ng-show="changed && authProvider.providerName">Save</button>
</div>
<div class="pull-right form-actions" data-ng-show="!create && access.manageRealm">
<button kc-reset data-ng-show="changed">Clear changes</button>
<button kc-save data-ng-show="changed">Save</button>
<button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
</div>
</form>
</div>
</div>

View File

@@ -1,46 +0,0 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<data-kc-navigation data-kc-current="auth-settings" data-kc-realm="realm.realm" data-kc-social="realm.social"></data-kc-navigation>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.realm}}">Settings</a></li>
<li class="active">Authentication</li>
</ol>
<h2><span>{{realm.realm}}</span> Authentication Providers</h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="kc-table-actions" colspan="3">
<div class="pull-right" data-ng-show="access.manageRealm">
<a class="btn btn-primary" href="#/realms/{{realm.realm}}/auth-settings/create">Add Provider</a>
</div>
</th>
</tr>
<tr data-ng-show="authenticationProviders && authenticationProviders.length > 0">
<th>Provider Name</th>
<th>Password Update Supported</th>
<th>Configuration</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="authProvider in authenticationProviders">
<td><a href="#/realms/{{realm.realm}}/auth-settings/{{$index}}">{{authProvider.providerName|capitalize}}</a></td>
<td>{{authProvider.passwordUpdateSupported}}</td>
<td>
<table class="table table-striped table-bordered" data-ng-show="authProvider.config">
<tr data-ng-repeat="(key, value) in authProvider.config">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</table>
</td>
</tr>
<tr data-ng-show="!authenticationProviders || authenticationProviders.length == 0">
<td>No authentication providers available</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@@ -1,88 +0,0 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<data-kc-navigation data-kc-current="ldap" data-kc-realm="realm.realm" data-kc-social="realm.social"></data-kc-navigation>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}">{{realm.realm}}</a></li>
<li><a href="#/realms/{{realm.realm}}">Settings</a></li>
<li class="active">Ldap Configuration</li>
</ol>
<h2 class="pull-left"><span>{{realm.realm}}</span> Ldap Server Settings</h2>
<p class="subtitle"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
<legend><span class="text">Required Settings</span></legend>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="vendor">Vendor <span class="required">*</span></label>
<div class="col-sm-4">
<div class="select-kc">
<select id="vendor"
ng-model="realm.ldapServer.vendor"
ng-options="vendor.id as vendor.name for vendor in ldapVendors">
</select>
</div>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="usernameLDAPAttribute">Username LDAP attribute <span class="required">*</span></label>
<div class="col-sm-4">
<div class="select-kc">
<select id="usernameLDAPAttribute"
ng-model="realm.ldapServer.usernameLDAPAttribute"
ng-options="usernameLDAPAttribute for usernameLDAPAttribute in usernameLDAPAttributes">
</select>
</div>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="userObjectClasses">User Object Classes <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="userObjectClasses" type="text" ng-model="realm.ldapServer.userObjectClasses" placeholder="LDAP User Object Classes (div. by comma)" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapConnectionUrl">Connection URL <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapConnectionUrl" type="text" ng-model="realm.ldapServer.connectionUrl" placeholder="LDAP connection URL" required>
</div>
<div class="col-sm-4" data-ng-show="access.manageRealm">
<a class="btn btn-primary" data-ng-click="testConnection()">Test connection</a>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapBaseDn">Base DN <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapBaseDn" type="text" ng-model="realm.ldapServer.baseDn" placeholder="LDAP Base DN" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapUserDnSuffix">User DN Suffix <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapUserDnSuffix" type="text" ng-model="realm.ldapServer.userDnSuffix" placeholder="LDAP User DN Suffix" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapBindDn">Bind DN <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapBindDn" type="text" ng-model="realm.ldapServer.bindDn" placeholder="LDAP Bind DN" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapBindCredential">Bind Credential <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapBindCredential" type="text" ng-model="realm.ldapServer.bindCredential" placeholder="LDAP Bind Credentials" required>
</div>
<div class="col-sm-4" data-ng-show="access.manageRealm">
<a class="btn btn-primary" data-ng-click="testAuthentication()">Test authentication</a>
</div>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="access.manageRealm">
<button data-kc-reset data-ng-show="changed">Clear changes</button>
<button data-kc-save data-ng-show="changed">Save</button>
</div>
</form>
</div>
</div>

View File

@@ -6,6 +6,4 @@
<li ng-class="{active: path[2] == 'required-credentials'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li ng-class="{active: path[2] == 'keys-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>
<li ng-class="{active: path[2] == 'smtp-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/smtp-settings">Email</a></li>
<li ng-class="{active: path[2] == 'ldap-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/ldap-settings">Ldap</a></li>
<li ng-class="{active: path[2] == 'auth-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/auth-settings">Authentication</a></li>
</ul>

View File

@@ -1,35 +0,0 @@
package org.keycloak.models;
/**
* Link between user and authentication provider
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationLinkModel {
private String authProvider;
private String authUserId;
public AuthenticationLinkModel() {};
public AuthenticationLinkModel(String authProvider, String authUserId) {
this.authProvider = authProvider;
this.authUserId = authUserId;
}
public String getAuthUserId() {
return authUserId;
}
public void setAuthUserId(String authUserId) {
this.authUserId = authUserId;
}
public String getAuthProvider() {
return authProvider;
}
public void setAuthProvider(String authProvider) {
this.authProvider = authProvider;
}
}

View File

@@ -1,51 +0,0 @@
package org.keycloak.models;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationProviderModel {
public static final AuthenticationProviderModel DEFAULT_PROVIDER = new AuthenticationProviderModel("model", true, Collections.EMPTY_MAP);
private String providerName;
private boolean passwordUpdateSupported = true;
private Map<String, String> config = new HashMap<String, String>();
public AuthenticationProviderModel() {};
public AuthenticationProviderModel(String providerName, boolean passwordUpdateSupported, Map<String, String> config) {
this.providerName = providerName;
this.passwordUpdateSupported = passwordUpdateSupported;
if (config != null) {
this.config.putAll(config);
}
}
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public boolean isPasswordUpdateSupported() {
return passwordUpdateSupported;
}
public void setPasswordUpdateSupported(boolean passwordUpdateSupported) {
this.passwordUpdateSupported = passwordUpdateSupported;
}
public Map<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
}

View File

@@ -51,7 +51,7 @@ public interface KeycloakSession {
*
* @return
*/
UserProvider users();
UserFederationManager users();
/**
* Keycloak user storage. Non-federated, but possibly cache (if it is on) view of users.

View File

@@ -159,14 +159,6 @@ public interface RealmModel extends RoleContainerModel {
void setSocialConfig(Map<String, String> socialConfig);
Map<String, String> getLdapServerConfig();
void setLdapServerConfig(Map<String, String> ldapServerConfig);
List<AuthenticationProviderModel> getAuthenticationProviders();
void setAuthenticationProviders(List<AuthenticationProviderModel> authenticationProviders);
List<UserFederationProviderModel> getUserFederationProviders();
UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName);

View File

@@ -302,16 +302,27 @@ public class UserFederationManager implements UserProvider {
session.userStorage().preRemove(realm, role);
}
public void updateCredential(RealmModel realm, UserModel user, UserCredentialModel credential) {
if (credential.getType().equals(UserCredentialModel.PASSWORD)) {
if (realm.getPasswordPolicy() != null) {
String error = realm.getPasswordPolicy().validate(credential.getValue());
if (error != null) throw new ModelException(error);
}
}
user.updateCredential(credential);
}
@Override
public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
UserFederationProvider link = getFederationLink(realm, user);
if (link != null) {
validateUser(realm, user);
if (link.getSupportedCredentialTypes(user).size() > 0) {
Set<String> supportedCredentialTypes = link.getSupportedCredentialTypes(user);
if (supportedCredentialTypes.size() > 0) {
List<UserCredentialModel> fedCreds = new ArrayList<UserCredentialModel>();
List<UserCredentialModel> localCreds = new ArrayList<UserCredentialModel>();
for (UserCredentialModel cred : input) {
if (fedCreds.contains(cred.getType())) {
if (supportedCredentialTypes.contains(cred.getType())) {
fedCreds.add(cred);
} else {
localCreds.add(cred);

View File

@@ -64,12 +64,6 @@ public interface UserModel {
void updateCredentialDirectly(UserCredentialValueModel cred);
AuthenticationLinkModel getAuthenticationLink();
void setAuthenticationLink(AuthenticationLinkModel authenticationLink);
Set<RoleModel> getRealmRoleMappings();
Set<RoleModel> getApplicationRoleMappings(ApplicationModel app);
boolean hasRole(RoleModel role);

View File

@@ -1,26 +0,0 @@
package org.keycloak.models.entities;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationLinkEntity {
private String authUserId;
private String authProvider;
public String getAuthUserId() {
return authUserId;
}
public void setAuthUserId(String authUserId) {
this.authUserId = authUserId;
}
public String getAuthProvider() {
return authProvider;
}
public void setAuthProvider(String authProvider) {
this.authProvider = authProvider;
}
}

View File

@@ -1,37 +0,0 @@
package org.keycloak.models.entities;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationProviderEntity {
private String providerName;
private boolean passwordUpdateSupported;
private Map<String, String> config;
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public boolean isPasswordUpdateSupported() {
return passwordUpdateSupported;
}
public void setPasswordUpdateSupported(boolean passwordUpdateSupported) {
this.passwordUpdateSupported = passwordUpdateSupported;
}
public Map<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
}

View File

@@ -50,12 +50,10 @@ public class RealmEntity extends AbstractIdentifiableEntity {
private List<String> defaultRoles = new ArrayList<String>();
private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
private List<AuthenticationProviderEntity> authenticationProviders = new ArrayList<AuthenticationProviderEntity>();
private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
private Map<String, String> smtpConfig = new HashMap<String, String>();
private Map<String, String> socialConfig = new HashMap<String, String>();
private Map<String, String> ldapServerConfig = new HashMap<String, String>();
private boolean auditEnabled;
private long auditExpiration;
@@ -319,14 +317,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
this.requiredCredentials = requiredCredentials;
}
public List<AuthenticationProviderEntity> getAuthenticationProviders() {
return authenticationProviders;
}
public void setAuthenticationProviders(List<AuthenticationProviderEntity> authenticationProviders) {
this.authenticationProviders = authenticationProviders;
}
public Map<String, String> getSmtpConfig() {
return smtpConfig;
}
@@ -343,14 +333,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
this.socialConfig = socialConfig;
}
public Map<String, String> getLdapServerConfig() {
return ldapServerConfig;
}
public void setLdapServerConfig(Map<String, String> ldapServerConfig) {
this.ldapServerConfig = ldapServerConfig;
}
public boolean isAuditEnabled() {
return auditEnabled;
}

View File

@@ -27,7 +27,6 @@ public class UserEntity extends AbstractIdentifiableEntity {
private List<UserModel.RequiredAction> requiredActions;
private List<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
private List<SocialLinkEntity> socialLinks;
private AuthenticationLinkEntity authenticationLink;
private String federationLink;
public String getUsername() {
@@ -134,14 +133,6 @@ public class UserEntity extends AbstractIdentifiableEntity {
this.socialLinks = socialLinks;
}
public AuthenticationLinkEntity getAuthenticationLink() {
return authenticationLink;
}
public void setAuthenticationLink(AuthenticationLinkEntity authenticationLink) {
this.authenticationLink = authenticationLink;
}
public String getFederationLink() {
return federationLink;
}

View File

@@ -1,7 +1,6 @@
package org.keycloak.models.utils;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
@@ -17,7 +16,6 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.AuthenticationProviderRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
@@ -107,7 +105,6 @@ public class ModelToRepresentation {
rep.setAccessCodeLifespanUserAction(realm.getAccessCodeLifespanUserAction());
rep.setSmtpServer(realm.getSmtpConfig());
rep.setSocialProviders(realm.getSocialConfig());
rep.setLdapServer(realm.getLdapServerConfig());
rep.setAccountTheme(realm.getAccountTheme());
rep.setLoginTheme(realm.getLoginTheme());
rep.setAdminTheme(realm.getAdminTheme());
@@ -133,18 +130,6 @@ public class ModelToRepresentation {
}
}
List<AuthenticationProviderModel> authProviderModels = realm.getAuthenticationProviders();
if (authProviderModels.size() > 0) {
List<AuthenticationProviderRepresentation> authProviderReps = new ArrayList<AuthenticationProviderRepresentation>();
for (AuthenticationProviderModel model : authProviderModels) {
AuthenticationProviderRepresentation authProvRep = new AuthenticationProviderRepresentation();
authProvRep.setProviderName(model.getProviderName());
authProvRep.setPasswordUpdateSupported(model.isPasswordUpdateSupported());
authProvRep.setConfig(model.getConfig());
authProviderReps.add(authProvRep);
}
rep.setAuthenticationProviders(authProviderReps);
}
List<UserFederationProviderModel> fedProviderModels = realm.getUserFederationProviders();
if (fedProviderModels.size() > 0) {
List<UserFederationProviderRepresentation> fedProviderReps = new ArrayList<UserFederationProviderRepresentation>();

View File

@@ -3,8 +3,6 @@ package org.keycloak.models.utils;
import net.iharder.Base64;
import org.jboss.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserFederationProviderModel;
@@ -20,8 +18,6 @@ import org.keycloak.models.UserModel;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
import org.keycloak.representations.idm.AuthenticationProviderRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
@@ -34,7 +30,6 @@ import org.keycloak.representations.idm.UserRepresentation;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -204,18 +199,6 @@ public class RepresentationToModel {
if (rep.getSocialProviders() != null) {
newRealm.setSocialConfig(new HashMap(rep.getSocialProviders()));
}
if (rep.getLdapServer() != null) {
newRealm.setLdapServerConfig(new HashMap(rep.getLdapServer()));
}
if (rep.getAuthenticationProviders() != null) {
List<AuthenticationProviderModel> authProviderModels = convertAuthenticationProviders(rep.getAuthenticationProviders());
newRealm.setAuthenticationProviders(authProviderModels);
} else {
List<AuthenticationProviderModel> authProviderModels = Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER);
newRealm.setAuthenticationProviders(authProviderModels);
}
if (rep.getUserFederationProviders() != null) {
List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
newRealm.setUserFederationProviders(providerModels);
@@ -280,14 +263,6 @@ public class RepresentationToModel {
realm.setSocialConfig(new HashMap(rep.getSocialProviders()));
}
if (rep.getLdapServer() != null) {
realm.setLdapServerConfig(new HashMap(rep.getLdapServer()));
}
if (rep.getAuthenticationProviders() != null) {
List<AuthenticationProviderModel> authProviderModels = convertAuthenticationProviders(rep.getAuthenticationProviders());
realm.setAuthenticationProviders(authProviderModels);
}
if (rep.getUserFederationProviders() != null) {
List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
realm.setUserFederationProviders(providerModels);
@@ -305,17 +280,6 @@ public class RepresentationToModel {
}
private static List<AuthenticationProviderModel> convertAuthenticationProviders(List<AuthenticationProviderRepresentation> authenticationProviders) {
List<AuthenticationProviderModel> result = new ArrayList<AuthenticationProviderModel>();
for (AuthenticationProviderRepresentation representation : authenticationProviders) {
AuthenticationProviderModel model = new AuthenticationProviderModel(representation.getProviderName(),
representation.isPasswordUpdateSupported(), representation.getConfig());
result.add(model);
}
return result;
}
private static List<UserFederationProviderModel> convertFederationProviders(List<UserFederationProviderRepresentation> providers) {
List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
@@ -624,11 +588,6 @@ public class RepresentationToModel {
updateCredential(user, cred);
}
}
if (userRep.getAuthenticationLink() != null) {
AuthenticationLinkRepresentation link = userRep.getAuthenticationLink();
AuthenticationLinkModel authLink = new AuthenticationLinkModel(link.getAuthProvider(), link.getAuthUserId());
user.setAuthenticationLink(authLink);
}
if (userRep.getSocialLinks() != null) {
for (SocialLinkRepresentation socialLink : userRep.getSocialLinks()) {
SocialLinkModel mappingModel = new SocialLinkModel(socialLink.getSocialProvider(), socialLink.getSocialUserId(), socialLink.getSocialUsername());

View File

@@ -1,7 +1,6 @@
package org.keycloak.models.utils;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
@@ -147,16 +146,6 @@ public class UserModelDelegate implements UserModel {
delegate.updateCredentialDirectly(cred);
}
@Override
public AuthenticationLinkModel getAuthenticationLink() {
return delegate.getAuthenticationLink();
}
@Override
public void setAuthenticationLink(AuthenticationLinkModel authenticationLink) {
delegate.setAuthenticationLink(authenticationLink);
}
@Override
public Set<RoleModel> getRealmRoleMappings() {
return delegate.getRealmRoleMappings();

View File

@@ -2,7 +2,6 @@ package org.keycloak.models.cache;
import org.keycloak.Config;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.OAuthClientModel;
@@ -582,30 +581,6 @@ public class RealmAdapter implements RealmModel {
updated.setSocialConfig(socialConfig);
}
@Override
public Map<String, String> getLdapServerConfig() {
if (updated != null) return updated.getLdapServerConfig();
return cached.getLdapServerConfig();
}
@Override
public void setLdapServerConfig(Map<String, String> ldapServerConfig) {
getDelegateForUpdate();
updated.setLdapServerConfig(ldapServerConfig);
}
@Override
public List<AuthenticationProviderModel> getAuthenticationProviders() {
if (updated != null) return updated.getAuthenticationProviders();
return cached.getAuthenticationProviders();
}
@Override
public void setAuthenticationProviders(List<AuthenticationProviderModel> authenticationProviders) {
getDelegateForUpdate();
updated.setAuthenticationProviders(authenticationProviders);
}
@Override
public List<UserFederationProviderModel> getUserFederationProviders() {
if (updated != null) return updated.getUserFederationProviders();

View File

@@ -1,7 +1,6 @@
package org.keycloak.models.cache;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
@@ -191,18 +190,6 @@ public class UserAdapter implements UserModel {
updated.updateCredentialDirectly(cred);
}
@Override
public AuthenticationLinkModel getAuthenticationLink() {
if (updated != null) return updated.getAuthenticationLink();
return cached.getAuthenticationLink();
}
@Override
public void setAuthenticationLink(AuthenticationLinkModel authenticationLink) {
getDelegateForUpdate();
updated.setAuthenticationLink(authenticationLink);
}
@Override
public String getFederationLink() {
if (updated != null) return updated.getFederationLink();

View File

@@ -1,7 +1,6 @@
package org.keycloak.models.cache.entities;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.OAuthClientModel;
@@ -65,12 +64,10 @@ public class CachedRealm {
private String masterAdminApp;
private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
private List<AuthenticationProviderModel> authenticationProviders = new ArrayList<AuthenticationProviderModel>();
private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
private Map<String, String> smtpConfig = new HashMap<String, String>();
private Map<String, String> socialConfig = new HashMap<String, String>();
private Map<String, String> ldapServerConfig = new HashMap<String, String>();
private boolean auditEnabled;
private long auditExpiration;
@@ -122,12 +119,10 @@ public class CachedRealm {
emailTheme = model.getEmailTheme();
requiredCredentials = model.getRequiredCredentials();
authenticationProviders = model.getAuthenticationProviders();
userFederationProviders = model.getUserFederationProviders();
smtpConfig.putAll(model.getSmtpConfig());
socialConfig.putAll(model.getSocialConfig());
ldapServerConfig.putAll(model.getLdapServerConfig());
auditEnabled = model.isAuditEnabled();
auditExpiration = model.getAuditExpiration();
@@ -292,14 +287,6 @@ public class CachedRealm {
return socialConfig;
}
public Map<String, String> getLdapServerConfig() {
return ldapServerConfig;
}
public List<AuthenticationProviderModel> getAuthenticationProviders() {
return authenticationProviders;
}
public String getLoginTheme() {
return loginTheme;
}

View File

@@ -1,6 +1,5 @@
package org.keycloak.models.cache.entities;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialValueModel;
@@ -27,7 +26,6 @@ public class CachedUser {
private List<UserCredentialValueModel> credentials = new LinkedList<UserCredentialValueModel>();
private boolean enabled;
private boolean totp;
private AuthenticationLinkModel authenticationLink;
private String federationLink;
private Map<String, String> attributes = new HashMap<String, String>();
private Set<UserModel.RequiredAction> requiredActions = new HashSet<UserModel.RequiredAction>();
@@ -47,7 +45,6 @@ public class CachedUser {
this.totp = user.isTotp();
this.federationLink = user.getFederationLink();
this.requiredActions.addAll(user.getRequiredActions());
this.authenticationLink = user.getAuthenticationLink();
for (RoleModel role : user.getRoleMappings()) {
roleMappings.add(role.getId());
}
@@ -101,10 +98,6 @@ public class CachedUser {
return roleMappings;
}
public AuthenticationLinkModel getAuthenticationLink() {
return authenticationLink;
}
public String getFederationLink() {
return federationLink;
}

View File

@@ -8,7 +8,6 @@ import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.models.jpa.entities.AuthenticationLinkEntity;
import org.keycloak.models.jpa.entities.SocialLinkEntity;
import org.keycloak.models.jpa.entities.UserEntity;
import org.keycloak.models.utils.CredentialValidation;
@@ -80,11 +79,6 @@ public class JpaUserProvider implements UserProvider {
private void removeUser(UserEntity user) {
em.createNamedQuery("deleteUserRoleMappingsByUser").setParameter("user", user).executeUpdate();
em.createNamedQuery("deleteSocialLinkByUser").setParameter("user", user).executeUpdate();
if (user.getAuthenticationLink() != null) {
for (AuthenticationLinkEntity l : user.getAuthenticationLink()) {
em.remove(l);
}
}
em.remove(user);
}
@@ -127,8 +121,6 @@ public class JpaUserProvider implements UserProvider {
.setParameter("realmId", realm.getId()).executeUpdate();
num = em.createNamedQuery("deleteUserAttributesByRealm")
.setParameter("realmId", realm.getId()).executeUpdate();
num = em.createNamedQuery("deleteAuthenticationLinksByRealm")
.setParameter("realmId", realm.getId()).executeUpdate();
num = em.createNamedQuery("deleteUsersByRealm")
.setParameter("realmId", realm.getId()).executeUpdate();
}

View File

@@ -1,7 +1,6 @@
package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.enums.SslRequired;
@@ -13,7 +12,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ApplicationEntity;
import org.keycloak.models.jpa.entities.AuthenticationProviderEntity;
import org.keycloak.models.jpa.entities.OAuthClientEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
@@ -660,74 +658,6 @@ public class RealmAdapter implements RealmModel {
em.flush();
}
@Override
public Map<String, String> getLdapServerConfig() {
return realm.getLdapServerConfig();
}
@Override
public void setLdapServerConfig(Map<String, String> ldapServerConfig) {
realm.setLdapServerConfig(ldapServerConfig);
em.flush();
}
@Override
public List<AuthenticationProviderModel> getAuthenticationProviders() {
List<AuthenticationProviderEntity> entities = realm.getAuthenticationProviders();
List<AuthenticationProviderEntity> copy = new ArrayList<AuthenticationProviderEntity>();
for (AuthenticationProviderEntity entity : entities) {
copy.add(entity);
}
Collections.sort(copy, new Comparator<AuthenticationProviderEntity>() {
@Override
public int compare(AuthenticationProviderEntity o1, AuthenticationProviderEntity o2) {
return o1.getPriority() - o2.getPriority();
}
});
List<AuthenticationProviderModel> result = new ArrayList<AuthenticationProviderModel>();
for (AuthenticationProviderEntity entity : copy) {
result.add(new AuthenticationProviderModel(entity.getProviderName(), entity.isPasswordUpdateSupported(), entity.getConfig()));
}
return result;
}
@Override
public void setAuthenticationProviders(List<AuthenticationProviderModel> authenticationProviders) {
List<AuthenticationProviderEntity> newEntities = new ArrayList<AuthenticationProviderEntity>();
int counter = 1;
for (AuthenticationProviderModel model : authenticationProviders) {
AuthenticationProviderEntity entity = new AuthenticationProviderEntity();
entity.setRealm(realm);
entity.setProviderName(model.getProviderName());
entity.setPasswordUpdateSupported(model.isPasswordUpdateSupported());
entity.setConfig(model.getConfig());
entity.setPriority(counter++);
newEntities.add(entity);
}
// Remove all existing first
Collection<AuthenticationProviderEntity> existing = realm.getAuthenticationProviders();
Collection<AuthenticationProviderEntity> copy = new ArrayList<AuthenticationProviderEntity>(existing);
for (AuthenticationProviderEntity apToRemove : copy) {
existing.remove(apToRemove);
em.remove(apToRemove);
}
em.flush();
// Now create all new providers
for (AuthenticationProviderEntity apToAdd : newEntities) {
existing.add(apToAdd);
em.persist(apToAdd);
}
em.flush();
}
@Override
public List<UserFederationProviderModel> getUserFederationProviders() {
List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();

View File

@@ -1,7 +1,6 @@
package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
@@ -9,7 +8,6 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.AuthenticationLinkEntity;
import org.keycloak.models.jpa.entities.CredentialEntity;
import org.keycloak.models.jpa.entities.UserAttributeEntity;
import org.keycloak.models.jpa.entities.UserEntity;
@@ -21,11 +19,9 @@ import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -383,36 +379,6 @@ public class UserAdapter implements UserModel {
return roles;
}
@Override
public AuthenticationLinkModel getAuthenticationLink() {
Collection<AuthenticationLinkEntity> col = user.getAuthenticationLink();
if (col == null || col.isEmpty()) {
return null;
}
AuthenticationLinkEntity authLinkEntity = col.iterator().next();
return new AuthenticationLinkModel(authLinkEntity.getAuthProvider(), authLinkEntity.getAuthUserId());
}
@Override
public void setAuthenticationLink(AuthenticationLinkModel authenticationLink) {
AuthenticationLinkEntity entity = new AuthenticationLinkEntity();
entity.setAuthProvider(authenticationLink.getAuthProvider());
entity.setAuthUserId(authenticationLink.getAuthUserId());
entity.setUser(user);
if (user.getAuthenticationLink() == null) {
user.setAuthenticationLink(new LinkedList<AuthenticationLinkEntity>());
} else if (!user.getAuthenticationLink().isEmpty()) {
AuthenticationLinkEntity old = user.getAuthenticationLink().iterator().next();
user.getAuthenticationLink().clear();
em.remove(old);
}
user.getAuthenticationLink().add(entity);
em.persist(entity);
em.flush();
}
@Override
public String getFederationLink() {
return user.getFederationLink();

View File

@@ -1,105 +0,0 @@
package org.keycloak.models.jpa.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.io.Serializable;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@NamedQueries({
@NamedQuery(name="deleteAuthenticationLinksByRealm", query="delete from AuthenticationLinkEntity authLink where authLink.user IN (select u from UserEntity u where u.realmId=:realmId)")
})
@Table(name="AUTHENTICATION_LINK")
@Entity
@IdClass(AuthenticationLinkEntity.Key.class)
public class AuthenticationLinkEntity {
@Id
@Column(name="AUTH_PROVIDER")
protected String authProvider;
@Column(name="AUTH_USER_ID")
protected String authUserId;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="USER_ID")
protected UserEntity user;
public String getAuthProvider() {
return authProvider;
}
public void setAuthProvider(String authProvider) {
this.authProvider = authProvider;
}
public String getAuthUserId() {
return authUserId;
}
public void setAuthUserId(String authUserId) {
this.authUserId = authUserId;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
public static class Key implements Serializable {
protected UserEntity user;
protected String authProvider;
public Key() {
}
public Key(UserEntity user, String authProvider) {
this.user = user;
this.authProvider = authProvider;
}
public UserEntity getUser() {
return user;
}
public String getAuthProvider() {
return authProvider;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
if (authProvider != null ? !authProvider.equals(key.authProvider) : key.authProvider != null) return false;
if (user != null ? !user.getId().equals(key.user != null ? key.user.getId() : null) : key.user != null) return false;
return true;
}
@Override
public int hashCode() {
int result = user != null ? user.getId().hashCode() : 0;
result = 31 * result + (authProvider != null ? authProvider.hashCode() : 0);
return result;
}
}
}

View File

@@ -1,129 +0,0 @@
package org.keycloak.models.jpa.entities;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@Entity
@Table(name="AUTH_PROVIDER")
@IdClass(AuthenticationProviderEntity.Key.class)
public class AuthenticationProviderEntity {
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REALM_ID")
protected RealmEntity realm;
@Id
@Column(name="PROVIDER_NAME")
private String providerName;
@Column(name="PASSWORD_UPDATE_SUPPORTED")
private boolean passwordUpdateSupported;
@Column(name="PRIORITY")
private int priority;
@ElementCollection
@MapKeyColumn(name="NAME")
@Column(name="VALUE")
@CollectionTable(name="AUTH_PROVIDER_CONFIG", joinColumns = {
@JoinColumn(name="REALM_ID", referencedColumnName = "REALM_ID"),
@JoinColumn(name="AUTH_PROVIDER_NAME", referencedColumnName = "PROVIDER_NAME")})
private Map<String, String> config;
public RealmEntity getRealm() {
return realm;
}
public void setRealm(RealmEntity realm) {
this.realm = realm;
}
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public boolean isPasswordUpdateSupported() {
return passwordUpdateSupported;
}
public void setPasswordUpdateSupported(boolean passwordUpdateSupported) {
this.passwordUpdateSupported = passwordUpdateSupported;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public Map<String, String> getConfig() {
return config;
}
public void setConfig(Map<String, String> config) {
this.config = config;
}
public static class Key implements Serializable {
protected RealmEntity realm;
protected String providerName;
public Key() {
}
public Key(RealmEntity realm, String providerName) {
this.realm = realm;
this.providerName = providerName;
}
public RealmEntity getRealm() {
return realm;
}
public String getProviderName() {
return providerName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
if (providerName != null ? !providerName.equals(key.providerName) : key.providerName != null) return false;
if (realm != null ? !realm.getId().equals(key.realm != null ? key.realm.getId() : null) : key.realm != null) return false;
return true;
}
@Override
public int hashCode() {
int result = realm != null ? realm.getId().hashCode() : 0;
result = 31 * result + (providerName != null ? providerName.hashCode() : 0);
return result;
}
}
}

View File

@@ -112,9 +112,6 @@ public class RealmEntity {
Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
List<AuthenticationProviderEntity> authenticationProviders = new ArrayList<AuthenticationProviderEntity>();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
@JoinTable(name="FED_PROVIDERS")
List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
@@ -138,12 +135,6 @@ public class RealmEntity {
@CollectionTable(name="REALM_SOCIAL_CONFIG", joinColumns={ @JoinColumn(name="REALM_ID") })
protected Map<String, String> socialConfig = new HashMap<String, String>();
@ElementCollection
@MapKeyColumn(name="NAME")
@Column(name="VALUE")
@CollectionTable(name="REALM_LDAP_CONFIG", joinColumns={ @JoinColumn(name="REALM_ID") })
protected Map<String, String> ldapServerConfig = new HashMap<String, String>();
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
@JoinTable(name="REALM_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="REALM_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")})
protected Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
@@ -314,14 +305,6 @@ public class RealmEntity {
this.requiredCredentials = requiredCredentials;
}
public List<AuthenticationProviderEntity> getAuthenticationProviders() {
return authenticationProviders;
}
public void setAuthenticationProviders(List<AuthenticationProviderEntity> authenticationProviders) {
this.authenticationProviders = authenticationProviders;
}
public Collection<ApplicationEntity> getApplications() {
return applications;
}
@@ -361,14 +344,6 @@ public class RealmEntity {
this.socialConfig = socialConfig;
}
public Map<String, String> getLdapServerConfig() {
return ldapServerConfig;
}
public void setLdapServerConfig(Map<String, String> ldapServerConfig) {
this.ldapServerConfig = ldapServerConfig;
}
public Collection<RoleEntity> getDefaultRoles() {
return defaultRoles;
}

View File

@@ -85,9 +85,6 @@ public class UserEntity {
@Column(name="federation_link")
protected String federationLink;
@OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true, mappedBy="user")
protected Collection<AuthenticationLinkEntity> authenticationLink;
public String getId() {
return id;
}
@@ -193,14 +190,6 @@ public class UserEntity {
this.credentials = credentials;
}
public Collection<AuthenticationLinkEntity> getAuthenticationLink() {
return authenticationLink;
}
public void setAuthenticationLink(Collection<AuthenticationLinkEntity> authenticationLink) {
this.authenticationLink = authenticationLink;
}
public String getFederationLink() {
return federationLink;
}

View File

@@ -5,7 +5,6 @@ import com.mongodb.QueryBuilder;
import org.jboss.logging.Logger;
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.entities.UserFederationProviderEntity;
@@ -16,7 +15,6 @@ import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.entities.AuthenticationProviderEntity;
import org.keycloak.models.entities.RequiredCredentialEntity;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
@@ -758,43 +756,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
updateRealm();
}
@Override
public Map<String, String> getLdapServerConfig() {
return realm.getLdapServerConfig();
}
@Override
public void setLdapServerConfig(Map<String, String> ldapServerConfig) {
realm.setLdapServerConfig(ldapServerConfig);
updateRealm();
}
@Override
public List<AuthenticationProviderModel> getAuthenticationProviders() {
List<AuthenticationProviderEntity> entities = realm.getAuthenticationProviders();
List<AuthenticationProviderModel> result = new ArrayList<AuthenticationProviderModel>();
for (AuthenticationProviderEntity entity : entities) {
result.add(new AuthenticationProviderModel(entity.getProviderName(), entity.isPasswordUpdateSupported(), entity.getConfig()));
}
return result;
}
@Override
public void setAuthenticationProviders(List<AuthenticationProviderModel> authenticationProviders) {
List<AuthenticationProviderEntity> entities = new ArrayList<AuthenticationProviderEntity>();
for (AuthenticationProviderModel model : authenticationProviders) {
AuthenticationProviderEntity entity = new AuthenticationProviderEntity();
entity.setProviderName(model.getProviderName());
entity.setPasswordUpdateSupported(model.isPasswordUpdateSupported());
entity.setConfig(model.getConfig());
entities.add(entity);
}
realm.setAuthenticationProviders(entities);
updateRealm();
}
@Override
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName) {
UserFederationProviderEntity entity = new UserFederationProviderEntity();

View File

@@ -2,7 +2,6 @@ package org.keycloak.models.mongo.keycloak.adapters;
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
@@ -10,7 +9,6 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.entities.AuthenticationLinkEntity;
import org.keycloak.models.entities.CredentialEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
@@ -341,27 +339,6 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
}
@Override
public AuthenticationLinkModel getAuthenticationLink() {
AuthenticationLinkEntity authLinkEntity = user.getAuthenticationLink();
if (authLinkEntity == null) {
return null;
} else {
return new AuthenticationLinkModel(authLinkEntity.getAuthProvider(), authLinkEntity.getAuthUserId());
}
}
@Override
public void setAuthenticationLink(AuthenticationLinkModel authenticationLink) {
AuthenticationLinkEntity authLinkEntity = new AuthenticationLinkEntity();
authLinkEntity.setAuthProvider(authenticationLink.getAuthProvider());
authLinkEntity.setAuthUserId(authenticationLink.getAuthUserId());
user.setAuthenticationLink(authLinkEntity);
getMongoStore().updateEntity(user, invocationContext);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@@ -17,7 +17,6 @@
<modules>
<module>keycloak-picketlink-api</module>
<module>keycloak-picketlink-realm</module>
</modules>

View File

@@ -96,7 +96,6 @@
<modules>
<module>audit</module>
<module>authentication</module>
<module>core</module>
<module>core-jaxrs</module>
<module>connections</module>

View File

@@ -73,12 +73,6 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authentication-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId>

View File

@@ -127,7 +127,7 @@ public class DefaultKeycloakSession implements KeycloakSession {
}
@Override
public UserProvider users() {
public UserFederationManager users() {
return federationManager;
}

View File

@@ -4,7 +4,6 @@ import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
@@ -16,7 +15,6 @@ import org.keycloak.enums.SslRequired;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.CredentialRepresentation;
import java.util.Arrays;
import java.util.Collections;
/**
@@ -61,7 +59,6 @@ public class ApplianceBootstrap {
realm.setSslRequired(SslRequired.EXTERNAL);
realm.setRegistrationAllowed(false);
KeycloakModelUtils.generateRealmKeys(realm);
realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
realm.setAuditListeners(Collections.singleton("jboss-logging"));
@@ -70,7 +67,7 @@ public class ApplianceBootstrap {
UserCredentialModel password = new UserCredentialModel();
password.setType(UserCredentialModel.PASSWORD);
password.setValue("admin");
adminUser.updateCredential(password);
session.users().updateCredential(realm, adminUser, password);
adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);

View File

@@ -3,11 +3,7 @@ package org.keycloak.services.managers;
import org.jboss.logging.Logger;
import org.keycloak.RSATokenVerifier;
import org.keycloak.VerificationException;
import org.keycloak.authentication.AuthProviderStatus;
import org.keycloak.authentication.AuthUser;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
@@ -29,6 +25,8 @@ import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
@@ -257,20 +255,8 @@ public class AuthenticationManager {
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
if (user == null) {
AuthUser authUser = AuthenticationProviderManager.getManager(realm, session).getUser(username);
if (authUser != null) {
// Create new user and link him with authentication provider
user = session.users().addUser(realm, authUser.getUsername());
user.setEnabled(true);
user.setFirstName(authUser.getFirstName());
user.setLastName(authUser.getLastName());
user.setEmail(authUser.getEmail());
user.setAuthenticationLink(new AuthenticationLinkModel(authUser.getProviderName(), authUser.getId()));
logger.info("User " + authUser.getUsername() + " created in Keycloak and linked with provider " + authUser.getProviderName());
} else {
logger.warn("User " + username + " not found");
return AuthenticationStatus.INVALID_USER;
}
logger.warn("User " + username + " not found");
return AuthenticationStatus.INVALID_USER;
}
if (!checkEnabled(user)) {
@@ -284,11 +270,13 @@ public class AuthenticationManager {
}
if (types.contains(CredentialRepresentation.PASSWORD)) {
List<UserCredentialModel> credentials = new LinkedList<UserCredentialModel>();
String password = formData.getFirst(CredentialRepresentation.PASSWORD);
if (password == null) {
logger.warn("Password not provided");
return AuthenticationStatus.MISSING_PASSWORD;
}
credentials.add(UserCredentialModel.password(password));
if (user.isTotp()) {
String token = formData.getFirst(CredentialRepresentation.TOTP);
@@ -296,21 +284,14 @@ public class AuthenticationManager {
logger.warn("TOTP token not provided");
return AuthenticationStatus.MISSING_TOTP;
}
credentials.add(UserCredentialModel.totp(token));
logger.debug("validating TOTP");
if (!session.users().validCredentials(realm, user, UserCredentialModel.totp(token))) {
return AuthenticationStatus.INVALID_CREDENTIALS;
}
}
}
logger.debug("validating password for user: " + username);
AuthProviderStatus authStatus = AuthenticationProviderManager.getManager(realm, session).validatePassword(user, password);
if (authStatus == AuthProviderStatus.INVALID_CREDENTIALS) {
logger.debug("invalid password for user: " + username);
if (!session.users().validCredentials(realm, user, credentials)) {
return AuthenticationStatus.INVALID_CREDENTIALS;
} else if (authStatus == AuthProviderStatus.FAILED) {
return AuthenticationStatus.FAILED;
}
if (!user.getRequiredActions().isEmpty()) {
@@ -324,6 +305,9 @@ public class AuthenticationManager {
logger.warn("Secret not provided");
return AuthenticationStatus.MISSING_PASSWORD;
}
if (!session.users().validCredentials(realm, user, UserCredentialModel.secret(secret))) {
return AuthenticationStatus.INVALID_CREDENTIALS;
}
if (!user.getRequiredActions().isEmpty()) {
return AuthenticationStatus.ACTIONS_REQUIRED;
} else {

View File

@@ -33,13 +33,8 @@ import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.Details;
import org.keycloak.audit.Event;
import org.keycloak.audit.EventType;
import org.keycloak.authentication.AuthProviderStatus;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.models.AccountRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.Constants;
@@ -146,7 +141,6 @@ public class AccountService {
account = session.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(uriInfo);
boolean passwordUpdateSupported = false;
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, true);
@@ -173,16 +167,12 @@ public class AccountService {
account.setUser(auth.getUser());
AuthenticationLinkModel authLinkModel = auth.getUser().getAuthenticationLink();
if (authLinkModel != null) {
AuthenticationProviderModel authProviderModel = AuthenticationProviderManager.getConfiguredProviderModel(realm, authLinkModel.getAuthProvider());
passwordUpdateSupported = authProviderModel.isPasswordUpdateSupported();
}
}
boolean auditEnabled = auditProvider != null && realm.isAuditEnabled();
account.setFeatures(realm.isSocial(), auditEnabled, passwordUpdateSupported);
// todo find out from federation if password is updatable
account.setFeatures(realm.isSocial(), auditEnabled, true);
}
public static UriBuilder accountServiceBaseUrl(UriInfo uriInfo) {
@@ -428,7 +418,7 @@ public class AccountService {
UserCredentialModel credentials = new UserCredentialModel();
credentials.setType(CredentialRepresentation.TOTP);
credentials.setValue(totpSecret);
user.updateCredential(credentials);
session.users().updateCredential(realm, user, credentials);
user.setTotp(true);
@@ -471,19 +461,18 @@ public class AccountService {
return account.setError(Messages.INVALID_PASSWORD_CONFIRM).createResponse(AccountPages.PASSWORD);
}
AuthenticationProviderManager authProviderManager = AuthenticationProviderManager.getManager(realm, session);
UserCredentialModel cred = UserCredentialModel.password(password);
if (Validation.isEmpty(password)) {
return account.setError(Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
} else if (authProviderManager.validatePassword(user, password) != AuthProviderStatus.SUCCESS) {
return account.setError(Messages.INVALID_PASSWORD_EXISTING).createResponse(AccountPages.PASSWORD);
} else {
if (!session.users().validCredentials(realm, user, cred)) {
return account.setError(Messages.INVALID_PASSWORD_EXISTING).createResponse(AccountPages.PASSWORD);
}
}
try {
boolean passwordUpdateSuccess = authProviderManager.updatePassword(user, passwordNew);
if (!passwordUpdateSuccess) {
return account.setError("Password update failed").createResponse(AccountPages.PASSWORD);
}
} catch (AuthenticationProviderException ape) {
session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew));
} catch (Exception ape) {
return account.setError(ape.getMessage()).createResponse(AccountPages.PASSWORD);
}
@@ -539,7 +528,7 @@ public class AccountService {
if (link != null) {
// Removing last social provider is not possible if you don't have other possibility to authenticate
if (session.users().getSocialLinks(user, realm).size() > 1 || user.getAuthenticationLink() != null) {
if (session.users().getSocialLinks(user, realm).size() > 1 || user.getFederationLink() != null) {
session.users().removeSocialLink(realm, user, providerId);
logger.debug("Social provider " + providerId + " removed successfully from user " + user.getUsername());

View File

@@ -28,8 +28,6 @@ import org.keycloak.audit.Audit;
import org.keycloak.audit.Details;
import org.keycloak.audit.Errors;
import org.keycloak.audit.EventType;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.email.EmailException;
import org.keycloak.email.EmailProvider;
import org.keycloak.login.LoginFormsProvider;
@@ -167,7 +165,7 @@ public class RequiredActionsService {
UserCredentialModel credentials = new UserCredentialModel();
credentials.setType(CredentialRepresentation.TOTP);
credentials.setValue(totpSecret);
user.updateCredential(credentials);
session.users().updateCredential(realm, user, credentials);
user.setTotp(true);
@@ -205,11 +203,8 @@ public class RequiredActionsService {
}
try {
boolean updateSuccessful = AuthenticationProviderManager.getManager(realm, session).updatePassword(user, passwordNew);
if (!updateSuccessful) {
return loginForms.setError("Password update failed").createResponse(RequiredAction.UPDATE_PASSWORD);
}
} catch (AuthenticationProviderException ape) {
session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew));
} catch (Exception ape) {
return loginForms.setError(ape.getMessage()).createResponse(RequiredAction.UPDATE_PASSWORD);
}

View File

@@ -17,8 +17,6 @@ import org.keycloak.audit.Audit;
import org.keycloak.audit.Details;
import org.keycloak.audit.Errors;
import org.keycloak.audit.EventType;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.login.LoginFormsProvider;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
@@ -639,10 +637,8 @@ public class TokenService {
return Flows.forms(session, realm, uriInfo).setError(error).setFormData(formData).createRegistration();
}
AuthenticationProviderManager authenticationProviderManager = AuthenticationProviderManager.getManager(realm, session);
// Validate that user with this username doesn't exist in realm or any authentication provider
if (session.users().getUserByUsername(username, realm) != null || authenticationProviderManager.getUser(username) != null) {
if (session.users().getUserByUsername(username, realm) != null) {
audit.error(Errors.USERNAME_IN_USE);
return Flows.forms(session, realm, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration();
}
@@ -660,11 +656,11 @@ public class TokenService {
credentials.setValue(formData.getFirst("password"));
boolean passwordUpdateSuccessful;
String passwordUpdateError;
String passwordUpdateError = null;
try {
passwordUpdateSuccessful = AuthenticationProviderManager.getManager(realm, session).updatePassword(user, formData.getFirst("password"));
passwordUpdateError = "Password update failed";
} catch (AuthenticationProviderException ape) {
session.users().updateCredential(realm, user, UserCredentialModel.password(formData.getFirst("password")));
passwordUpdateSuccessful = true;
} catch (Exception ape) {
passwordUpdateSuccessful = false;
passwordUpdateError = ape.getMessage();
}

View File

@@ -1,8 +1,6 @@
package org.keycloak.services.resources.admin;
import org.keycloak.audit.AuditListener;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.freemarker.ExtendingThemeManager;
import org.keycloak.freemarker.Theme;
import org.keycloak.freemarker.ThemeProvider;
import org.keycloak.models.KeycloakSession;
@@ -36,7 +34,6 @@ public class ServerInfoAdminResource {
ServerInfoRepresentation info = new ServerInfoRepresentation();
setSocialProviders(info);
setThemes(info);
setAuthProviders(info);
setAuditListeners(info);
return info;
}
@@ -61,14 +58,6 @@ public class ServerInfoAdminResource {
Collections.sort(info.socialProviders);
}
private void setAuthProviders(ServerInfoRepresentation info) {
info.authProviders = new HashMap<String, List<String>>();
Iterable<AuthenticationProvider> authProviders = session.getAllProviders(AuthenticationProvider.class);
for (AuthenticationProvider authProvider : authProviders) {
info.authProviders.put(authProvider.getName(), authProvider.getAvailableOptions());
}
}
private void setAuditListeners(ServerInfoRepresentation info) {
info.auditListeners = new LinkedList<String>();
@@ -84,7 +73,6 @@ public class ServerInfoAdminResource {
private List<String> socialProviders;
private Map<String, List<String>> authProviders;
private List<String> auditListeners;
@@ -99,10 +87,6 @@ public class ServerInfoAdminResource {
return socialProviders;
}
public Map<String, List<String>> getAuthProviders() {
return authProviders;
}
public List<String> getAuditListeners() {
return auditListeners;
}

View File

@@ -766,7 +766,7 @@ public class UsersResource {
}
UserCredentialModel cred = RepresentationToModel.convertCredential(pass);
user.updateCredential(cred);
session.users().updateCredential(realm, user, cred);
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
}

View File

@@ -135,7 +135,6 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
ldapConfig.put(LDAPConstants.BIND_CREDENTIAL, getBindCredential());
ldapConfig.put(LDAPConstants.USER_DN_SUFFIX, getUserDnSuffix());
ldapConfig.put(LDAPConstants.VENDOR, getVendor());
realm.setLdapServerConfig(ldapConfig);
}

View File

@@ -1,23 +1,27 @@
package org.keycloak.testsuite;
import org.keycloak.authentication.picketlink.PicketlinkAuthenticationProvider;
import org.keycloak.federation.ldap.PartitionManagerRegistry;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.picketlink.IdentityManagerProvider;
import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.PartitionManager;
import org.picketlink.idm.credential.Password;
import org.picketlink.idm.model.basic.BasicModel;
import org.picketlink.idm.model.basic.User;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class LDAPTestUtils {
public static void setLdapPassword(KeycloakSession session, RealmModel realm, String username, String password) {
public static void setLdapPassword(Map<String, String> ldapConfig, String username, String password) {
// Update password directly in ldap. It's workaround, but LDIF import doesn't seem to work on windows for ApacheDS
try {
IdentityManager identityManager = new PicketlinkAuthenticationProvider(session.getProvider(IdentityManagerProvider.class)).getIdentityManager(realm);
PartitionManager partitionManager = PartitionManagerRegistry.createPartitionManager(ldapConfig);
IdentityManager identityManager = partitionManager.createIdentityManager();
User user = BasicModel.getUser(identityManager, username);
identityManager.updateCredential(user, new Password(password.toCharArray()));
} catch (Exception e) {

View File

@@ -33,7 +33,6 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.AuthenticationProviderRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
@@ -279,22 +278,6 @@ public class AdminAPITest {
Assert.assertEquals(rep.getSocialProviders(), storedRealm.getSocialProviders());
}
if (rep.getLdapServer() != null) {
Assert.assertEquals(rep.getLdapServer(), storedRealm.getLdapServer());
}
if (rep.getAuthenticationProviders() != null) {
Set<AuthenticationProviderRepresentation> set = new HashSet<AuthenticationProviderRepresentation>();
for (AuthenticationProviderRepresentation authRep : rep.getAuthenticationProviders()) {
set.add(authRep);
}
Set<AuthenticationProviderRepresentation> storedSet = new HashSet<AuthenticationProviderRepresentation>();
if (storedRealm.getAuthenticationProviders() != null) {
for (AuthenticationProviderRepresentation authRep : storedRealm.getAuthenticationProviders()) {
storedSet.add(authRep);
}
}
Assert.assertEquals(set, storedSet);
}
}
protected void testCreateRealm(String path) {

View File

@@ -28,7 +28,6 @@ import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
@@ -48,7 +47,6 @@ import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import java.security.PublicKey;
import java.util.Arrays;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -71,7 +69,6 @@ public class CompositeRoleTest {
realm.setSslRequired(SslRequired.EXTERNAL);
realm.setEnabled(true);
realm.addRequiredCredential(UserCredentialModel.PASSWORD);
realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
final RoleModel realmRole1 = realm.addRole("REALM_ROLE_1");
final RoleModel realmRole2 = realm.addRole("REALM_ROLE_2");
final RoleModel realmRole3 = realm.addRole("REALM_ROLE_3");

View File

@@ -1,227 +0,0 @@
package org.keycloak.testsuite.forms;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runners.MethodSorters;
import org.keycloak.OAuth2Constants;
import org.keycloak.testsuite.LDAPTestUtils;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AccountPasswordPage;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.LDAPRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class AuthProvidersIntegrationTest {
private static LDAPRule ldapRule = new LDAPRule();
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
addUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
addUser(manager.getSession(), adminstrationRealm, "mary-admin", "mary@admin.com", "password-admin");
AuthenticationProviderModel modelProvider = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_MODEL, false, Collections.EMPTY_MAP);
AuthenticationProviderModel picketlinkProvider = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_PICKETLINK, true, Collections.EMPTY_MAP);
// Delegate authentication to admin realm
Map<String,String> config = new HashMap<String,String>();
config.put(AuthProviderConstants.EXTERNAL_REALM_ID, adminstrationRealm.getId());
AuthenticationProviderModel externalModelProvider = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, true, config);
appRealm.setAuthenticationProviders(Arrays.asList(modelProvider, picketlinkProvider, externalModelProvider));
// Configure LDAP
ldapRule.getEmbeddedServer().setupLdapInRealm(appRealm);
LDAPTestUtils.setLdapPassword(session, appRealm, "johnkeycloak", "password");
}
});
@ClassRule
public static TestRule chain = RuleChain
.outerRule(ldapRule)
.around(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected OAuthClient oauth;
@WebResource
protected WebDriver driver;
@WebResource
protected AppPage appPage;
@WebResource
protected RegisterPage registerPage;
@WebResource
protected LoginPage loginPage;
@WebResource
protected AccountUpdateProfilePage profilePage;
@WebResource
protected AccountPasswordPage changePasswordPage;
private static UserModel addUser(KeycloakSession session, RealmModel realm, String username, String email, String password) {
UserModel user = session.users().addUser(realm, username);
user.setEmail(email);
user.setEnabled(true);
UserCredentialModel creds = new UserCredentialModel();
creds.setType(CredentialRepresentation.PASSWORD);
creds.setValue(password);
user.updateCredential(creds);
return user;
}
@Test
public void loginClassic() {
loginPage.open();
loginPage.login("mary", "password-app");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
profilePage.open();
Assert.assertFalse(profilePage.isPasswordUpdateSupported());
}
@Test
public void loginExternalModel() {
loginPage.open();
loginPage.login("mary-admin", "password-admin");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
profilePage.open();
Assert.assertTrue(profilePage.isPasswordUpdateSupported());
}
@Test
public void loginLdap() {
loginPage.open();
loginPage.login("johnkeycloak", "password");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
profilePage.open();
Assert.assertTrue(profilePage.isPasswordUpdateSupported());
Assert.assertEquals("John", profilePage.getFirstName());
Assert.assertEquals("Doe", profilePage.getLastName());
Assert.assertEquals("john@email.org", profilePage.getEmail());
}
@Test
public void passwordChangeExternalModel() {
// Set password-policy for admin realm
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
adminstrationRealm.setPasswordPolicy(new PasswordPolicy("length(6)"));
}
});
try {
changePasswordPage.open();
loginPage.login("mary-admin", "password-admin");
// Can't update to "pass" due to passwordPolicy
changePasswordPage.changePassword("password-admin", "pass", "pass");
Assert.assertEquals("Invalid password: minimum length 6", profilePage.getError());
changePasswordPage.changePassword("password-admin", "password-updated", "password-updated");
Assert.assertEquals("Your password has been updated", profilePage.getSuccess());
changePasswordPage.logout();
loginPage.open();
loginPage.login("mary-admin", "password-updated");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
} finally {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
adminstrationRealm.setPasswordPolicy(new PasswordPolicy(null));
}
});
}
}
@Test
public void passwordChangeLdap() throws Exception {
changePasswordPage.open();
loginPage.login("johnkeycloak", "password");
changePasswordPage.changePassword("password", "new-password", "new-password");
Assert.assertEquals("Your password has been updated", profilePage.getSuccess());
changePasswordPage.logout();
loginPage.open();
loginPage.login("johnkeycloak", "password");
Assert.assertEquals("Invalid username or password.", loginPage.getError());
loginPage.open();
loginPage.login("johnkeycloak", "new-password");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
}
@Test
public void registerExistingLdapUser() {
loginPage.open();
loginPage.clickRegister();
registerPage.assertCurrent();
registerPage.register("firstName", "lastName", "email", "existing", "password", "password");
registerPage.assertCurrent();
Assert.assertEquals("Username already exists", registerPage.getError());
}
@Test
public void registerUserLdapSuccess() {
loginPage.open();
loginPage.clickRegister();
registerPage.assertCurrent();
registerPage.register("firstName", "lastName", "email", "registerUserSuccess", "password", "password");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
}
}

View File

@@ -76,7 +76,7 @@ public class FederationProvidersIntegrationTest {
// Configure LDAP
ldapRule.getEmbeddedServer().setupLdapInRealm(appRealm);
LDAPTestUtils.setLdapPassword(session, appRealm, "johnkeycloak", "password");
LDAPTestUtils.setLdapPassword(ldapConfig, "johnkeycloak", "password");
}
});

View File

@@ -1,76 +0,0 @@
package org.keycloak.testsuite.model;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.RealmModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthProvidersConfigTest extends AbstractModelTest {
@Test
public void testConfiguration() {
// Create realm and add some providers and ldap config. Then commit
RealmModel realm = realmManager.createRealm("auth-providers-config-test");
Map<String, String> ldapConfig = new HashMap<String,String>();
ldapConfig.put("connectionUrl", "ldap://localhost:10389");
ldapConfig.put("baseDn", "dc=keycloak,dc=org");
realm.setLdapServerConfig(ldapConfig);
AuthenticationProviderModel ap1 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_MODEL, true, Collections.EMPTY_MAP);
AuthenticationProviderModel ap2 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, true, Collections.EMPTY_MAP);
AuthenticationProviderModel ap3 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_PICKETLINK, true, Collections.EMPTY_MAP);
List<AuthenticationProviderModel> authProviders = new ArrayList<AuthenticationProviderModel>();
authProviders.add(ap1);
authProviders.add(ap2);
authProviders.add(ap3);
realm.setAuthenticationProviders(authProviders);
commit();
// Assert ldap config are same
RealmModel persisted = realmManager.getRealm(realm.getId());
Assert.assertEquals(persisted.getLdapServerConfig(), ldapConfig);
// Assert providers are same and in same order
List<AuthenticationProviderModel> persProviders = persisted.getAuthenticationProviders();
Assert.assertEquals(persProviders.size(), 3);
assertProviderEquals(persProviders.get(0), ap1);
assertProviderEquals(persProviders.get(1), ap2);
assertProviderEquals(persProviders.get(2), ap3);
// Update providers
authProviders = new ArrayList<AuthenticationProviderModel>();
authProviders.add(ap3);
authProviders.add(ap2);
authProviders.add(ap1);
persisted.setAuthenticationProviders(authProviders);
commit();
// Assert providers are same and in same order
persisted = realmManager.getRealm(realm.getId());
persProviders = persisted.getAuthenticationProviders();
Assert.assertEquals(persProviders.size(), 3);
assertProviderEquals(persProviders.get(0), ap3);
assertProviderEquals(persProviders.get(1), ap2);
assertProviderEquals(persProviders.get(2), ap1);
}
private void assertProviderEquals(AuthenticationProviderModel prov1, AuthenticationProviderModel prov2) {
Assert.assertEquals(prov1.getProviderName(), prov2.getProviderName());
Assert.assertEquals(prov1.isPasswordUpdateSupported(), prov2.isPasswordUpdateSupported());
Assert.assertEquals(prov1.getConfig(), prov2.getConfig());
}
}

View File

@@ -1,196 +0,0 @@
package org.keycloak.testsuite.model;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.AuthenticationManager;
import javax.ws.rs.core.MultivaluedMap;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class AuthProvidersExternalModelTest extends AbstractModelTest {
private RealmModel realm1;
private RealmModel realm2;
private AuthenticationManager am;
@Before
@Override
public void before() throws Exception {
super.before();
// Create 2 realms and user in realm1
realm1 = realmManager.createRealm("realm1");
realm1.setBruteForceProtected(false);
realm2 = realmManager.createRealm("realm2");
realm2.setBruteForceProtected(false);
realm1.addRequiredCredential(CredentialRepresentation.PASSWORD);
realm2.addRequiredCredential(CredentialRepresentation.PASSWORD);
realm1.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
realm2.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
UserModel john = realmManager.getSession().users().addUser(realm1, "john");
john.setEnabled(true);
john.setFirstName("John");
john.setLastName("Doe");
john.setEmail("john@email.org");
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.PASSWORD);
credential.setValue("password");
john.updateCredential(credential);
am = new AuthenticationManager();
}
@Test
public void testExternalModelAuthentication() {
MultivaluedMap<String, String> formData = createFormData("john", "password");
// Authenticate user with realm1
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm1, formData));
// Verify that user doesn't exists in realm2 and can't authenticate here
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm2, formData));
Assert.assertNull(realmManager.getSession().users().getUserByUsername("john", realm2));
// Add externalModel authenticationProvider into realm2 and point to realm1
setupAuthenticationProviders();
try {
// this is needed for externalModel provider
ResteasyProviderFactory.pushContext(KeycloakSession.class, session);
// Authenticate john in realm2 and verify that now he exists here.
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm2, formData));
UserModel john2 = realmManager.getSession().users().getUserByUsername("john", realm2);
Assert.assertNotNull(john2);
Assert.assertEquals("john", john2.getUsername());
Assert.assertEquals("John", john2.getFirstName());
Assert.assertEquals("Doe", john2.getLastName());
Assert.assertEquals("john@email.org", john2.getEmail());
// Verify link exists
AuthenticationLinkModel authLink = john2.getAuthenticationLink();
Assert.assertNotNull(authLink);
Assert.assertEquals(authLink.getAuthProvider(), AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL);
Assert.assertEquals(authLink.getAuthUserId(), realmManager.getSession().users().getUserByUsername("john", realm1).getId());
} finally {
ResteasyProviderFactory.clearContextData();
}
}
@Test
public void testExternalModelPasswordUpdate() {
// Add externalModel authenticationProvider into realm2 and point to realm1
setupAuthenticationProviders();
// Add john to realm2 and set authentication link
UserModel john = realmManager.getSession().users().addUser(realm2, "john");
john.setEnabled(true);
john.setAuthenticationLink(new AuthenticationLinkModel(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, realmManager.getSession().users().getUserByUsername("john", realm1).getId()));
try {
// this is needed for externalModel provider
ResteasyProviderFactory.pushContext(KeycloakSession.class, session);
// Change credential via realm2 and validate that they are changed also in realm1
AuthenticationProviderManager authProviderManager = AuthenticationProviderManager.getManager(realm2, session);
try {
Assert.assertTrue(authProviderManager.updatePassword(john, "password-updated"));
} catch (AuthenticationProviderException ape) {
ape.printStackTrace();
Assert.fail("Error not expected");
}
MultivaluedMap<String, String> formData = createFormData("john", "password-updated");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm1, formData));
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm2, formData));
// Switch to disallow password update propagation to realm1
setPasswordUpdateForProvider(false, AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, realm2);
// Change credential and validate that password is updated just for realm2
try {
Assert.assertFalse(authProviderManager.updatePassword(john, "password-updated2"));
} catch (AuthenticationProviderException ape) {
ape.printStackTrace();
Assert.fail("Error not expected");
}
formData = createFormData("john", "password-updated2");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm1, formData));
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm2, formData));
// Allow passwordUpdate propagation again
setPasswordUpdateForProvider(true, AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, realm2);
// Set passwordPolicy for realm1 and verify that password update fail
realm1.setPasswordPolicy(new PasswordPolicy("length(8)"));
try {
authProviderManager.updatePassword(john, "passw");
Assert.fail("Update not expected to pass");
} catch (AuthenticationProviderException ape) {
}
} finally {
ResteasyProviderFactory.clearContextData();
}
}
/**
* Setup authentication providers into realm2
*/
private void setupAuthenticationProviders() {
AuthenticationProviderModel ap1 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_MODEL, true, Collections.EMPTY_MAP);
Map<String,String> config = new HashMap<String,String>();
config.put(AuthProviderConstants.EXTERNAL_REALM_ID, "realm1");
AuthenticationProviderModel ap2 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, true, config);
realm2.setAuthenticationProviders(Arrays.asList(ap1, ap2));
}
public static void setPasswordUpdateForProvider(boolean isPasswordUpdate, String providerName, RealmModel realm) {
List<AuthenticationProviderModel> authProviders = realm.getAuthenticationProviders();
for (AuthenticationProviderModel authProvider : authProviders) {
if (providerName.equals(authProvider.getProviderName())) {
authProvider.setPasswordUpdateSupported(isPasswordUpdate);
break;
}
}
realm.setAuthenticationProviders(authProviders);
}
public static MultivaluedMap<String, String> createFormData(String username, String password) {
MultivaluedMap<String, String> formData = new MultivaluedMapImpl<String, String>();
formData.add("username", username);
formData.add(CredentialRepresentation.PASSWORD, password);
return formData;
}
}

View File

@@ -1,183 +0,0 @@
package org.keycloak.testsuite.model;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.testutils.LDAPEmbeddedServer;
import org.keycloak.testsuite.LDAPTestUtils;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.AuthenticationManager;
import javax.ws.rs.core.MultivaluedMap;
import java.util.Arrays;
import java.util.Collections;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class AuthProvidersLDAPTest extends AbstractModelTest {
private static LDAPEmbeddedServer embeddedServer;
private RealmModel realm;
private AuthenticationManager am;
@BeforeClass
public static void beforeClass() {
try {
embeddedServer = new LDAPEmbeddedServer();
embeddedServer.setup();
embeddedServer.importLDIF("ldap/users.ldif");
} catch (Exception e) {
throw new RuntimeException("Error starting Embedded LDAP server.", e);
}
}
@AfterClass
public static void afterClass() {
try {
embeddedServer.tearDown();
} catch (Exception e) {
throw new RuntimeException("Error starting Embedded LDAP server.", e);
}
}
@Before
public void before() throws Exception {
super.before();
// Create realm and configure ldap
realm = realmManager.createRealm("realm");
realm.setBruteForceProtected(false);
realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
this.embeddedServer.setupLdapInRealm(realm);
am = new AuthenticationManager();
}
@Test
public void testLdapAuthentication() {
MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password");
// Set password of user in LDAP
LDAPTestUtils.setLdapPassword(session, realm, "johnkeycloak", "password");
// Verify that user doesn't exists in realm2 and can't authenticate here
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm, formData));
Assert.assertNull(session.users().getUserByUsername("johnkeycloak", realm));
// Add ldap authenticationProvider
setupAuthenticationProviders();
// Authenticate john and verify that now he exists in realm
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
Assert.assertNotNull(john);
Assert.assertEquals("johnkeycloak", john.getUsername());
Assert.assertEquals("John", john.getFirstName());
Assert.assertEquals("Doe", john.getLastName());
Assert.assertEquals("john@email.org", john.getEmail());
// Verify link exists
AuthenticationLinkModel authLink = john.getAuthenticationLink();
Assert.assertNotNull(authLink);
Assert.assertEquals(authLink.getAuthProvider(), AuthProviderConstants.PROVIDER_NAME_PICKETLINK);
}
@Test
public void testLdapInvalidAuthentication() {
setupAuthenticationProviders();
// Add some user and password to realm
UserModel realmUser = session.users().addUser(realm, "realmUser");
realmUser.setEnabled(true);
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.PASSWORD);
credential.setValue("pass");
realmUser.updateCredential(credential);
// User doesn't exists
MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("invalid", "invalid");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm, formData));
// User exists in ldap
formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "invalid");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm, formData));
// User exists in realm
formData = AuthProvidersExternalModelTest.createFormData("realmUser", "invalid");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm, formData));
// User disabled
realmUser.setEnabled(false);
formData = AuthProvidersExternalModelTest.createFormData("realmUser", "pass");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.ACCOUNT_DISABLED, am.authenticateForm(session, null, realm, formData));
// Successful authentication
realmUser.setEnabled(true);
formData = AuthProvidersExternalModelTest.createFormData("realmUser", "pass");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
}
@Test
public void testLdapPasswordUpdate() {
// Add ldap
setupAuthenticationProviders();
LDAPTestUtils.setLdapPassword(session, realm, "johnkeycloak", "password");
// First authenticate successfully to sync john into realm
MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
// Change credential and validate that user can authenticate
AuthenticationProviderManager authProviderManager = AuthenticationProviderManager.getManager(realm, session);
UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
try {
Assert.assertTrue(authProviderManager.updatePassword(john, "password-updated"));
} catch (AuthenticationProviderException ape) {
ape.printStackTrace();
Assert.fail("Error not expected");
}
formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password-updated");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
// Password updated just in LDAP, so validating directly in realm should fail
Assert.assertFalse(session.users().validCredentials(realm, john, UserCredentialModel.password("password-updated")));
// Switch to not allow updating passwords in ldap
AuthProvidersExternalModelTest.setPasswordUpdateForProvider(false, AuthProviderConstants.PROVIDER_NAME_PICKETLINK, realm);
// Change credential and validate that password is not updated
try {
Assert.assertFalse(authProviderManager.updatePassword(john, "password-updated2"));
} catch (AuthenticationProviderException ape) {
ape.printStackTrace();
Assert.fail("Error not expected");
}
formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password-updated2");
Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm, formData));
}
/**
* Setup authentication providers in realm
*/
private void setupAuthenticationProviders() {
AuthenticationProviderModel ap1 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_MODEL, false, Collections.EMPTY_MAP);
AuthenticationProviderModel ap2 = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_PICKETLINK, true, Collections.EMPTY_MAP);
realm.setAuthenticationProviders(Arrays.asList(ap1, ap2));
}
}

View File

@@ -5,7 +5,6 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
@@ -18,7 +17,6 @@ import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus
import org.keycloak.services.managers.BruteForceProtector;
import javax.ws.rs.core.MultivaluedMap;
import java.util.Arrays;
import java.util.UUID;
public class AuthenticationManagerTest extends AbstractModelTest {
@@ -163,7 +161,6 @@ public class AuthenticationManagerTest extends AbstractModelTest {
realm.setPublicKeyPem("0234234");
realm.setAccessTokenLifespan(1000);
realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
protector = ResteasyProviderFactory.getContextData(BruteForceProtector.class);
am = new AuthenticationManager(protector);

View File

@@ -4,10 +4,7 @@ import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
@@ -197,32 +194,6 @@ public class ImportTest extends AbstractModelTest {
Assert.assertEquals("abc", socialConfig.get("google.key"));
Assert.assertEquals("def", socialConfig.get("google.secret"));
// Test ldap config
Map<String, String> ldapConfig = realm.getLdapServerConfig();
Assert.assertTrue(ldapConfig.size() == 6);
Assert.assertEquals("ldap://localhost:10389", ldapConfig.get("connectionUrl"));
Assert.assertEquals("dc=keycloak,dc=org", ldapConfig.get("baseDn"));
Assert.assertEquals("ou=People,dc=keycloak,dc=org", ldapConfig.get("userDnSuffix"));
Assert.assertEquals("other", ldapConfig.get("vendor"));
// Test authentication providers
List<AuthenticationProviderModel> authProviderModels = realm.getAuthenticationProviders();
Assert.assertTrue(authProviderModels.size() == 3);
AuthenticationProviderModel authProv1 = authProviderModels.get(0);
AuthenticationProviderModel authProv2 = authProviderModels.get(1);
AuthenticationProviderModel authProv3 = authProviderModels.get(2);
Assert.assertEquals(AuthProviderConstants.PROVIDER_NAME_MODEL, authProv1.getProviderName());
Assert.assertTrue(authProv1.isPasswordUpdateSupported());
Assert.assertEquals(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, authProv2.getProviderName());
Assert.assertFalse(authProv2.isPasswordUpdateSupported());
Assert.assertEquals("trustedRealm", authProv2.getConfig().get("externalRealmId"));
Assert.assertEquals(AuthProviderConstants.PROVIDER_NAME_PICKETLINK, authProv3.getProviderName());
Assert.assertTrue(authProv3.isPasswordUpdateSupported());
// Test authentication linking
AuthenticationLinkModel authLink = socialUser.getAuthenticationLink();
Assert.assertEquals(AuthProviderConstants.PROVIDER_NAME_PICKETLINK, authLink.getAuthProvider());
Assert.assertEquals("myUser1", authLink.getAuthUserId());
}
@Test

View File

@@ -12,34 +12,10 @@
"host": "localhost",
"port":"3025"
},
"ldapServer": {
"connectionUrl": "ldap://localhost:10389",
"baseDn": "dc=keycloak,dc=org",
"userDnSuffix": "ou=People,dc=keycloak,dc=org",
"bindDn": "uid=admin,ou=system",
"bindCredential": "secret",
"vendor": "other"
},
"socialProviders": {
"google.key": "abc",
"google.secret": "def"
},
"authenticationProviders": [
{
"providerName": "model"
},
{
"providerName": "externalModel",
"passwordUpdateSupported": false,
"config": {
"externalRealmId": "trustedRealm"
}
},
{
"providerName": "picketlink",
"passwordUpdateSupported": true
}
],
"users": [
{
"username": "wburke",
@@ -86,10 +62,6 @@
{
"username": "mySocialUser",
"enabled": true,
"authenticationLink": {
"authProvider": "picketlink",
"authUserId": "myUser1"
},
"socialLinks": [
{
"socialProvider": "facebook",