Dear community,
we're locking out inactive i.e. disabled users. We use LDAP for authentication. We use Sakai 23.
This code section is what fails the login successfully:
[UserAuthnComponent.java]
...
// Check to see if the user account is disabled
String disabled = user.getProperties().getProperty("disabled");
if (disabled != null && "true".equals(disabled))
{
throw new AuthenticationException("Account Disabled: The user's authentication has been disabled");
}
However, if we then change the LDAP-criteria which marks if the user is disabled or not, this change has no effect due to caching:
BaseUserDirectoryService.java (line
public User getUserByEid(String eid) throws UserNotDefinedException
...
String id = m_storage.checkMapForId(eid);
if (id != null)
{
user = getCachedUser(userReference(id));
...
protected UserEdit getCachedUser(String ref)
{
// KNL-1241 removed caching in threadlocal
UserEdit userEdit = null;
if (m_callCache != null)
{
Object cachedRef = m_callCache.get(ref);
This cache is currently configured to keep rows in between 8 to 12 hours.
Clearing (all) caches via "Memory > Reset all caches" solves the issue.
I've tried to sketch the involved classes in a diagram. See appendix.
In there, I've diagnosed, that the authCache is not involved in this situation, but the m_storage and m_callCache is returning the User-object; Note, that the authentication itself is being done (successfully and would be mapping the LDAP-attribute to the User's disabled-property correctly), using that cached User-object. Our LDAP itself does allow binding, yet returns the LDAP-attribute responsible for calculating the "disabled"-property. - which is never used, since the old cached User-object is being returned instead.
I think it is wrong, that during login, any cached value inside BaseUserDirectoryService is being considered; Instead, each new login-attempt should always lead to consulting:
UnboundidDirectoryProvider.getUserByEid
What is your opinion on this?
Best regards,
Sebastian Riemer