Kerberos/LDAP fixes
This commit is contained in:
parent
9dd5ecd464
commit
9f8b59dfb6
8 changed files with 29 additions and 36 deletions
|
@ -210,15 +210,17 @@ 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() +
|
||||
if (isValid(user)) {
|
||||
return proxy(user);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
return proxy(user);
|
||||
} else {
|
||||
return importUserToKeycloak(realm, username);
|
||||
}
|
||||
|
||||
logger.debug("Kerberos authenticated user " + username + " not in Keycloak storage. Creating him");
|
||||
return importUserToKeycloak(realm, username);
|
||||
}
|
||||
|
||||
protected UserModel importUserToKeycloak(RealmModel realm, String username) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
return proxy(user);
|
||||
} else {
|
||||
// Creating user to local storage
|
||||
return getUserByUsername(realm, username);
|
||||
}
|
||||
|
||||
// Creating user to local storage
|
||||
logger.debug("Kerberos authenticated user " + username + " not in Keycloak storage. Creating him");
|
||||
return getUserByUsername(realm, username);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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>
|
||||
</div>
|
||||
<input class="form-control" id="usernameLDAPAttribute" type="text" ng-model="instance.config.usernameLDAPAttribute" placeholder="LDAP attribute for uid" required>
|
||||
</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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -140,7 +140,6 @@ public class HttpAuthenticationManager {
|
|||
|
||||
loginFormsProvider.setStatus(Response.Status.UNAUTHORIZED);
|
||||
loginFormsProvider.setResponseHeader(HttpHeaders.WWW_AUTHENTICATE, negotiateHeader);
|
||||
loginFormsProvider.setWarning("errorKerberosLogin");
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue