federation iteration 1 complete
This commit is contained in:
parent
171e9b1ce9
commit
43d08f2d05
10 changed files with 307 additions and 15 deletions
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.federation.ldap;
|
package org.keycloak.federation.ldap;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.FederationProvider;
|
import org.keycloak.models.FederationProvider;
|
||||||
import org.keycloak.models.FederationProviderModel;
|
import org.keycloak.models.FederationProviderModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -14,6 +15,7 @@ import org.picketlink.idm.IdentityManager;
|
||||||
import org.picketlink.idm.PartitionManager;
|
import org.picketlink.idm.PartitionManager;
|
||||||
import org.picketlink.idm.credential.Credentials;
|
import org.picketlink.idm.credential.Credentials;
|
||||||
import org.picketlink.idm.credential.Password;
|
import org.picketlink.idm.credential.Password;
|
||||||
|
import org.picketlink.idm.credential.TOTPCredential;
|
||||||
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
||||||
import org.picketlink.idm.model.basic.BasicModel;
|
import org.picketlink.idm.model.basic.BasicModel;
|
||||||
import org.picketlink.idm.model.basic.User;
|
import org.picketlink.idm.model.basic.User;
|
||||||
|
@ -31,6 +33,8 @@ import static org.picketlink.idm.IDMMessages.MESSAGES;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class LDAPFederationProvider implements FederationProvider {
|
public class LDAPFederationProvider implements FederationProvider {
|
||||||
|
private static final Logger logger = Logger.getLogger(LDAPFederationProvider.class);
|
||||||
|
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
protected FederationProviderModel model;
|
protected FederationProviderModel model;
|
||||||
protected PartitionManager partitionManager;
|
protected PartitionManager partitionManager;
|
||||||
|
@ -73,7 +77,7 @@ public class LDAPFederationProvider implements FederationProvider {
|
||||||
@Override
|
@Override
|
||||||
public UserModel proxy(UserModel local) {
|
public UserModel proxy(UserModel local) {
|
||||||
// todo
|
// todo
|
||||||
return local;
|
return new LDAPUserModelDelegate(local, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,11 +181,12 @@ public class LDAPFederationProvider implements FederationProvider {
|
||||||
protected UserModel importUserFromPicketlink(RealmModel realm, User picketlinkUser) {
|
protected UserModel importUserFromPicketlink(RealmModel realm, User picketlinkUser) {
|
||||||
String email = (picketlinkUser.getEmail() != null && picketlinkUser.getEmail().trim().length() > 0) ? picketlinkUser.getEmail() : null;
|
String email = (picketlinkUser.getEmail() != null && picketlinkUser.getEmail().trim().length() > 0) ? picketlinkUser.getEmail() : null;
|
||||||
UserModel imported = session.userStorage().addUser(realm, picketlinkUser.getLoginName());
|
UserModel imported = session.userStorage().addUser(realm, picketlinkUser.getLoginName());
|
||||||
|
imported.setEnabled(true);
|
||||||
imported.setEmail(email);
|
imported.setEmail(email);
|
||||||
imported.setFirstName(picketlinkUser.getFirstName());
|
imported.setFirstName(picketlinkUser.getFirstName());
|
||||||
imported.setLastName(picketlinkUser.getLastName());
|
imported.setLastName(picketlinkUser.getLastName());
|
||||||
imported.setFederationLink(model.getId());
|
imported.setFederationLink(model.getId());
|
||||||
return imported;
|
return proxy(imported);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected User queryByEmail(IdentityManager identityManager, String email) throws IdentityManagementException {
|
protected User queryByEmail(IdentityManager identityManager, String email) throws IdentityManagementException {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class LDAPFederationProviderFactory implements FederationProviderFactory {
|
public class LDAPFederationProviderFactory implements FederationProviderFactory {
|
||||||
|
public static final String PROVIDER_NAME = "ldap";
|
||||||
PartitionManagerRegistry registry;
|
PartitionManagerRegistry registry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,6 +42,6 @@ public class LDAPFederationProviderFactory implements FederationProviderFactory
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "ldap";
|
return PROVIDER_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.federation.ldap;
|
package org.keycloak.federation.ldap;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.AuthenticationLinkModel;
|
import org.keycloak.models.AuthenticationLinkModel;
|
||||||
import org.keycloak.models.FederationProviderModel;
|
import org.keycloak.models.FederationProviderModel;
|
||||||
|
@ -10,6 +11,8 @@ import org.keycloak.models.UserCredentialValueModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.picketlink.idm.IdentityManagementException;
|
import org.picketlink.idm.IdentityManagementException;
|
||||||
import org.picketlink.idm.IdentityManager;
|
import org.picketlink.idm.IdentityManager;
|
||||||
|
import org.picketlink.idm.credential.Password;
|
||||||
|
import org.picketlink.idm.credential.TOTPCredential;
|
||||||
import org.picketlink.idm.model.basic.BasicModel;
|
import org.picketlink.idm.model.basic.BasicModel;
|
||||||
import org.picketlink.idm.model.basic.User;
|
import org.picketlink.idm.model.basic.User;
|
||||||
|
|
||||||
|
@ -21,62 +24,83 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class LDAPUserModelDelegate {
|
public class LDAPUserModelDelegate implements UserModel {
|
||||||
|
private static final Logger logger = Logger.getLogger(LDAPUserModelDelegate.class);
|
||||||
|
|
||||||
protected UserModel delegate;
|
protected UserModel delegate;
|
||||||
protected LDAPFederationProvider provider;
|
protected LDAPFederationProvider provider;
|
||||||
|
|
||||||
|
public LDAPUserModelDelegate(UserModel delegate, LDAPFederationProvider provider) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return delegate.getId();
|
return delegate.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setAttribute(String name, String value) {
|
public void setAttribute(String name, String value) {
|
||||||
delegate.setAttribute(name, value);
|
delegate.setAttribute(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isEmailVerified() {
|
public boolean isEmailVerified() {
|
||||||
return delegate.isEmailVerified();
|
return delegate.isEmailVerified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void removeAttribute(String name) {
|
public void removeAttribute(String name) {
|
||||||
delegate.removeAttribute(name);
|
delegate.removeAttribute(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getLastName() {
|
public String getLastName() {
|
||||||
return delegate.getLastName();
|
return delegate.getLastName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setFederationLink(String link) {
|
public void setFederationLink(String link) {
|
||||||
delegate.setFederationLink(link);
|
delegate.setFederationLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public AuthenticationLinkModel getAuthenticationLink() {
|
public AuthenticationLinkModel getAuthenticationLink() {
|
||||||
return delegate.getAuthenticationLink();
|
return delegate.getAuthenticationLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, String> getAttributes() {
|
public Map<String, String> getAttributes() {
|
||||||
return delegate.getAttributes();
|
return delegate.getAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean hasRole(RoleModel role) {
|
public boolean hasRole(RoleModel role) {
|
||||||
return delegate.hasRole(role);
|
return delegate.hasRole(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void grantRole(RoleModel role) {
|
public void grantRole(RoleModel role) {
|
||||||
delegate.grantRole(role);
|
delegate.grantRole(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
delegate.setEnabled(enabled);
|
delegate.setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void removeRequiredAction(UserModel.RequiredAction action) {
|
public void removeRequiredAction(UserModel.RequiredAction action) {
|
||||||
delegate.removeRequiredAction(action);
|
delegate.removeRequiredAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void deleteRoleMapping(RoleModel role) {
|
public void deleteRoleMapping(RoleModel role) {
|
||||||
delegate.deleteRoleMapping(role);
|
delegate.deleteRoleMapping(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setUsername(String username) {
|
public void setUsername(String username) {
|
||||||
IdentityManager identityManager = provider.getIdentityManager();
|
IdentityManager identityManager = provider.getIdentityManager();
|
||||||
|
|
||||||
|
@ -93,14 +117,17 @@ public class LDAPUserModelDelegate {
|
||||||
delegate.setUsername(username);
|
delegate.setUsername(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return delegate.isEnabled();
|
return delegate.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
return delegate.getFirstName();
|
return delegate.getFirstName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setLastName(String lastName) {
|
public void setLastName(String lastName) {
|
||||||
IdentityManager identityManager = provider.getIdentityManager();
|
IdentityManager identityManager = provider.getIdentityManager();
|
||||||
|
|
||||||
|
@ -117,14 +144,39 @@ public class LDAPUserModelDelegate {
|
||||||
delegate.setLastName(lastName);
|
delegate.setLastName(lastName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setEmailVerified(boolean verified) {
|
public void setEmailVerified(boolean verified) {
|
||||||
delegate.setEmailVerified(verified);
|
delegate.setEmailVerified(verified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateCredential(UserCredentialModel cred) {
|
public void updateCredential(UserCredentialModel cred) {
|
||||||
delegate.updateCredential(cred);
|
if (!provider.getSupportedCredentialTypes().contains(cred.getType())) {
|
||||||
|
delegate.updateCredential(cred);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IdentityManager identityManager = provider.getIdentityManager();
|
||||||
|
|
||||||
|
try {
|
||||||
|
User picketlinkUser = BasicModel.getUser(identityManager, getUsername());
|
||||||
|
if (picketlinkUser == null) {
|
||||||
|
logger.debugf("User '%s' doesn't exists. Skip password update", getUsername());
|
||||||
|
throw new IllegalStateException("User doesn't exist in LDAP storage");
|
||||||
|
}
|
||||||
|
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
|
||||||
|
identityManager.updateCredential(picketlinkUser, new Password(cred.getValue().toCharArray()));
|
||||||
|
} else if (cred.getType().equals(UserCredentialModel.TOTP)) {
|
||||||
|
TOTPCredential credential = new TOTPCredential(cred.getValue());
|
||||||
|
credential.setDevice(cred.getDevice());
|
||||||
|
identityManager.updateCredential(picketlinkUser, credential);
|
||||||
|
}
|
||||||
|
} catch (IdentityManagementException ie) {
|
||||||
|
throw new ModelException(ie);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setEmail(String email) {
|
public void setEmail(String email) {
|
||||||
IdentityManager identityManager = provider.getIdentityManager();
|
IdentityManager identityManager = provider.getIdentityManager();
|
||||||
|
|
||||||
|
@ -141,62 +193,77 @@ public class LDAPUserModelDelegate {
|
||||||
delegate.setEmail(email);
|
delegate.setEmail(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addRequiredAction(UserModel.RequiredAction action) {
|
public void addRequiredAction(UserModel.RequiredAction action) {
|
||||||
delegate.addRequiredAction(action);
|
delegate.addRequiredAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<UserCredentialValueModel> getCredentialsDirectly() {
|
public List<UserCredentialValueModel> getCredentialsDirectly() {
|
||||||
return delegate.getCredentialsDirectly();
|
return delegate.getCredentialsDirectly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isTotp() {
|
public boolean isTotp() {
|
||||||
return delegate.isTotp();
|
return delegate.isTotp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setFirstName(String firstName) {
|
public void setFirstName(String firstName) {
|
||||||
delegate.setFirstName(firstName);
|
delegate.setFirstName(firstName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<UserModel.RequiredAction> getRequiredActions() {
|
public Set<UserModel.RequiredAction> getRequiredActions() {
|
||||||
return delegate.getRequiredActions();
|
return delegate.getRequiredActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
return delegate.getEmail();
|
return delegate.getEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setTotp(boolean totp) {
|
public void setTotp(boolean totp) {
|
||||||
delegate.setTotp(totp);
|
delegate.setTotp(totp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setAuthenticationLink(AuthenticationLinkModel authenticationLink) {
|
public void setAuthenticationLink(AuthenticationLinkModel authenticationLink) {
|
||||||
delegate.setAuthenticationLink(authenticationLink);
|
delegate.setAuthenticationLink(authenticationLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return delegate.getUsername();
|
return delegate.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getFederationLink() {
|
public String getFederationLink() {
|
||||||
return delegate.getFederationLink();
|
return delegate.getFederationLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<RoleModel> getRealmRoleMappings() {
|
public Set<RoleModel> getRealmRoleMappings() {
|
||||||
return delegate.getRealmRoleMappings();
|
return delegate.getRealmRoleMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<RoleModel> getRoleMappings() {
|
public Set<RoleModel> getRoleMappings() {
|
||||||
return delegate.getRoleMappings();
|
return delegate.getRoleMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
|
public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
|
||||||
return delegate.getApplicationRoleMappings(app);
|
return delegate.getApplicationRoleMappings(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getAttribute(String name) {
|
public String getAttribute(String name) {
|
||||||
return delegate.getAttribute(name);
|
return delegate.getAttribute(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateCredentialDirectly(UserCredentialValueModel cred) {
|
public void updateCredentialDirectly(UserCredentialValueModel cred) {
|
||||||
delegate.updateCredentialDirectly(cred);
|
delegate.updateCredentialDirectly(cred);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
org.keycloak.federation.ldap.LDAPFederationProviderFactory
|
|
@ -96,7 +96,7 @@ public class FederationManager implements UserProvider {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
||||||
FederationProvider fed = session.getProvider(FederationProvider.class, federation.getProviderName());
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
user = fed.getUserById(id, realm);
|
user = fed.getUserById(id, realm);
|
||||||
if (user != null) return user;
|
if (user != null) return user;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public class FederationManager implements UserProvider {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
||||||
FederationProvider fed = session.getProvider(FederationProvider.class, federation.getProviderName());
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
user = fed.getUserByUsername(username, realm);
|
user = fed.getUserByUsername(username, realm);
|
||||||
if (user != null) return user;
|
if (user != null) return user;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ public class FederationManager implements UserProvider {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
||||||
FederationProvider fed = session.getProvider(FederationProvider.class, federation.getProviderName());
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
user = fed.getUserByEmail(email, realm);
|
user = fed.getUserByEmail(email, realm);
|
||||||
if (user != null) return user;
|
if (user != null) return user;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ public class FederationManager implements UserProvider {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
List<FederationProviderModel> federationProviders = realm.getFederationProviders();
|
List<FederationProviderModel> federationProviders = realm.getFederationProviders();
|
||||||
for (int i = federationProviders.size(); i >= 0; i--) {
|
for (int i = federationProviders.size() - 1; i >= 0; i--) {
|
||||||
FederationProviderModel federation = federationProviders.get(i);
|
FederationProviderModel federation = federationProviders.get(i);
|
||||||
FederationProvider fed = getFederationProvider(federation);
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
query = fed.getUsers(realm, firstResult, maxResults);
|
query = fed.getUsers(realm, firstResult, maxResults);
|
||||||
|
@ -220,7 +220,7 @@ public class FederationManager implements UserProvider {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
List<FederationProviderModel> federationProviders = realm.getFederationProviders();
|
List<FederationProviderModel> federationProviders = realm.getFederationProviders();
|
||||||
for (int i = federationProviders.size(); i >= 0; i--) {
|
for (int i = federationProviders.size() - 1; i >= 0; i--) {
|
||||||
FederationProviderModel federation = federationProviders.get(i);
|
FederationProviderModel federation = federationProviders.get(i);
|
||||||
FederationProvider fed = getFederationProvider(federation);
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
query = fed.searchForUser(search, realm, firstResult, maxResults);
|
query = fed.searchForUser(search, realm, firstResult, maxResults);
|
||||||
|
@ -254,7 +254,7 @@ public class FederationManager implements UserProvider {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
List<FederationProviderModel> federationProviders = realm.getFederationProviders();
|
List<FederationProviderModel> federationProviders = realm.getFederationProviders();
|
||||||
for (int i = federationProviders.size(); i >= 0; i--) {
|
for (int i = federationProviders.size() - 1; i >= 0; i--) {
|
||||||
FederationProviderModel federation = federationProviders.get(i);
|
FederationProviderModel federation = federationProviders.get(i);
|
||||||
FederationProvider fed = getFederationProvider(federation);
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
query = fed.searchForUserByAttributes(attributes, realm, firstResult, maxResults);
|
query = fed.searchForUserByAttributes(attributes, realm, firstResult, maxResults);
|
||||||
|
@ -286,7 +286,7 @@ public class FederationManager implements UserProvider {
|
||||||
@Override
|
@Override
|
||||||
public void preRemove(RealmModel realm) {
|
public void preRemove(RealmModel realm) {
|
||||||
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
||||||
FederationProvider fed = session.getProvider(FederationProvider.class, federation.getProviderName());
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
fed.preRemove(realm);
|
fed.preRemove(realm);
|
||||||
}
|
}
|
||||||
session.userStorage().preRemove(realm);
|
session.userStorage().preRemove(realm);
|
||||||
|
@ -295,7 +295,7 @@ public class FederationManager implements UserProvider {
|
||||||
@Override
|
@Override
|
||||||
public void preRemove(RealmModel realm, RoleModel role) {
|
public void preRemove(RealmModel realm, RoleModel role) {
|
||||||
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
for (FederationProviderModel federation : realm.getFederationProviders()) {
|
||||||
FederationProvider fed = session.getProvider(FederationProvider.class, federation.getProviderName());
|
FederationProvider fed = getFederationProvider(federation);
|
||||||
fed.preRemove(realm, role);
|
fed.preRemove(realm, role);
|
||||||
}
|
}
|
||||||
session.userStorage().preRemove(realm, role);
|
session.userStorage().preRemove(realm, role);
|
||||||
|
@ -328,11 +328,12 @@ public class FederationManager implements UserProvider {
|
||||||
public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
|
public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
|
||||||
FederationProvider link = getFederationLink(realm, user);
|
FederationProvider link = getFederationLink(realm, user);
|
||||||
if (link != null) {
|
if (link != null) {
|
||||||
if (link.getSupportedCredentialTypes().size() > 0) {
|
Set<String> supportedCredentialTypes = link.getSupportedCredentialTypes();
|
||||||
|
if (supportedCredentialTypes.size() > 0) {
|
||||||
List<UserCredentialModel> fedCreds = new ArrayList<UserCredentialModel>();
|
List<UserCredentialModel> fedCreds = new ArrayList<UserCredentialModel>();
|
||||||
List<UserCredentialModel> localCreds = new ArrayList<UserCredentialModel>();
|
List<UserCredentialModel> localCreds = new ArrayList<UserCredentialModel>();
|
||||||
for (UserCredentialModel cred : input) {
|
for (UserCredentialModel cred : input) {
|
||||||
if (fedCreds.contains(cred.getType())) {
|
if (supportedCredentialTypes.contains(cred.getType())) {
|
||||||
fedCreds.add(cred);
|
fedCreds.add(cred);
|
||||||
} else {
|
} else {
|
||||||
localCreds.add(cred);
|
localCreds.add(cred);
|
||||||
|
|
27
model/api/src/main/java/org/keycloak/models/FederationSpi.java
Executable file
27
model/api/src/main/java/org/keycloak/models/FederationSpi.java
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
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 FederationSpi implements Spi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "federation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Provider> getProviderClass() {
|
||||||
|
return FederationProvider.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
|
return FederationProviderFactory.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
org.keycloak.models.FederationSpi
|
||||||
org.keycloak.models.RealmSpi
|
org.keycloak.models.RealmSpi
|
||||||
org.keycloak.models.UserSessionSpi
|
org.keycloak.models.UserSessionSpi
|
||||||
org.keycloak.models.UserSpi
|
org.keycloak.models.UserSpi
|
|
@ -255,6 +255,7 @@ public class AuthenticationManager {
|
||||||
|
|
||||||
protected AuthenticationStatus authenticateInternal(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, String username) {
|
protected AuthenticationStatus authenticateInternal(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, String username) {
|
||||||
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
|
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
AuthUser authUser = AuthenticationProviderManager.getManager(realm, session).getUser(username);
|
AuthUser authUser = AuthenticationProviderManager.getManager(realm, session).getUser(username);
|
||||||
if (authUser != null) {
|
if (authUser != null) {
|
||||||
|
|
|
@ -97,6 +97,11 @@
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-ldap-federation</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-undertow-adapter</artifactId>
|
<artifactId>keycloak-undertow-adapter</artifactId>
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
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.authentication.AuthProviderConstants;
|
||||||
|
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||||
|
import org.keycloak.model.test.LDAPEmbeddedServer;
|
||||||
|
import org.keycloak.model.test.LDAPTestUtils;
|
||||||
|
import org.keycloak.models.AuthenticationProviderModel;
|
||||||
|
import org.keycloak.models.FederationProviderModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
|
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.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 FederationProvidersIntegrationTest {
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
LDAPEmbeddedServer ldapServer = ldapRule.getEmbeddedServer();
|
||||||
|
Map<String,String> ldapConfig = new HashMap<String,String>();
|
||||||
|
ldapConfig.put(LDAPConstants.CONNECTION_URL, ldapServer.getConnectionUrl());
|
||||||
|
ldapConfig.put(LDAPConstants.BASE_DN, ldapServer.getBaseDn());
|
||||||
|
ldapConfig.put(LDAPConstants.BIND_DN, ldapServer.getBindDn());
|
||||||
|
ldapConfig.put(LDAPConstants.BIND_CREDENTIAL, ldapServer.getBindCredential());
|
||||||
|
ldapConfig.put(LDAPConstants.USER_DN_SUFFIX, ldapServer.getUserDnSuffix());
|
||||||
|
ldapConfig.put(LDAPConstants.VENDOR, ldapServer.getVendor());
|
||||||
|
|
||||||
|
|
||||||
|
FederationProviderModel ldapProvider = new FederationProviderModel(null, LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig);
|
||||||
|
appRealm.setFederationProviders(Arrays.asList(ldapProvider));
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@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.assertEquals("John", profilePage.getFirstName());
|
||||||
|
Assert.assertEquals("Doe", profilePage.getLastName());
|
||||||
|
Assert.assertEquals("john@email.org", profilePage.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@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", "email2", "registerUserSuccess2", "password", "password");
|
||||||
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue