import java.security.Principal;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.jcr.RepositoryException;
import org.apache.jackrabbit.core.security.AnonymousPrincipal;
import org.apache.jackrabbit.core.security.SecurityConstants;
import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
-import org.argeo.ArgeoException;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
/** Integrates Spring Security and Jackrabbit Security user and roles. */
public class ArgeoSecurityManager extends DefaultSecurityManager {
- private Log log = LogFactory.getLog(ArgeoSecurityManager.class);
+ private final static Log log = LogFactory
+ .getLog(ArgeoSecurityManager.class);
+
+ /** TODO? use a bounded buffer */
+ private Map<String, String> userRolesCache = Collections
+ .synchronizedMap(new HashMap<String, String>());
/**
* Since this is called once when the session is created, we take the
Authentication authen;
Set<Authentication> authens = subject
.getPrincipals(Authentication.class);
- if (authens.size() == 0)
- throw new ArgeoException("No Spring authentication found in "
- + subject);
- else
+ String userId;
+ if (authens.size() == 0) {
+ // make sure that logged-in user has a Principal, useful for testing
+ // using an admin user
+ userId = super.getUserID(subject, workspaceName);
+ UserManager systemUm = getSystemUserManager(null);
+ if (systemUm.getAuthorizable(userId) == null)
+ systemUm.createUser(userId, "");
+ } else {// Spring Security
authen = authens.iterator().next();
- // sync Spring and Jackrabbit
- syncSpringAndJackrabbitSecurity(authen);
+ userId = authen.getName();
+ StringBuffer roles = new StringBuffer("");
+ GrantedAuthority[] authorities = authen.getAuthorities();
+ for (GrantedAuthority ga : authorities) {
+ roles.append(ga.toString());
+ }
+
+ // do not sync if not changed
+ if (userRolesCache.containsKey(userId)
+ && userRolesCache.get(userId).equals(roles.toString()))
+ return userId;
- return authen.getName();
+ // sync Spring and Jackrabbit
+ // workspace is irrelevant here
+ UserManager systemUm = getSystemUserManager(null);
+ syncSpringAndJackrabbitSecurity(systemUm, authen);
+ userRolesCache.put(userId, roles.toString());
+ }
+ return userId;
}
/**
* Make sure that the Jackrabbit security model contains this user and its
* granted authorities
*/
- protected void syncSpringAndJackrabbitSecurity(Authentication authen)
- throws RepositoryException {
+ static void syncSpringAndJackrabbitSecurity(UserManager systemUm,
+ Authentication authen) throws RepositoryException {
long begin = System.currentTimeMillis();
- // workspace is irrelevant here
- UserManager systemUm = getSystemUserManager(null);
-
String userId = authen.getName();
User user = (User) systemUm.getAuthorizable(userId);
if (user == null) {