Skip to content

Commit

Permalink
LDAP fixes + added authType to UI to allow users specify authType
Browse files Browse the repository at this point in the history
  • Loading branch information
mposolda committed May 28, 2015
1 parent bcd607a commit e83de89
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 20 deletions.
Expand Up @@ -12,7 +12,6 @@


import org.keycloak.models.LDAPConstants; import org.keycloak.models.LDAPConstants;
import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;


/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
Expand All @@ -37,8 +36,12 @@ public String getFactoryName() {
} }


public String getAuthType() { public String getAuthType() {
// hardcoded for now String value = config.get(LDAPConstants.AUTH_TYPE);
return "simple"; if (value == null) {
return LDAPConstants.AUTH_TYPE_SIMPLE;
} else {
return value;
}
} }


public String getSecurityProtocol() { public String getSecurityProtocol() {
Expand Down Expand Up @@ -70,7 +73,7 @@ public Collection<String> getUserObjectClasses() {
String[] objectClasses = objClassesStr.split(","); String[] objectClasses = objClassesStr.split(",");


// Trim them // Trim them
Set<String> userObjClasses = new HashSet<String>(); Set<String> userObjClasses = new HashSet<>();
for (int i=0 ; i<objectClasses.length ; i++) { for (int i=0 ; i<objectClasses.length ; i++) {
userObjClasses.add(objectClasses[i].trim()); userObjClasses.add(objectClasses[i].trim());
} }
Expand Down
Expand Up @@ -106,7 +106,7 @@ protected UserModel proxy(RealmModel realm, UserModel local, LDAPObject ldapObje
proxied = new UnsyncedLDAPUserModelDelegate(local, this); proxied = new UnsyncedLDAPUserModelDelegate(local, this);
} }


Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappersByFederationProvider(model.getId());
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel); LDAPFederationMapper ldapMapper = getMapper(mapperModel);
proxied = ldapMapper.proxy(mapperModel, this, ldapObject, proxied, realm); proxied = ldapMapper.proxy(mapperModel, this, ldapObject, proxied, realm);
Expand Down Expand Up @@ -263,7 +263,7 @@ protected UserModel importUserFromLDAP(RealmModel realm, LDAPObject ldapUser) {
UserModel imported = session.userStorage().addUser(realm, ldapUsername); UserModel imported = session.userStorage().addUser(realm, ldapUsername);
imported.setEnabled(true); imported.setEnabled(true);


Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappersByFederationProvider(getModel().getId());
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel); LDAPFederationMapper ldapMapper = getMapper(mapperModel);
ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, imported, realm, true); ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, imported, realm, true);
Expand Down Expand Up @@ -399,7 +399,7 @@ protected UserFederationSyncResult importLDAPUsers(RealmModel realm, List<LDAPOb
if ((fedModel.getId().equals(currentUser.getFederationLink())) && (ldapUser.getUuid().equals(currentUser.getAttribute(LDAPConstants.LDAP_ID)))) { if ((fedModel.getId().equals(currentUser.getFederationLink())) && (ldapUser.getUuid().equals(currentUser.getAttribute(LDAPConstants.LDAP_ID)))) {


// Update keycloak user // Update keycloak user
Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappers(); Set<UserFederationMapperModel> federationMappers = realm.getUserFederationMappersByFederationProvider(model.getId());
for (UserFederationMapperModel mapperModel : federationMappers) { for (UserFederationMapperModel mapperModel : federationMappers) {
LDAPFederationMapper ldapMapper = getMapper(mapperModel); LDAPFederationMapper ldapMapper = getMapper(mapperModel);
ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, currentUser, realm, false); ldapMapper.onImportUserFromLDAP(mapperModel, this, ldapUser, currentUser, realm, false);
Expand Down
Expand Up @@ -62,7 +62,7 @@ public static LDAPIdentityQuery createQueryForUserSearch(LDAPFederationProvider
ldapQuery.addSearchDns(config.getUserDns()); ldapQuery.addSearchDns(config.getUserDns());
ldapQuery.addObjectClasses(config.getUserObjectClasses()); ldapQuery.addObjectClasses(config.getUserObjectClasses());


Set<UserFederationMapperModel> mapperModels = realm.getUserFederationMappers(); Set<UserFederationMapperModel> mapperModels = realm.getUserFederationMappersByFederationProvider(ldapProvider.getModel().getId());
ldapQuery.addMappers(mapperModels); ldapQuery.addMappers(mapperModels);


return ldapQuery; return ldapQuery;
Expand Down
Expand Up @@ -108,7 +108,7 @@ public void remove(LDAPObject ldapObject) {


@Override @Override
public List<LDAPObject> fetchQueryResults(LDAPIdentityQuery identityQuery) { public List<LDAPObject> fetchQueryResults(LDAPIdentityQuery identityQuery) {
List<LDAPObject> results = new ArrayList<LDAPObject>(); List<LDAPObject> results = new ArrayList<>();


try { try {
if (identityQuery.getSorting() != null && !identityQuery.getSorting().isEmpty()) { if (identityQuery.getSorting() != null && !identityQuery.getSorting().isEmpty()) {
Expand Down Expand Up @@ -153,7 +153,7 @@ public List<LDAPObject> fetchQueryResults(LDAPIdentityQuery identityQuery) {
} }
} }
} catch (Exception e) { } catch (Exception e) {
throw new ModelException("Querying of identity type failed " + identityQuery, e); throw new ModelException("Querying of LDAP failed " + identityQuery, e);
} }


return results; return results;
Expand Down Expand Up @@ -382,7 +382,7 @@ private LDAPObject populateAttributedType(SearchResult searchResult, Collection<
NamingEnumeration<? extends Attribute> ldapAttributes = attributes.getAll(); NamingEnumeration<? extends Attribute> ldapAttributes = attributes.getAll();


// Exact name of attributes might be different // Exact name of attributes might be different
List<String> uppercasedReadOnlyAttrNames = new ArrayList<String>(); List<String> uppercasedReadOnlyAttrNames = new ArrayList<>();
for (String readonlyAttr : readOnlyAttrNames) { for (String readonlyAttr : readOnlyAttrNames) {
uppercasedReadOnlyAttrNames.add(readonlyAttr.toUpperCase()); uppercasedReadOnlyAttrNames.add(readonlyAttr.toUpperCase());
} }
Expand All @@ -402,11 +402,11 @@ private LDAPObject populateAttributedType(SearchResult searchResult, Collection<
Object uuidValue = ldapAttribute.get(); Object uuidValue = ldapAttribute.get();
ldapObject.setUuid(this.operationManager.decodeEntryUUID(uuidValue)); ldapObject.setUuid(this.operationManager.decodeEntryUUID(uuidValue));
} else { } else {
Set<String> attrValues = new TreeSet<String>(); Set<String> attrValues = new TreeSet<>();
NamingEnumeration<?> enumm = ldapAttribute.getAll(); NamingEnumeration<?> enumm = ldapAttribute.getAll();
while (enumm.hasMoreElements()) { while (enumm.hasMoreElements()) {
String objectClass = enumm.next().toString(); String attrVal = enumm.next().toString();
attrValues.add(objectClass); attrValues.add(attrVal);
} }


if (ldapAttributeName.toLowerCase().equals(LDAPConstants.OBJECT_CLASS)) { if (ldapAttributeName.toLowerCase().equals(LDAPConstants.OBJECT_CLASS)) {
Expand Down
Expand Up @@ -451,8 +451,9 @@ private LdapContext createLdapContext() throws NamingException {
private Map<String, Object> createConnectionProperties() { private Map<String, Object> createConnectionProperties() {
HashMap<String, Object> env = new HashMap<String, Object>(); HashMap<String, Object> env = new HashMap<String, Object>();


String authType = this.config.getAuthType();
env.put(Context.INITIAL_CONTEXT_FACTORY, this.config.getFactoryName()); env.put(Context.INITIAL_CONTEXT_FACTORY, this.config.getFactoryName());
env.put(Context.SECURITY_AUTHENTICATION, this.config.getAuthType()); env.put(Context.SECURITY_AUTHENTICATION, authType);


String protocol = this.config.getSecurityProtocol(); String protocol = this.config.getSecurityProtocol();


Expand All @@ -468,7 +469,7 @@ private Map<String, Object> createConnectionProperties() {
bindCredential = this.config.getBindCredential().toCharArray(); bindCredential = this.config.getBindCredential().toCharArray();
} }


if (bindDN != null) { if (!LDAPConstants.AUTH_TYPE_NONE.equals(authType)) {
env.put(Context.SECURITY_PRINCIPAL, bindDN); env.put(Context.SECURITY_PRINCIPAL, bindDN);
env.put(Context.SECURITY_CREDENTIALS, bindCredential); env.put(Context.SECURITY_CREDENTIALS, bindCredential);
} }
Expand Down
Expand Up @@ -541,6 +541,7 @@ module.controller('LDAPCtrl', function($scope, $location, $route, Notifications,
instance.config.debug = false; instance.config.debug = false;
instance.config.useKerberosForPasswordAuthentication = false; instance.config.useKerberosForPasswordAuthentication = false;


instance.config.authType = 'simple';
instance.config.batchSizeForSync = DEFAULT_BATCH_SIZE; instance.config.batchSizeForSync = DEFAULT_BATCH_SIZE;
instance.config.searchScope = "1"; instance.config.searchScope = "1";


Expand All @@ -556,12 +557,16 @@ module.controller('LDAPCtrl', function($scope, $location, $route, Notifications,
instance.config.debug = (instance.config.debug === 'true' || instance.config.debug === true); instance.config.debug = (instance.config.debug === 'true' || instance.config.debug === true);
instance.config.useKerberosForPasswordAuthentication = (instance.config.useKerberosForPasswordAuthentication === 'true' || instance.config.useKerberosForPasswordAuthentication === true); instance.config.useKerberosForPasswordAuthentication = (instance.config.useKerberosForPasswordAuthentication === 'true' || instance.config.useKerberosForPasswordAuthentication === true);


if (!instance.config.authType) {
instance.config.authType = 'simple';
}
if (!instance.config.batchSizeForSync) { if (!instance.config.batchSizeForSync) {
instance.config.batchSizeForSync = DEFAULT_BATCH_SIZE; instance.config.batchSizeForSync = DEFAULT_BATCH_SIZE;
} }
if (!instance.config.searchScope) { if (!instance.config.searchScope) {
instance.config.searchScope = "1"; instance.config.searchScope = '1';
} }

$scope.fullSyncEnabled = (instance.fullSyncPeriod && instance.fullSyncPeriod > 0); $scope.fullSyncEnabled = (instance.fullSyncPeriod && instance.fullSyncPeriod > 0);
$scope.changedSyncEnabled = (instance.changedSyncPeriod && instance.changedSyncPeriod > 0); $scope.changedSyncEnabled = (instance.changedSyncPeriod && instance.changedSyncPeriod > 0);
} }
Expand All @@ -581,6 +586,11 @@ module.controller('LDAPCtrl', function($scope, $location, $route, Notifications,
{ "id": "other", "name": "Other" } { "id": "other", "name": "Other" }
]; ];


$scope.authTypes = [
{ "id": "none", "name": "none" },
{ "id": "simple", "name": "simple" }
];

$scope.searchScopes = [ $scope.searchScopes = [
{ "id": "1", "name": "One Level" }, { "id": "1", "name": "One Level" },
{ "id": "2", "name": "Subtree" } { "id": "2", "name": "Subtree" }
Expand Down
Expand Up @@ -119,16 +119,29 @@ <h1 data-ng-show="create"><strong>Add LDAP User Federation Provider</strong></h1
</kc-tooltip> </kc-tooltip>
</div> </div>
<div class="form-group clearfix"> <div class="form-group clearfix">
<label class="col-md-2 control-label" for="authType"><span class="required">*</span> Authentication Type</label>
<div class="col-md-6">
<div>
<select class="form-control" id="authType"
ng-model="instance.config.authType"
ng-options="authType.id as authType.name for authType in authTypes"
required>
</select>
</div>
</div>
<kc-tooltip>LDAP Authentication type. Right now just 'none' (anonymous LDAP authentication) or 'simple' (Bind credential + Bind password authentication) mechanisms are available</kc-tooltip>
</div>
<div class="form-group clearfix" data-ng-hide="instance.config.authType == 'none'">
<label class="col-md-2 control-label" for="ldapBindDn"><span class="required">*</span> Bind DN</label> <label class="col-md-2 control-label" for="ldapBindDn"><span class="required">*</span> Bind DN</label>
<div class="col-md-6"> <div class="col-md-6">
<input class="form-control" id="ldapBindDn" type="text" ng-model="instance.config.bindDn" placeholder="LDAP Bind DN" required> <input class="form-control" id="ldapBindDn" type="text" ng-model="instance.config.bindDn" placeholder="LDAP Bind DN" data-ng-required="instance.config.authType != 'none'">
</div> </div>
<kc-tooltip>DN of LDAP admin, which will be used by Keycloak to access LDAP server</kc-tooltip> <kc-tooltip>DN of LDAP admin, which will be used by Keycloak to access LDAP server</kc-tooltip>
</div> </div>
<div class="form-group clearfix"> <div class="form-group clearfix" data-ng-hide="instance.config.authType == 'none'">
<label class="col-md-2 control-label" for="ldapBindCredential"><span class="required">*</span> Bind Credential</label> <label class="col-md-2 control-label" for="ldapBindCredential"><span class="required">*</span> Bind Credential</label>
<div class="col-md-6"> <div class="col-md-6">
<input class="form-control" id="ldapBindCredential" type="password" ng-model="instance.config.bindCredential" placeholder="LDAP Bind Credentials" required> <input class="form-control" id="ldapBindCredential" type="password" ng-model="instance.config.bindCredential" placeholder="LDAP Bind Credentials" data-ng-required="instance.config.authType != 'none'">
</div> </div>
<kc-tooltip>Password of LDAP admin</kc-tooltip> <kc-tooltip>Password of LDAP admin</kc-tooltip>
<div class="col-sm-4" data-ng-show="access.manageRealm"> <div class="col-sm-4" data-ng-show="access.manageRealm">
Expand Down
Expand Up @@ -23,6 +23,10 @@ public class LDAPConstants {
public static final String BIND_DN = "bindDn"; public static final String BIND_DN = "bindDn";
public static final String BIND_CREDENTIAL = "bindCredential"; public static final String BIND_CREDENTIAL = "bindCredential";


public static final String AUTH_TYPE = "authType";
public static final String AUTH_TYPE_NONE = "none";
public static final String AUTH_TYPE_SIMPLE = "simple";

public static final String SEARCH_SCOPE = "searchScope"; public static final String SEARCH_SCOPE = "searchScope";
public static final String CONNECTION_POOLING = "connectionPooling"; public static final String CONNECTION_POOLING = "connectionPooling";
public static final String PAGINATION = "pagination"; public static final String PAGINATION = "pagination";
Expand Down

0 comments on commit e83de89

Please sign in to comment.