mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-25 16:42:34 +00:00
remove AuthenticationProvider/Link
This commit is contained in:
@@ -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>
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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> {
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
org.keycloak.authentication.AuthenticationSpi
|
||||
@@ -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>
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
org.keycloak.authentication.model.ModelAuthenticationProviderFactory
|
||||
org.keycloak.authentication.model.ExternalModelAuthenticationProviderFactory
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
org.keycloak.authentication.picketlink.PicketlinkAuthenticationProviderFactory
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
10
dependencies/server-all/pom.xml
vendored
10
dependencies/server-all/pom.xml
vendored
@@ -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>
|
||||
|
||||
12
dependencies/server-min/pom.xml
vendored
12
dependencies/server-min/pom.xml
vendored
@@ -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>
|
||||
|
||||
@@ -27,6 +27,5 @@
|
||||
<modules>
|
||||
<module>audit-listener-sysout</module>
|
||||
<module>audit-provider-mem</module>
|
||||
<module>authentication-properties</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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 $
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 : {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
<modules>
|
||||
<module>keycloak-picketlink-api</module>
|
||||
<module>keycloak-picketlink-realm</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
||||
1
pom.xml
1
pom.xml
@@ -96,7 +96,6 @@
|
||||
|
||||
<modules>
|
||||
<module>audit</module>
|
||||
<module>authentication</module>
|
||||
<module>core</module>
|
||||
<module>core-jaxrs</module>
|
||||
<module>connections</module>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -127,7 +127,7 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProvider users() {
|
||||
public UserFederationManager users() {
|
||||
return federationManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java
Normal file → Executable file
10
testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java
Normal file → Executable 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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class FederationProvidersIntegrationTest {
|
||||
|
||||
// Configure LDAP
|
||||
ldapRule.getEmbeddedServer().setupLdapInRealm(appRealm);
|
||||
LDAPTestUtils.setLdapPassword(session, appRealm, "johnkeycloak", "password");
|
||||
LDAPTestUtils.setLdapPassword(ldapConfig, "johnkeycloak", "password");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user