X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=security%2Fruntime%2Forg.argeo.security.jackrabbit%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fjackrabbit%2FArgeoSecurityManager.java;h=3450c75d8dbd51f9e9418814a82023e8cdd4a205;hb=757231ada3408c39ef3d88527c61b1279ba462b8;hp=244207bc59dd6f80cb838296cb3eece79531abd7;hpb=7abea79fee4787580e26cfb1f01a845767cce504;p=lgpl%2Fargeo-commons.git diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java index 244207bc5..3450c75d8 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2012 Mathieu Baudier + * Copyright (C) 2007-2012 Argeo GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,22 +34,46 @@ import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.jackrabbit.core.DefaultSecurityManager; +import org.apache.jackrabbit.core.security.AMContext; +import org.apache.jackrabbit.core.security.AccessManager; 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; +import org.springframework.security.context.SecurityContextHolder; -/** Integrates Spring Security and Jackrabbit Security user and roles. */ +/** Integrates Spring Security and Jackrabbit Security users and roles. */ public class ArgeoSecurityManager extends DefaultSecurityManager { + /** Legacy security sync */ + final static String PROPERTY_JACKRABBIT_SECURITY_SYNC_1_1 = "argeo.jackarabbit.securitySync.1.1"; + private final static Log log = LogFactory .getLog(ArgeoSecurityManager.class); + private static Boolean synchronize = Boolean.parseBoolean(System + .getProperty(PROPERTY_JACKRABBIT_SECURITY_SYNC_1_1, "false")); + /** TODO? use a bounded buffer */ private Map userRolesCache = Collections .synchronizedMap(new HashMap()); + @Override + public AccessManager getAccessManager(Session session, AMContext amContext) + throws RepositoryException { + synchronized (getSystemSession()) { + return super.getAccessManager(session, amContext); + } + } + + @Override + public UserManager getUserManager(Session session) + throws RepositoryException { + synchronized (getSystemSession()) { + return super.getUserManager(session); + } + } + /** * Since this is called once when the session is created, we take the * opportunity to make sure that Jackrabbit users and groups reflect Spring @@ -58,6 +82,15 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { @Override public String getUserID(Subject subject, String workspaceName) throws RepositoryException { + if (!synchronize) { + Authentication authentication = SecurityContextHolder.getContext() + .getAuthentication(); + if (authentication != null) + return authentication.getName(); + else + return super.getUserID(subject, workspaceName); + } + if (log.isTraceEnabled()) log.trace(subject); // skip anonymous user (no rights) @@ -72,30 +105,36 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { Authentication authen; Set authens = subject .getPrincipals(Authentication.class); - if (authens.size() == 0) - throw new ArgeoException("No Spring authentication found in " - + subject); - else + String userId = super.getUserID(subject, workspaceName); + if (authens.size() == 0) { + // make sure that logged-in user has a Principal, useful for testing + // using an admin user + UserManager systemUm = getSystemUserManager(null); + if (systemUm.getAuthorizable(userId) == null) + systemUm.createUser(userId, ""); + } else {// Spring Security authen = authens.iterator().next(); - String 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; + if (!userId.equals(authen.getName())) + log.warn("User ID is '" + userId + "' but authen is " + + authen.getName()); + StringBuffer roles = new StringBuffer(""); + GrantedAuthority[] authorities = authen.getAuthorities(); + for (GrantedAuthority ga : authorities) { + roles.append(ga.toString()); + } - // sync Spring and Jackrabbit - // workspace is irrelevant here - UserManager systemUm = getSystemUserManager(null); - syncSpringAndJackrabbitSecurity(systemUm, authen); - userRolesCache.put(userId, roles.toString()); + // do not sync if not changed + if (userRolesCache.containsKey(userId) + && userRolesCache.get(userId).equals(roles.toString())) + return userId; + // sync Spring and Jackrabbit + // workspace is irrelevant here + UserManager systemUm = getSystemUserManager(null); + syncSpringAndJackrabbitSecurity(systemUm, authen); + userRolesCache.put(userId, roles.toString()); + } return userId; } @@ -103,7 +142,7 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { * Make sure that the Jackrabbit security model contains this user and its * granted authorities */ - static void syncSpringAndJackrabbitSecurity(UserManager systemUm, + static private void syncSpringAndJackrabbitSecurity(UserManager systemUm, Authentication authen) throws RepositoryException { long begin = System.currentTimeMillis(); @@ -112,10 +151,6 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { if (user == null) { user = systemUm.createUser(userId, authen.getCredentials() .toString(), authen, null); - // SecurityJcrUtils.createUserHomeIfNeeded(getSystemSession(), - // userId); - // getSystemSession().save(); - // setSecurityHomeAuthorizations(user); log.info(userId + " added as " + user); } @@ -145,50 +180,6 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { + " ms"); } - // protected synchronized void setSecurityHomeAuthorizations(User user) { - // // give read privileges on user security home - // String userId = ""; - // try { - // userId = user.getID(); - // Node userHome = SecurityJcrUtils.getUserHome(getSystemSession(), userId); - // if (userHome == null) - // throw new ArgeoException("No security home available for user " - // + userId); - // - // String path = userHome.getPath(); - // Principal principal = user.getPrincipal(); - // - // JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) - // getSystemSession() - // .getAccessControlManager(); - // JackrabbitAccessControlPolicy[] ps = acm - // .getApplicablePolicies(principal); - // if (ps.length == 0) { - // // log.warn("No ACL found for " + user); - // return; - // } - // - // JackrabbitAccessControlList list = (JackrabbitAccessControlList) ps[0]; - // - // // add entry - // Privilege[] privileges = new Privilege[] { acm - // .privilegeFromName(Privilege.JCR_READ) }; - // Map restrictions = new HashMap(); - // ValueFactory vf = getSystemSession().getValueFactory(); - // restrictions.put("rep:nodePath", - // vf.createValue(path, PropertyType.PATH)); - // restrictions.put("rep:glob", vf.createValue("*")); - // list.addEntry(principal, privileges, true /* allow or deny */, - // restrictions); - // } catch (Exception e) { - // e.printStackTrace(); - // throw new ArgeoException( - // "Cannot set authorization on security home for " + userId - // + ": " + e.getMessage()); - // } - // - // } - @Override protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() { WorkspaceAccessManager wam = super @@ -200,8 +191,6 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { WorkspaceAccessManager { private final WorkspaceAccessManager wam; - // private String defaultWorkspace; - public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) { super(); this.wam = wam; @@ -209,8 +198,6 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { public void init(Session systemSession) throws RepositoryException { wam.init(systemSession); - // defaultWorkspace = ((RepositoryImpl) getRepository()).getConfig() - // .getDefaultWorkspaceName(); } public void close() throws RepositoryException { @@ -218,22 +205,8 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { public boolean grants(Set principals, String workspaceName) throws RepositoryException { - // everybody has access to all workspaces // TODO: implements finer access to workspaces return true; - - // anonymous has access to the default workspace (required for - // remoting which does a default login when initializing the - // repository) - // Boolean anonymous = false; - // for (Principal principal : principals) - // if (principal instanceof AnonymousPrincipal) - // anonymous = true; - // - // if (anonymous && workspaceName.equals(defaultWorkspace)) - // return true; - // else - // return wam.grants(principals, workspaceName); } }