Kerberos/LDAP fixes

This commit is contained in:
mposolda 2015-02-23 13:12:41 +01:00
parent 9dd5ecd464
commit 9f8b59dfb6
8 changed files with 29 additions and 36 deletions

View file

@ -210,17 +210,19 @@ public class KerberosFederationProvider implements UserFederationProvider {
UserModel user = session.userStorage().getUserByUsername(username, realm);
if (user != null) {
logger.debug("Kerberos authenticated user " + username + " found in Keycloak storage");
if (!isValid(user)) {
throw new IllegalStateException("User with username " + username + " already exists, but is not linked to provider [" + model.getDisplayName() +
"] or kerberos principal is not correct. Kerberos principal on user is: " + user.getAttribute(KERBEROS_PRINCIPAL));
}
if (isValid(user)) {
return proxy(user);
} else {
return importUserToKeycloak(realm, username);
logger.warn("User with username " + username + " already exists, but is not linked to provider [" + model.getDisplayName() +
"] or kerberos principal is not correct. Kerberos principal on user is: " + user.getAttribute(KERBEROS_PRINCIPAL));
session.userStorage().removeUser(realm, user);
}
}
logger.debug("Kerberos authenticated user " + username + " not in Keycloak storage. Creating him");
return importUserToKeycloak(realm, username);
}
protected UserModel importUserToKeycloak(RealmModel realm, String username) {
// Just guessing email from kerberos realm
String email = username + "@" + kerberosConfig.getKerberosRealm().toLowerCase();

View file

@ -47,14 +47,7 @@ public class SPNEGOAuthenticator {
Subject serverSubject = kerberosSubjectAuthenticator.authenticateServerSubject();
authenticated = Subject.doAs(serverSubject, new AcceptSecContext());
} catch (Exception e) {
String message = e.getMessage();
if (e instanceof PrivilegedActionException && e.getCause() != null) {
message = e.getCause().getMessage();
}
log.warn("SPNEGO login failed: " + message);
if (log.isDebugEnabled()) {
log.debug("SPNEGO login failed: " + message, e);
}
log.warn("SPNEGO login failed: " + e.getMessage(), e);
} finally {
kerberosSubjectAuthenticator.logoutServerSubject();
}

View file

@ -353,6 +353,11 @@ public class LDAPFederationProvider implements UserFederationProvider {
String username = spnegoAuthenticator.getAuthenticatedUsername();
UserModel user = findOrCreateAuthenticatedUser(realm, username);
if (user == null) {
logger.warn("Kerberos/SPNEGO authentication succeeded with username [" + username + "], but couldn't find or create user with federation provider [" + model.getDisplayName() + "]");
return CredentialValidationOutput.failed();
}
return new CredentialValidationOutput(user, CredentialValidationOutput.Status.AUTHENTICATED, state);
} else {
Map<String, Object> state = new HashMap<String, Object>();
@ -404,15 +409,17 @@ public class LDAPFederationProvider implements UserFederationProvider {
UserModel user = session.userStorage().getUserByUsername(username, realm);
if (user != null) {
logger.debug("Kerberos authenticated user " + username + " found in Keycloak storage");
if (!isValid(user)) {
throw new IllegalStateException("User with username " + username + " already exists, but is not linked to provider [" + model.getDisplayName() +
"] or LDAP_ID is not correct. LDAP_ID on user is: " + user.getAttribute(LDAP_ID));
}
if (isValid(user)) {
return proxy(user);
} else {
logger.warn("User with username " + username + " already exists, but is not linked to provider [" + model.getDisplayName() +
"] or LDAP_ID is not correct. Stale LDAP_ID on local user is: " + user.getAttribute(LDAP_ID));
session.userStorage().removeUser(realm, user);
}
}
// Creating user to local storage
logger.debug("Kerberos authenticated user " + username + " not in Keycloak storage. Creating him");
return getUserByUsername(realm, username);
}
}
}

View file

@ -547,10 +547,6 @@ module.controller('LDAPCtrl', function($scope, $location, Notifications, Dialog,
{ "id": "other", "name": "Other" }
];
$scope.usernameLDAPAttributes = [
"uid", "cn", "sAMAccountName", "entryDN"
];
$scope.realm = realm;
$scope.$watch('fullSyncEnabled', function(newVal, oldVal) {
@ -581,7 +577,7 @@ module.controller('LDAPCtrl', function($scope, $location, Notifications, Dialog,
$scope.lastVendor = $scope.instance.config.vendor;
if ($scope.lastVendor === "ad") {
$scope.instance.config.usernameLDAPAttribute = "cn";
$scope.instance.config.usernameLDAPAttribute = "sAMAccountName";
$scope.instance.config.userObjectClasses = "person, organizationalPerson, user";
} else {
$scope.instance.config.usernameLDAPAttribute = "uid";

View file

@ -78,15 +78,9 @@
<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="instance.config.usernameLDAPAttribute"
ng-options="usernameLDAPAttribute for usernameLDAPAttribute in usernameLDAPAttributes"
required>
</select>
<input class="form-control" id="usernameLDAPAttribute" type="text" ng-model="instance.config.usernameLDAPAttribute" placeholder="LDAP attribute for uid" required>
</div>
</div>
<span tooltip-placement="right" tooltip="Name of LDAP attribute, which is mapped as Keycloak username" class="fa fa-info-circle"></span>
<span tooltip-placement="right" tooltip="Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server vendors it's 'uid'. For Active directory it's usually 'sAMAccountName' or 'cn'" class="fa fa-info-circle"></span>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="userObjectClasses">User Object Classes<span class="required">*</span></label>

View file

@ -384,6 +384,7 @@ public class UserFederationManager implements UserProvider {
return CredentialValidationOutput.failed();
}
logger.debug("Found provider [" + providerSupportingCreds + "] supporting credentials of type " + cred.getType());
CredentialValidationOutput currentResult = providerSupportingCreds.validCredentials(realm, cred);
result = (result == null) ? currentResult : result.merge(currentResult);
}

View file

@ -140,7 +140,6 @@ public class HttpAuthenticationManager {
loginFormsProvider.setStatus(Response.Status.UNAUTHORIZED);
loginFormsProvider.setResponseHeader(HttpHeaders.WWW_AUTHENTICATE, negotiateHeader);
loginFormsProvider.setWarning("errorKerberosLogin");
}
});

View file

@ -2,6 +2,7 @@
default_realm = KEYCLOAK.ORG
default_tgs_enctypes = des3-cbc-sha1-kd rc4-hmac
default_tkt_enctypes = des3-cbc-sha1-kd rc4-hmac
permitted_enctypes = des3-cbc-sha1-kd rc4-hmac
kdc_timeout = 30000
dns_lookup_realm = false
dns_lookup_kdc = false