org.springframework.security;specification-version="2.0.4.A",
org.springframework.security.adapters;specification-version="2.0.6.RELEASE",
org.springframework.security.providers;specification-version="2.0.6.RELEASE",
+ org.springframework.security.providers.anonymous;specification-version="2.0.6.RELEASE",
org.springframework.security.providers.encoding;specification-version="2.0.6.RELEASE",
org.springframework.security.providers.rememberme;specification-version="2.0.6.RELEASE"
Bundle-Name: Security Services
\r
<reference id="securityDao" interface="org.argeo.security.ArgeoSecurityDao" />\r
\r
- <reference id="authenticationProvider"\r
- interface="org.springframework.security.providers.AuthenticationProvider" />\r
+ <!-- <reference id="authenticationProvider" -->\r
+ <!-- interface="org.springframework.security.providers.AuthenticationProvider" \r
+ /> -->\r
+ <list id="authenticationProviders"\r
+ interface="org.springframework.security.providers.AuthenticationProvider"\r
+ cardinality="0..N">\r
+ <listener ref="authenticationManager" bind-method="register"\r
+ unbind-method="unregister" />\r
+ </list>\r
\r
<!-- SERVICES -->\r
<service ref="securityService" interface="org.argeo.security.ArgeoSecurityService" />\r
<property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
</bean>
- <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
+ <bean id="authenticationManager" class="org.argeo.security.core.ArgeoAuthenticationManager">
<property name="providers">
<list>
<bean class="org.springframework.security.adapters.AuthByAdapterProvider">
<property name="key" value="${argeo.security.systemKey}" />
</bean>
<bean
- class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
+ class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="${argeo.security.systemKey}" />
</bean>
- <ref bean="authenticationProvider" />
</list>
</property>
</bean>
+
+
+ <!-- <bean id="rememberMeAuthenticationProvider" -->
+ <!-- class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider"> -->
+ <!-- <property name="key" value="${argeo.security.systemKey}" /> -->
+ <!-- </bean> -->
+
</beans>
\ No newline at end of file
<artifactId>org.argeo.basic.nodeps</artifactId>
<version>0.2.3-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.argeo.commons.security</groupId>
+ <artifactId>org.argeo.security.core</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
+ </dependency>
<!-- Spring -->
<dependency>
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.login.LoginException;
+import org.argeo.security.SiteAuthenticationToken;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.context.SecurityContextHolder;
-import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.providers.jaas.SecurityContextLoginModule;
/** Login module which caches one subject per thread. */
NameCallback nameCallback = new NameCallback("User");
PasswordCallback passwordCallback = new PasswordCallback("Password",
false);
+ NameCallback urlCallback = new NameCallback("Site URL");
if (callbackHandler == null) {
throw new LoginException("No call back handler available");
}
try {
callbackHandler.handle(new Callback[] { label, nameCallback,
- passwordCallback });
+ passwordCallback, urlCallback });
} catch (Exception e) {
LoginException le = new LoginException("Callback handling failed");
le.initCause(e);
if (passwordCallback.getPassword() != null) {
password = String.valueOf(passwordCallback.getPassword());
}
- UsernamePasswordAuthenticationToken credentials = new UsernamePasswordAuthenticationToken(
- username, password);
+ String url = urlCallback.getName();
+ // TODO: set it via system properties
+ String workspace = null;
+
+ // UsernamePasswordAuthenticationToken credentials = new
+ // UsernamePasswordAuthenticationToken(
+ // username, password);
+ SiteAuthenticationToken credentials = new SiteAuthenticationToken(
+ username, password, url, workspace);
try {
Authentication authentication = authenticationManager
<plugins>
<plugin id="com.ibm.icu"/>
<plugin id="com.springsource.antlr"/>
+ <plugin id="com.springsource.com.sun.syndication"/>
<plugin id="com.springsource.edu.emory.mathcs.backport"/>
+ <plugin id="com.springsource.edu.oswego.cs.dl.util.concurrent"/>
+ <plugin id="com.springsource.javax.mail"/>
<plugin id="com.springsource.javax.servlet"/>
<plugin id="com.springsource.javax.xml.stream"/>
<plugin id="com.springsource.jdbm"/>
<plugin id="com.springsource.org.aopalliance"/>
<plugin id="com.springsource.org.apache.commons.codec"/>
<plugin id="com.springsource.org.apache.commons.collections"/>
+ <plugin id="com.springsource.org.apache.commons.compress"/>
+ <plugin id="com.springsource.org.apache.commons.dbcp"/>
+ <plugin id="com.springsource.org.apache.commons.fileupload"/>
+ <plugin id="com.springsource.org.apache.commons.httpclient"/>
<plugin id="com.springsource.org.apache.commons.io"/>
<plugin id="com.springsource.org.apache.commons.lang"/>
<plugin id="com.springsource.org.apache.commons.pool"/>
<plugin id="com.springsource.org.apache.directory.shared.asn1"/>
<plugin id="com.springsource.org.apache.directory.shared.ldap"/>
<plugin id="com.springsource.org.apache.log4j"/>
+ <plugin id="com.springsource.org.apache.lucene"/>
<plugin id="com.springsource.org.apache.mina"/>
<plugin id="com.springsource.org.apache.ws.commons.schema"/>
+ <plugin id="com.springsource.org.apache.xalan"/>
+ <plugin id="com.springsource.org.apache.xerces" fragment="true"/>
+ <plugin id="com.springsource.org.apache.xml.resolver"/>
+ <plugin id="com.springsource.org.apache.xml.serializer"/>
+ <plugin id="com.springsource.org.apache.xmlbeans"/>
+ <plugin id="com.springsource.org.apache.xmlcommons"/>
<plugin id="com.springsource.org.codehaus.jackson"/>
<plugin id="com.springsource.org.codehaus.jackson.mapper"/>
+ <plugin id="com.springsource.org.cyberneko.html"/>
+ <plugin id="com.springsource.org.dom4j"/>
+ <plugin id="com.springsource.org.h2"/>
+ <plugin id="com.springsource.org.jdom"/>
+ <plugin id="com.springsource.org.objectweb.asm"/>
+ <plugin id="com.springsource.org.postgresql.jdbc3"/>
<plugin id="com.springsource.slf4j.api"/>
<plugin id="com.springsource.slf4j.log4j" fragment="true"/>
<plugin id="com.springsource.slf4j.org.apache.commons.logging"/>
<plugin id="org.argeo.basic.nodeps"/>
+ <plugin id="org.argeo.dep.osgi.boilerpipe"/>
+ <plugin id="org.argeo.dep.osgi.bouncycastle.jdk15"/>
<plugin id="org.argeo.dep.osgi.directory.shared.asn.codec" fragment="true"/>
+ <plugin id="org.argeo.dep.osgi.drewnoakes.metadata_extractor"/>
+ <plugin id="org.argeo.dep.osgi.jackrabbit"/>
+ <plugin id="org.argeo.dep.osgi.jcr"/>
<plugin id="org.argeo.dep.osgi.mina.filter.ssl" fragment="true"/>
+ <plugin id="org.argeo.dep.osgi.netcdf"/>
+ <plugin id="org.argeo.dep.osgi.pdfbox"/>
+ <plugin id="org.argeo.dep.osgi.poi"/>
<plugin id="org.argeo.dep.osgi.springframework.ldap"/>
+ <plugin id="org.argeo.dep.osgi.tagsoup"/>
+ <plugin id="org.argeo.dep.osgi.tika"/>
<plugin id="org.argeo.eclipse.ui"/>
<plugin id="org.argeo.infra.core"/>
<plugin id="org.argeo.infra.security.services" fragment="true"/>
+ <plugin id="org.argeo.node.repo.jackrabbit"/>
<plugin id="org.argeo.security.core"/>
<plugin id="org.argeo.security.equinox"/>
+ <plugin id="org.argeo.security.jackrabbit" fragment="true"/>
<plugin id="org.argeo.security.ldap"/>
<plugin id="org.argeo.security.manager.ldap"/>
<plugin id="org.argeo.security.services"/>
<plugin id="org.argeo.server.ads"/>
<plugin id="org.argeo.server.ads.server"/>
<plugin id="org.argeo.server.core"/>
+ <plugin id="org.argeo.server.ext.jackrabbit" fragment="true"/>
+ <plugin id="org.argeo.server.jackrabbit"/>
+ <plugin id="org.argeo.server.jcr"/>
+ <plugin id="org.argeo.server.jcr.mvc"/>
<plugin id="org.argeo.server.json"/>
+ <plugin id="org.argeo.server.tika.jackrabbit" fragment="true"/>
+ <plugin id="org.argeo.slc.agent.ext.xalan" fragment="true"/>
<plugin id="org.argeo.slc.demo.log4j" fragment="true"/>
+ <plugin id="org.argeo.slc.gis.ext.dbcp" fragment="true"/>
<plugin id="org.eclipse.core.commands"/>
<plugin id="org.eclipse.core.contenttype"/>
<plugin id="org.eclipse.core.databinding"/>
<plugin id="org.springframework.osgi.extender"/>
<plugin id="org.springframework.osgi.io"/>
<plugin id="org.springframework.oxm"/>
+ <plugin id="org.springframework.security.acls" fragment="true"/>
<plugin id="org.springframework.security.core"/>
<plugin id="org.springframework.transaction"/>
+ <plugin id="org.springframework.web"/>
<plugin id="org.springframework.web.servlet"/>
<plugin id="org.springframework.xml"/>
</plugins>
<configurations>
+ <plugin id="org.argeo.node.repo.jackrabbit" autoStart="true" startLevel="0" />
<plugin id="org.argeo.security.manager.ldap" autoStart="true" startLevel="0" />
<plugin id="org.argeo.security.services" autoStart="true" startLevel="0" />
<plugin id="org.argeo.server.ads.server" autoStart="true" startLevel="0" />
import java.security.PrivilegedAction;
import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.dialogs.Error;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.ui.application.WorkbenchAdvisor;
/**
- * Common base class for authenticated access to the Eclipse UI framework (RAP and
- * RCP)
+ * Common base class for authenticated access to the Eclipse UI framework (RAP
+ * and RCP)
*/
public abstract class AbstractSecureApplication implements IApplication {
private static final Log log = LogFactory
Integer returnCode = null;
Display display = PlatformUI.createDisplay();
-
- // Force login
-
try {
- String username = null;
- Exception loginException = null;
Subject subject = null;
- try {
- SecureApplicationActivator.getLoginContext().login();
- subject = SecureApplicationActivator.getLoginContext()
- .getSubject();
-
- // username = CurrentUser.getUsername();
- } catch (Exception e) {
- loginException = e;
- e.printStackTrace();
+ Boolean retry = true;
+ while (retry) {
+ try {
+ SecureApplicationActivator.getLoginContext().login();
+ subject = SecureApplicationActivator.getLoginContext()
+ .getSubject();
+ retry = false;
+ } catch (LoginException e) {
+ Error.show("Cannot login", e);
+ retry = true;
+ } catch (Exception e) {
+ Error.show("Unexpected exception while trying to login", e);
+ retry = false;
+ }
}
+
if (subject == null) {
- IStatus status = new Status(IStatus.ERROR,
- "org.argeo.security.application", "Login is mandatory",
- loginException);
- ErrorDialog.openError(null, "Error", "Shutdown...", status);
- return status.getSeverity();
+ // IStatus status = new Status(IStatus.ERROR,
+ // "org.argeo.security.application", "Login is mandatory",
+ // loginException);
+ // ErrorDialog.openError(null, "Error", "Shutdown...", status);
+ // return status.getSeverity();
+
+ // TODO: log as anonymous
}
- returnCode = (Integer) Subject.doAs(subject, getRunAction(display));
- SecureApplicationActivator.getLoginContext().logout();
- return processReturnCode(returnCode);
+ if (subject != null) {
+ returnCode = (Integer) Subject.doAs(subject,
+ getRunAction(display));
+ SecureApplicationActivator.getLoginContext().logout();
+ return processReturnCode(returnCode);
+ } else {
+ return -1;
+ }
} catch (Exception e) {
// e.printStackTrace();
IStatus status = new Status(IStatus.ERROR,
}
protected Point getInitialSize() {
- return new Point(300, 250);
+ return new Point(300, 350);
}
protected Control createDialogArea(Composite parent) {
<artifactId>org.argeo.basic.nodeps</artifactId>
<version>0.2.3-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.argeo.commons.server</groupId>
+ <artifactId>org.argeo.server.jcr</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
+ </dependency>
<!-- Spring -->
<dependency>
--- /dev/null
+package org.argeo.security;
+
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+
+public class SiteAuthenticationToken extends
+ UsernamePasswordAuthenticationToken {
+ private static final long serialVersionUID = 1955222132884795213L;
+ private final String url;
+ private final String workspace;
+
+ public SiteAuthenticationToken(Object principal, Object credentials,
+ String url, String workspace) {
+ super(principal, credentials);
+ this.url = url;
+ this.workspace = workspace;
+ }
+
+ public SiteAuthenticationToken(Object principal, Object credentials,
+ GrantedAuthority[] authorities, String url, String workspace) {
+ super(principal, credentials, authorities);
+ this.url = url;
+ this.workspace = workspace;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String getWorkspace() {
+ return workspace;
+ }
+
+}
--- /dev/null
+package org.argeo.security.core;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.providers.AuthenticationProvider;
+import org.springframework.security.providers.ProviderManager;
+
+public class ArgeoAuthenticationManager extends ProviderManager {
+ private Log log = LogFactory.getLog(ArgeoAuthenticationManager.class);
+
+ @SuppressWarnings("unchecked")
+ public void register(AuthenticationProvider authenticationProvider,
+ Map<String, String> parameters) {
+ getProviders().add(authenticationProvider);
+ if (log.isDebugEnabled())
+ log.debug("Registered authentication provider " + parameters);
+ }
+
+ public void unregister(AuthenticationProvider authenticationProvider,
+ Map<String, String> parameters) {
+ getProviders().remove(authenticationProvider);
+ if (log.isDebugEnabled())
+ log.debug("Unregistered authentication provider " + parameters);
+ }
+
+}
--- /dev/null
+package org.argeo.security.jcr;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.security.SiteAuthenticationToken;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.security.providers.AuthenticationProvider;
+
+/** Connects to a JCR repository and delegate authentication to it. */
+public class JcrAuthenticationProvider implements AuthenticationProvider {
+ private List<RepositoryFactory> repositoryFactories = new ArrayList<RepositoryFactory>();
+ private final String defaultHome;
+ private final String userRole;
+
+ public JcrAuthenticationProvider() {
+ this("ROLE_USER", "home");
+ }
+
+ public JcrAuthenticationProvider(String userRole) {
+ this(userRole, "home");
+ }
+
+ public JcrAuthenticationProvider(String defaultHome, String userRole) {
+ super();
+ this.defaultHome = defaultHome;
+ this.userRole = userRole;
+ }
+
+ public Authentication authenticate(Authentication authentication)
+ throws AuthenticationException {
+ if (!(authentication instanceof SiteAuthenticationToken))
+ return null;
+ SiteAuthenticationToken siteAuth = (SiteAuthenticationToken) authentication;
+ String url = siteAuth.getUrl();
+ if (url == null)
+ return null;
+
+ try {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
+
+ Repository repository = null;
+ for (Iterator<RepositoryFactory> it = repositoryFactories
+ .iterator(); it.hasNext();) {
+ repository = it.next().getRepository(parameters);
+ }
+ if (repository == null)
+ return null;
+
+ SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
+ siteAuth.getCredentials().toString().toCharArray());
+ String workspace = siteAuth.getWorkspace();
+ Session session;
+ if (workspace == null || workspace.trim().equals(""))
+ session = repository.login(sp);
+ else
+ session = repository.login(sp, workspace);
+ Node userHome = getUserHome(session);
+ GrantedAuthority[] authorities = {};
+ return new JcrAuthenticationToken(siteAuth.getPrincipal(),
+ siteAuth.getCredentials(), authorities, url, userHome);
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected exception when authenticating to " + url, e);
+ }
+ }
+
+ protected GrantedAuthority[] getGrantedAuthorities(Session session) {
+ return new GrantedAuthority[] { new GrantedAuthorityImpl(userRole) };
+ }
+
+ @SuppressWarnings("rawtypes")
+ public boolean supports(Class authentication) {
+ return SiteAuthenticationToken.class.isAssignableFrom(authentication);
+ }
+
+ protected Node getUserHome(Session session) {
+ String userID = "<not yet logged in>";
+ try {
+ userID = session.getUserID();
+ Node rootNode = session.getRootNode();
+ Node homeNode;
+ if (!rootNode.hasNode(defaultHome)) {
+ homeNode = rootNode.addNode(defaultHome, ArgeoTypes.ARGEO_HOME);
+ } else {
+ homeNode = rootNode.getNode(defaultHome);
+ }
+
+ Node userHome;
+ if (!homeNode.hasNode(userID)) {
+ userHome = homeNode.addNode(userID);
+ userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
+ userHome.setProperty(ArgeoNames.ARGEO_USER_ID, userID);
+ } else {
+ userHome = homeNode.getNode(userID);
+ }
+ session.save();
+ return userHome;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot initialize home for user '"
+ + userID + "'", e);
+ }
+ }
+
+ public void setRepositoryFactories(
+ List<RepositoryFactory> repositoryFactories) {
+ this.repositoryFactories = repositoryFactories;
+ }
+
+ public String getDefaultHome() {
+ return defaultHome;
+ }
+
+ public String getUserRole() {
+ return userRole;
+ }
+
+}
--- /dev/null
+package org.argeo.security.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.SiteAuthenticationToken;
+import org.springframework.security.GrantedAuthority;
+
+public class JcrAuthenticationToken extends SiteAuthenticationToken {
+ private static final long serialVersionUID = -2736830165315486169L;
+ private final transient Node userHome;
+
+ public JcrAuthenticationToken(Object principal, Object credentials,
+ GrantedAuthority[] authorities, String url, Node userHome) {
+ super(principal, credentials, authorities, url,
+ extractWorkspace(userHome));
+ this.userHome = userHome;
+ }
+
+ private static String extractWorkspace(Node userHome) {
+ try {
+ return userHome.getSession().getWorkspace().getName();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot extract workspace of " + userHome,
+ e);
+ }
+ }
+
+ public Node getUserHome() {
+ return userHome;
+ }
+
+}
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import org.apache.jackrabbit.core.security.DefaultAccessManager;
+
+/** Intermediary class in order to have a consistent naming in config files. */
+public class ArgeoAccessManager extends DefaultAccessManager {
+
+}
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.core.security.AnonymousPrincipal;
+import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
+import org.apache.jackrabbit.core.security.authentication.Authentication;
+import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.argeo.security.SystemAuthentication;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
+
+public class ArgeoLoginModule extends AbstractLoginModule {
+ private String adminRole = "ROLE_ADMIN";
+
+ /**
+ * Returns the Spring {@link org.springframework.security.Authentication}
+ * (which can be null)
+ */
+ @Override
+ protected Principal getPrincipal(Credentials credentials) {
+ return SecurityContextHolder.getContext().getAuthentication();
+ }
+
+ protected Set<Principal> getPrincipals() {
+ // use linked HashSet instead of HashSet in order to maintain the order
+ // of principals (as in the Subject).
+ Set<Principal> principals = new LinkedHashSet<Principal>();
+ principals.add(principal);
+
+ org.springframework.security.Authentication authen = (org.springframework.security.Authentication) principal;
+
+ if (authen instanceof SystemAuthentication)
+ principals.add(new AdminPrincipal(authen.getName()));
+ else if (authen instanceof AnonymousAuthenticationToken)
+ principals.add(new AnonymousPrincipal());
+ else
+ for (GrantedAuthority ga : authen.getAuthorities()) {
+ if (adminRole.equals(ga.getAuthority()))
+ principals.add(new AdminPrincipal(authen.getName()));
+ }
+
+ // override credentials since we did not used the one passed to us
+ credentials = new SimpleCredentials(authen.getName(), authen
+ .getCredentials().toString().toCharArray());
+
+ return principals;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected void doInit(CallbackHandler callbackHandler, Session session,
+ Map options) throws LoginException {
+ }
+
+ @Override
+ protected boolean impersonate(Principal principal, Credentials credentials)
+ throws RepositoryException, LoginException {
+ throw new UnsupportedOperationException(
+ "Impersonation is not yet supported");
+ }
+
+ @Override
+ protected Authentication getAuthentication(final Principal principal,
+ Credentials creds) throws RepositoryException {
+ if (principal instanceof Group) {
+ return null;
+ }
+ return new Authentication() {
+ public boolean canHandle(Credentials credentials) {
+ return principal instanceof org.springframework.security.Authentication;
+ }
+
+ public boolean authenticate(Credentials credentials)
+ throws RepositoryException {
+ return ((org.springframework.security.Authentication) principal)
+ .isAuthenticated();
+ }
+ };
+ }
+
+}
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.security.auth.Subject;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+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.SystemPrincipal;
+import org.argeo.ArgeoException;
+import org.springframework.security.Authentication;
+import org.springframework.security.GrantedAuthority;
+
+/** Intermediary class in order to have a consistent naming in config files. */
+public class ArgeoSecurityManager extends DefaultSecurityManager {
+ private Log log = LogFactory.getLog(ArgeoSecurityManager.class);
+
+ @Override
+ /** Since this is called once when the session is created, we take the opportunity to synchronize Spring and Jackrabbit users and groups.*/
+ public String getUserID(Subject subject, String workspaceName)
+ throws RepositoryException {
+ long begin = System.currentTimeMillis();
+
+ if (!subject.getPrincipals(SystemPrincipal.class).isEmpty())
+ return super.getUserID(subject, workspaceName);
+
+ Authentication authen;
+ Set<Authentication> authens = subject
+ .getPrincipals(Authentication.class);
+ if (authens.size() == 0)
+ throw new ArgeoException("No Spring authentication found in "
+ + subject);
+ else
+ authen = authens.iterator().next();
+
+ UserManager systemUm = getSystemUserManager(workspaceName);
+
+ String userId = authen.getName();
+ User user = (User) systemUm.getAuthorizable(userId);
+ if (user == null) {
+ user = systemUm.createUser(userId, authen.getCredentials()
+ .toString(), authen, null);
+ log.info(userId + " added as " + user);
+ }
+
+ List<String> userGroupIds = new ArrayList<String>();
+ for (GrantedAuthority ga : authen.getAuthorities()) {
+ Group group = (Group) systemUm.getAuthorizable(ga.getAuthority());
+ if (group == null) {
+ group = systemUm.createGroup(ga.getAuthority(),
+ new GrantedAuthorityPrincipal(ga), null);
+ log.info(ga.getAuthority() + " added as " + group);
+ }
+ if (!group.isMember(user))
+ group.addMember(user);
+ userGroupIds.add(ga.getAuthority());
+ }
+
+ // check if user has not been removed from some groups
+ for (Iterator<Group> it = user.declaredMemberOf(); it.hasNext();) {
+ Group group = it.next();
+ if (!userGroupIds.contains(group.getID()))
+ group.removeMember(user);
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Spring and Jackrabbit Security synchronized for user "
+ + userId + " in " + (System.currentTimeMillis() - begin)
+ + " ms");
+ return userId;
+ }
+}
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import java.security.Principal;
+
+import org.springframework.security.GrantedAuthority;
+
+/** Wraps a {@link GrantedAuthority} as a prin,cipal. */
+class GrantedAuthorityPrincipal implements Principal {
+ private final GrantedAuthority grantedAuthority;
+
+ public GrantedAuthorityPrincipal(GrantedAuthority grantedAuthority) {
+ super();
+ this.grantedAuthority = grantedAuthority;
+ }
+
+ public String getName() {
+ return grantedAuthority.getAuthority();
+ }
+
+}
--- /dev/null
+package org.argeo.security.jackrabbit.providers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+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.argeo.ArgeoException;
+import org.argeo.security.jcr.JcrAuthenticationProvider;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+
+public class JackrabbitAuthenticationProvider extends JcrAuthenticationProvider {
+
+ @Override
+ protected GrantedAuthority[] getGrantedAuthorities(Session session) {
+ try {
+ JackrabbitSession jackrabbitSession = (JackrabbitSession) session;
+ UserManager userManager = jackrabbitSession.getUserManager();
+ User user = (User) userManager.getAuthorizable(session.getUserID());
+ List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+ for (Iterator<Group> it = user.memberOf(); it.hasNext();)
+ authorities.add(new GrantedAuthorityImpl(it.next().getID()));
+ return authorities
+ .toArray(new GrantedAuthority[authorities.size()]);
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot retrieve authorities for "
+ + session.getUserID(), e);
+ }
+ }
+
+}
+++ /dev/null
-package org.argeo.security.jackrabbit.spring;
-
-import java.security.Principal;
-
-import org.springframework.security.GrantedAuthority;
-
-/** Wraps a {@link GrantedAuthority} as a prin,cipal. */
-public class GrantedAuthorityPrincipal implements Principal {
- private final GrantedAuthority grantedAuthority;
-
- public GrantedAuthorityPrincipal(GrantedAuthority grantedAuthority) {
- super();
- this.grantedAuthority = grantedAuthority;
- }
-
- public String getName() {
- return grantedAuthority.getAuthority();
- }
-
-}
+++ /dev/null
-package org.argeo.security.jackrabbit.spring;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Credentials;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-
-import org.apache.jackrabbit.core.security.AnonymousPrincipal;
-import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
-import org.apache.jackrabbit.core.security.authentication.Authentication;
-import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
-import org.argeo.security.SystemAuthentication;
-import org.springframework.security.GrantedAuthority;
-import org.springframework.security.context.SecurityContextHolder;
-import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
-
-public class SpringLoginModule extends AbstractLoginModule {
-
- /**
- * Returns the Spring {@link org.springframework.security.Authentication}
- * (which can be null)
- */
- @Override
- protected Principal getPrincipal(Credentials credentials) {
- return SecurityContextHolder.getContext().getAuthentication();
- }
-
- protected Set<Principal> getPrincipals() {
- // use linked HashSet instead of HashSet in order to maintain the order
- // of principals (as in the Subject).
- Set<Principal> principals = new LinkedHashSet<Principal>();
- principals.add(principal);
-
- org.springframework.security.Authentication authen = (org.springframework.security.Authentication) principal;
-
- if (authen instanceof AnonymousAuthenticationToken)
- principals.add(new AnonymousPrincipal());
- if (authen instanceof SystemAuthentication)
- principals.add(new AdminPrincipal(authen.getName()));
-
- for (GrantedAuthority authority : authen.getAuthorities())
- principals.add(new GrantedAuthorityPrincipal(authority));
-
- return principals;
- }
-
- @SuppressWarnings("rawtypes")
- @Override
- protected void doInit(CallbackHandler callbackHandler, Session session,
- Map options) throws LoginException {
- }
-
- @Override
- protected boolean impersonate(Principal principal, Credentials credentials)
- throws RepositoryException, LoginException {
- throw new UnsupportedOperationException(
- "Impersonation is not yet supported");
- }
-
- @Override
- protected Authentication getAuthentication(Principal principal,
- Credentials creds) throws RepositoryException {
- if (principal instanceof Group) {
- return null;
- }
- return new Authentication() {
- public boolean canHandle(Credentials credentials) {
- return true;
- }
-
- public boolean authenticate(Credentials credentials)
- throws RepositoryException {
- return true;
- }
- };
- }
-
-}
org.springframework.aop.scope;version="2.5.6.SEC01",
org.springframework.osgi.web.context.support;version="1.2.1",
org.springframework.security;version="2.0.6.RELEASE",
+ org.springframework.security.providers.anonymous;version="2.0.6.RELEASE",
org.springframework.security.ui.webapp;version="2.0.6.RELEASE",
org.springframework.web.context;version="2.5.6.SEC01",
org.springframework.web.filter;version="2.5.6.SEC01",
<bean id="repositoryRegister" class="org.argeo.jcr.DefaultRepositoryRegister" />
- <bean id="sessionProvider" scope="session" destroy-method="dispose"
- class="org.argeo.jackrabbit.remote.SimpleSessionProvider">
+ <bean id="sessionProvider" scope="session" init-method="init"
+ destroy-method="dispose" class="org.argeo.jackrabbit.remote.SimpleSessionProvider">
<aop:scoped-proxy proxy-target-class="false" />
</bean>
unbind-method="unregister" />\r
</set>\r
\r
- <reference id="_authenticationManager"\r
- interface="org.springframework.security.AuthenticationManager" />\r
+<!-- <reference id="authenticationManager"-->\r
+<!-- interface="org.springframework.security.AuthenticationManager" />-->\r
</beans:beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
+
+
+ <!-- Filter chain -->
+ <alias name="filterChainProxy" alias="springSecurityFilterChain" />
+
+ <bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
+ <sec:filter-chain-map path-type="ant">
+ <sec:filter-chain pattern="/images/*" filters="none" />
+ <sec:filter-chain pattern="/**"
+ filters="securityContextFilter, logoutFilter, requestCacheFilter,
+ servletApiFilter, anonFilter, sessionMgmtFilter, exceptionTranslator, filterSecurityInterceptor" />
+ </sec:filter-chain-map>
+ </bean>
+
+ <!-- Filters -->
+ <bean id="securityContextFilter"
+ class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
+ <property name="securityContextRepository" ref="securityContextRepository" />
+ </bean>
+
+ <bean id="securityContextRepository"
+ class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
+
+ <bean id="logoutFilter"
+ class="org.springframework.security.web.authentication.logout.LogoutFilter">
+ <constructor-arg value="/logged_out.htm" />
+ <constructor-arg>
+ <list>
+ <bean
+ class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
+ </list>
+ </constructor-arg>
+ </bean>
+
+ <!-- <bean id="formLoginFilter" -->
+ <!-- class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> -->
+ <!-- <property name="authenticationManager" ref="authenticationManager"
+ /> -->
+ <!-- <property name="authenticationSuccessHandler"> -->
+ <!-- <bean -->
+ <!-- class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> -->
+ <!-- <property name="defaultTargetUrl" value="/index.jsp" /> -->
+ <!-- </bean> -->
+ <!-- </property> -->
+ <!-- <property name="sessionAuthenticationStrategy"> -->
+ <!-- <bean -->
+ <!-- class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"
+ /> -->
+ <!-- </property> -->
+ <!-- </bean> -->
+
+ <bean id="requestCacheFilter"
+ class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter" />
+
+ <bean id="servletApiFilter"
+ class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
+
+ <bean id="anonFilter"
+ class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
+ <property name="key" value="SomeUniqueKeyForThisApplication" />
+ <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
+ </bean>
+
+ <bean id="sessionMgmtFilter"
+ class="org.springframework.security.web.session.SessionManagementFilter">
+ <constructor-arg ref="securityContextRepository" />
+ </bean>
+
+ <bean id="exceptionTranslator"
+ class="org.springframework.security.web.access.ExceptionTranslationFilter">
+ <property name="authenticationEntryPoint">
+ <bean
+ class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
+ <property name="loginFormUrl" value="/login.htm" />
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="filterSecurityInterceptor"
+ class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
+ <!-- <property name="securityMetadataSource"> -->
+ <!-- <sec:filter-security-metadata-source> -->
+ <!-- <sec:intercept-url pattern="/secure/extreme/*" -->
+ <!-- access="ROLE_SUPERVISOR" /> -->
+ <!-- <sec:intercept-url pattern="/secure/**" -->
+ <!-- access="IS_AUTHENTICATED_FULLY" /> -->
+ <!-- <sec:intercept-url pattern="/login.htm" -->
+ <!-- access="IS_AUTHENTICATED_ANONYMOUSLY" /> -->
+ <!-- <sec:intercept-url pattern="/**" access="ROLE_USER" /> -->
+ <!-- </sec:filter-security-metadata-source> -->
+ <!-- </property> -->
+ <property name="authenticationManager" ref="authenticationManager" />
+ <property name="accessDecisionManager" ref="accessDecisionManager" />
+ </bean>
+
+ <!-- Access decision manager -->
+ <bean id="accessDecisionManager"
+ class="org.springframework.security.access.vote.AffirmativeBased">
+ <property name="decisionVoters">
+ <list>
+ <bean class="org.springframework.security.access.vote.RoleVoter" />
+ <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
+ </list>
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<security:http>
- <security:http-basic />
+ <security:intercept-url pattern="/remoting/*"
+ access="ROLE_USER,ROLE_ADMIN,ROLE_ANONYMOUS" />
+ <security:intercept-url pattern="/*/node/*/**"
+ access="ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN,ROLE_ANONYMOUS" />
+ <security:http-basic />
+ <security:anonymous />
</security:http>
+
+ <!-- LDAP -->
+ <security:ldap-authentication-provider
+ user-dn-pattern="uid={0},ou=People" group-search-base="ou=Roles"
+ group-search-filter="(member={0})" user-details-class="inetOrgPerson" />
+ <!-- <security:password-compare> -->
+ <!-- <security:password-encoder hash="{ssha}" > -->
+ <!-- <security:salt-source system-wide="test"/> -->
+ <!-- </security:password-encoder> -->
+ <!-- </security:password-compare> -->
+ <!-- </security:ldap-authentication-provider> -->
+ <security:ldap-server url="ldap://localhost:10389/dc=demo,dc=argeo,dc=org" />
+
</beans>
\ No newline at end of file
org.apache.xalan.processor,
org.argeo.jackrabbit,
org.argeo.jcr,
+ org.argeo.security.jackrabbit.providers,
+ org.argeo.security.jcr,
org.h2;version="[1.0.0,2.0.0)";resolution:=optional,
org.postgresql;version="[8.0.0,9.0.0)";resolution:=optional,
- org.springframework.beans.factory.config
+ org.springframework.beans.factory.config,
+ org.springframework.security.providers;version="2.0.6.RELEASE"
http://www.springframework.org/schema/util\r
http://www.springframework.org/schema/util/spring-util-2.5.xsd">\r
\r
+ <!-- REFERENCE -->\r
+ <list id="repositoryFactories" interface="javax.jcr.RepositoryFactory"\r
+ cardinality="0..N" />\r
+ <list id="repositories" interface="javax.jcr.Repository"\r
+ cardinality="0..N">\r
+ <listener ref="repositoryFactory" bind-method="register"\r
+ unbind-method="unregister" />\r
+ </list>\r
+\r
+ <!-- SERVICES -->\r
+ <service ref="repositoryFactory" interface="javax.jcr.RepositoryFactory" />\r
+\r
<service ref="nodeJcrRepository" interface="javax.jcr.Repository">\r
<service-properties>\r
<beans:entry value="node">\r
</service-properties>\r
</service>\r
\r
+ <service ref="jcrAuthenticationProvider"\r
+ interface="org.springframework.security.providers.AuthenticationProvider" />\r
\r
</beans:beans>
\ No newline at end of file
<property name="workspace" value="${argeo.node.repo.workspace}" />
</bean>
+ <bean id="jcrAuthenticationProvider" class="org.argeo.security.jackrabbit.providers.JackrabbitAuthenticationProvider">
+ <property name="repositoryFactories" ref="repositoryFactories" />
+ </bean>
+
+ <bean id="repositoryFactory" class="org.argeo.jackrabbit.JackrabbitRepositoryFactory">
+ </bean>
+
</beans>
\ No newline at end of file
<!-- Security -->
<Security appName="Jackrabbit">
- <SecurityManager
- class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager"
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
workspaceName="security">
</SecurityManager>
- <AccessManager
- class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
</AccessManager>
- <LoginModule
- class="org.springframework.security.providers.jaas.SecurityContextLoginModule">
+ <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
</LoginModule>
</Security>
</Repository>
\ No newline at end of file
<!-- Security -->
<Security appName="Jackrabbit">
- <SecurityManager
- class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager"
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
workspaceName="security">
</SecurityManager>
- <AccessManager
- class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
</AccessManager>
- <LoginModule
- class="org.springframework.security.providers.jaas.SecurityContextLoginModule">
+ <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
</LoginModule>
</Security>
</Repository>
\ No newline at end of file
-->
<property name="maxThreads" value="8" />
- <property name="allowAnonymousAccess" value="false" />
+ <property name="allowAnonymousAccess" value="true" />
<property name="accessControlEnabled" value="false" />
<property name="enableNtp" value="false" />
<property name="enableKerberos" value="false" />
<plugin id="org.argeo.eclipse.ui"/>
<plugin id="org.argeo.eclipse.ui.jcr"/>
<plugin id="org.argeo.eclipse.ui.rcp"/>
+ <plugin id="org.argeo.infra.core"/>
+ <plugin id="org.argeo.infra.security.services" fragment="true"/>
<plugin id="org.argeo.jackrabbit.webapp"/>
<plugin id="org.argeo.jcr.ui.explorer"/>
<plugin id="org.argeo.node.repo.jackrabbit"/>
<plugin id="org.argeo.security.core"/>
<plugin id="org.argeo.security.equinox"/>
+ <plugin id="org.argeo.security.jackrabbit" fragment="true"/>
<plugin id="org.argeo.security.ldap"/>
<plugin id="org.argeo.security.manager.ldap"/>
<plugin id="org.argeo.security.mvc"/>
<plugin id="org.argeo.server.ads.server"/>
<plugin id="org.argeo.server.catalina" fragment="true"/>
<plugin id="org.argeo.server.core"/>
+ <plugin id="org.argeo.server.ext.jackrabbit" fragment="true"/>
<plugin id="org.argeo.server.jackrabbit"/>
<plugin id="org.argeo.server.jcr"/>
<plugin id="org.argeo.server.jcr.mvc"/>
<plugin id="org.argeo.server.json"/>
<plugin id="org.argeo.server.tika.jackrabbit" fragment="true"/>
<plugin id="org.argeo.server.tomcat" fragment="true"/>
+ <plugin id="org.argeo.server.webextender" fragment="true"/>
+ <plugin id="org.argeo.slc.agent.ext.xalan" fragment="true"/>
+ <plugin id="org.argeo.slc.demo.log4j" fragment="true"/>
+ <plugin id="org.argeo.slc.gis.ext.dbcp" fragment="true"/>
<plugin id="org.eclipse.core.commands"/>
<plugin id="org.eclipse.core.contenttype"/>
<plugin id="org.eclipse.core.databinding"/>
<plugin id="org.springframework.osgi.web"/>
<plugin id="org.springframework.osgi.web.extender"/>
<plugin id="org.springframework.oxm"/>
+ <plugin id="org.springframework.security.acls" fragment="true"/>
<plugin id="org.springframework.security.core"/>
<plugin id="org.springframework.transaction"/>
<plugin id="org.springframework.web"/>
package org.argeo.jackrabbit;
+import java.util.HashMap;
import java.util.Map;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.RepositoryFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
+import org.argeo.ArgeoException;
import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.DefaultRepositoryRegister;
+import org.argeo.jcr.DefaultRepositoryFactory;
-public class JackrabbitRepositoryFactory extends DefaultRepositoryRegister
+public class JackrabbitRepositoryFactory extends DefaultRepositoryFactory
implements RepositoryFactory, ArgeoJcrConstants {
+ private final static Log log = LogFactory
+ .getLog(JackrabbitRepositoryFactory.class);
@SuppressWarnings("rawtypes")
public Repository getRepository(Map parameters) throws RepositoryException {
- String alias;
- if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) {
- alias = parameters.get(JCR_REPOSITORY_ALIAS).toString();
+ Repository repository = super.getRepository(parameters);
+ if (repository != null)
+ return repository;
+
+ if (parameters.containsKey(JCR_REPOSITORY_URI)) {
+ String uri = parameters.get(JCR_REPOSITORY_URI).toString();
+ Map<String, String> params = new HashMap<String, String>();
+
+ params.put(JcrUtils.REPOSITORY_URI, uri);
+ repository = new Jcr2davRepositoryFactory().getRepository(params);
+ if (repository == null)
+ throw new ArgeoException("Remote Davex repository " + uri
+ + " not found");
+ log.info("Initialized remote Jackrabbit repository " + repository
+ + " from uri " + uri);
+
}
- return null;
+
+ return repository;
}
}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.server.SessionProvider;
+import org.argeo.ArgeoException;
/** To be injected, typically of scope="session" */
public class SimpleSessionProvider implements SessionProvider, Serializable {
private final static Log log = LogFactory
.getLog(SimpleSessionProvider.class);
- private transient Map<String, Session> sessions = Collections
- .synchronizedMap(new HashMap<String, Session>());
+ private transient Map<String, Session> sessions;
private Credentials credentials = null;
String workspace) throws LoginException, ServletException,
RepositoryException {
+ // since sessions is transient it can be restored from the session
+ if (sessions == null)
+ sessions = Collections
+ .synchronizedMap(new HashMap<String, Session>());
+
if (!sessions.containsKey(workspace)) {
- Session session = rep.login(credentials, workspace);
- sessions.put(workspace, session);
- return session;
+ try {
+ Session session = rep.login(credentials, workspace);
+ if (log.isDebugEnabled())
+ log.debug("User " + session.getUserID() + " logged into "
+ + request.getServletPath());
+ sessions.put(workspace, session);
+ return session;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot open session", e);
+ }
} else {
Session session = sessions.get(workspace);
if (!session.isLive()) {
}
public void releaseSession(Session session) {
- if (log.isDebugEnabled())
- log.debug("Releasing JCR session " + session);
- // session.logout();
- // FIXME: find a way to log out when the HTTP session is expired
+ if (log.isTraceEnabled())
+ log.trace("Releasing JCR session " + session);
+ }
+
+ public void init() {
}
public void dispose() {
- for (String workspace : sessions.keySet()) {
- Session session = sessions.get(workspace);
- if (session.isLive())
- session.logout();
- }
+ if (sessions != null)
+ for (String workspace : sessions.keySet()) {
+ Session session = sessions.get(workspace);
+ if (session.isLive())
+ session.logout();
+ }
}
}
--- /dev/null
+package org.argeo.jcr;
+
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+
+public class DefaultRepositoryFactory extends DefaultRepositoryRegister
+ implements RepositoryFactory, ArgeoJcrConstants {
+// private final static Log log = LogFactory
+// .getLog(DefaultRepositoryFactory.class);
+
+ @SuppressWarnings("rawtypes")
+ public Repository getRepository(Map parameters) throws RepositoryException {
+ if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) {
+ String alias = parameters.get(JCR_REPOSITORY_ALIAS).toString();
+ if (getRepositories().containsKey(alias))
+ return getRepositories().get(alias);
+ }
+ return null;
+ }
+
+}