Tuesday, August 18, 2009

Alfresco Impersonation

On my current project, we are using Alfresco and working on an integration with JBoss Portal. In this case we were building a component that allowed for the browsing, uploading, moving, renaming, and deleting of files. We had built all the Alfresco Web Scripts to support these operations. In order to ensure the proper auditing of the changes, we needed to implement a WebScripts component that performed impersonation of the user that was executing the action. After some Google searching, we found the following common solution to the problem:

public String impersonate(String username) {

String currentUser = AuthenticationUtil.getCurrentUserName();

if (currentUser == null || !currentUser.equals(username)) {
AuthenticationUtil.setCurrentUser(username);
}

return currentUser;
}

With this code the owner is set correctly, but the creator and modifier fields are not being set to the username we are impersonating. Furthermore, the permission checks (via hasPermission) were behaving correctly in that we were authenticating for the impersonated user. After some searching through the Alfresco API we had to change our impersonation code as follows:

public String impersonate(String username) {
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();

if (currentUser == null || !currentUser.equals(username)) {

AuthenticationUtil.setRunAsUser(username);
AuthenticationUtil.setFullyAuthenticatedUser(username);
}

return currentUser;
}

The reason the original solution did not work for us is because the Alfresco engine runs background processes on the content item to apply any rules that may be defined on the workspace. If you do not ensure that those background processes run in the impersonated user’s context, then they will run as the system account. Reading the new API calls is what made the light bulb go off in my head. The API setRunAsUser says that it switches to the given user for all authenticated operations and the API setFullyAuthenticatedUser places the guarantees that the given users are set for all operations. Therefore the combination of these two API calls guarantees that all operations will be run in the context of this user.

No comments:

Post a Comment