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">
- <bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
+ <bean id="filterChain.davex" parent="filterChain.template">
<sec:filter-chain-map path-type="ant">
- <sec:filter-chain pattern="/files/**"
- filters="session,x509,basic,exception,interceptor" />
- <sec:filter-chain pattern="/jcr/*/*/**"
- filters="session,x509,basic,exception,interceptor" />
+ <sec:filter-chain pattern="/*/*/*/**"
+ filters="session,x509,basic,exception" />
<!-- For some reason the first level listing workspaces must be public -->
- <sec:filter-chain pattern="/jcr/*/"
- filters="anonymous,exception,interceptorPublic" />
- <sec:filter-chain pattern="/public/**"
- filters="anonymous,exception,interceptorPublic" />
- <sec:filter-chain pattern="/pub/**"
- filters="anonymous,exception,interceptorPublic" />
- <sec:filter-chain pattern="/j_spring_security_logout"
- filters="logout,exception" />
+ <sec:filter-chain pattern="/*/*/"
+ filters="anonymous,exception" />
</sec:filter-chain-map>
+ </bean>
+
+ <bean id="filterChain.private" parent="filterChain.template">
+ <sec:filter-chain-map path-type="ant">
+ <sec:filter-chain pattern="/**"
+ filters="session,x509,basic,exception" />
+ </sec:filter-chain-map>
+ </bean>
+
+ <bean id="filterChain.public" parent="filterChain.template">
+ <sec:filter-chain-map path-type="ant">
+ <sec:filter-chain pattern="/**"
+ filters="anonymous,exception" />
+ </sec:filter-chain-map>
+ </bean>
+
+ <!-- <bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy"> -->
+ <!-- <sec:filter-chain-map path-type="ant"> -->
+ <!-- <sec:filter-chain pattern="/files/**" -->
+ <!-- filters="session,x509,basic,exception,interceptor" /> -->
+ <!-- <sec:filter-chain pattern="/jcr/*/*/**" -->
+ <!-- filters="session,x509,basic,exception,interceptor" /> -->
+ <!-- <sec:filter-chain pattern="/jcr/*/" -->
+ <!-- filters="anonymous,exception,interceptorPublic" /> -->
+ <!-- <sec:filter-chain pattern="/public/**" -->
+ <!-- filters="anonymous,exception,interceptorPublic" /> -->
+ <!-- <sec:filter-chain pattern="/pub/**" -->
+ <!-- filters="anonymous,exception,interceptorPublic" /> -->
+ <!-- <sec:filter-chain pattern="/j_spring_security_logout" -->
+ <!-- filters="logout,exception" /> -->
+ <!-- </sec:filter-chain-map> -->
+ <!-- <property name="matcher"> -->
+ <!-- <bean class="org.springframework.security.util.AntUrlPathMatcher"> -->
+ <!-- <constructor-arg value="false" /> -->
+ <!-- </bean> -->
+ <!-- </property> -->
+ <!-- </bean> -->
+
+ <bean id="filterChain.template" abstract="true"
+ class="org.springframework.security.util.FilterChainProxy">
<property name="matcher">
<bean class="org.springframework.security.util.AntUrlPathMatcher">
<!-- Do not convert to lower case -->
</bean>
</property>
</bean>
-
+
<!-- The actual authorization checks (called last, but first here for ease
of configuration) -->
- <bean id="interceptor" parent="filterInvocationInterceptorTemplate">
- <property name="objectDefinitionSource">
- <value>
- PATTERN_TYPE_APACHE_ANT
- /**=ROLE_USER,ROLE_ADMIN
- </value>
- </property>
- </bean>
- <bean id="interceptorPublic" parent="filterInvocationInterceptorTemplate">
- <property name="objectDefinitionSource">
- <value>
- PATTERN_TYPE_APACHE_ANT
- /**=IS_AUTHENTICATED_ANONYMOUSLY
- </value>
- </property>
- </bean>
+<!-- <bean id="interceptor" parent="filterInvocationInterceptorTemplate"> -->
+<!-- <property name="objectDefinitionSource"> -->
+<!-- <value> -->
+<!-- PATTERN_TYPE_APACHE_ANT -->
+<!-- /**=ROLE_USER,ROLE_ADMIN -->
+<!-- </value> -->
+<!-- </property> -->
+<!-- </bean> -->
+<!-- <bean id="interceptorPublic" parent="filterInvocationInterceptorTemplate"> -->
+<!-- <property name="objectDefinitionSource"> -->
+<!-- <value> -->
+<!-- PATTERN_TYPE_APACHE_ANT -->
+<!-- /**=IS_AUTHENTICATED_ANONYMOUSLY -->
+<!-- </value> -->
+<!-- </property> -->
+<!-- </bean> -->
<bean id="x509"
class="org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessingFilter">
<!-- Processes logouts, removing both session informations and the remember-me
cookie from the browser -->
- <bean id="logout" class="org.springframework.security.ui.logout.LogoutFilter">
- <constructor-arg value="/webdav/node/main" />
- <!-- URL redirected to after logout -->
- <constructor-arg>
- <list>
- <!-- <ref bean="rememberMeServices" /> -->
- <bean
- class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />
- </list>
- </constructor-arg>
- </bean>
-
- <!-- Use the remember me cookie to authenticate <bean id="rememberMe" class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
- <property name="authenticationManager" ref="authenticationManager" /> <property
- name="rememberMeServices" ref="rememberMeServices" /> </bean> <bean id="rememberMeServices"
- class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
- <property name="userDetailsService" ref="userDetailsService" /> <property
- name="key" value="${argeo.security.systemKey}" /> <property name="tokenValiditySeconds"
- value="${argeo.jcr.webapp.rememberMeValidity}" /> <property name="alwaysRemember"
- value="true" /> </bean> -->
+<!-- <bean id="logout" class="org.springframework.security.ui.logout.LogoutFilter"> -->
+<!-- <constructor-arg value="/webdav/node/main" /> -->
+<!-- <constructor-arg> -->
+<!-- <list> -->
+<!-- <bean -->
+<!-- class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" /> -->
+<!-- </list> -->
+<!-- </constructor-arg> -->
+<!-- </bean> -->
<!-- Basic authentication -->
<bean id="basic"
<property name="authenticationEntryPoint">
<ref local="basicProcessingFilterEntryPoint" />
</property>
- <!-- <property name="rememberMeServices" ref="rememberMeServices" /> -->
</bean>
<!-- Activate basic auth when needed -->
</property>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.ui.AccessDeniedHandlerImpl">
- <property name="errorPage" value="/accessDenied.jsp" />
+<!-- <property name="errorPage" value="/accessDenied.jsp" /> -->
</bean>
</property>
</bean>
<!-- Template for authorization checks -->
- <bean id="filterInvocationInterceptorTemplate" abstract="true"
- class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
- <property name="authenticationManager" ref="authenticationManager" />
- <property name="accessDecisionManager">
- <bean class="org.springframework.security.vote.AffirmativeBased">
- <property name="allowIfAllAbstainDecisions" value="false" />
- <property name="decisionVoters">
- <list>
- <bean class="org.springframework.security.vote.RoleVoter" />
- <bean class="org.springframework.security.vote.AuthenticatedVoter" />
- </list>
- </property>
- </bean>
- </property>
- </bean>
+<!-- <bean id="filterInvocationInterceptorTemplate" abstract="true" -->
+<!-- class="org.springframework.security.intercept.web.FilterSecurityInterceptor"> -->
+<!-- <property name="authenticationManager" ref="authenticationManager" /> -->
+<!-- <property name="accessDecisionManager"> -->
+<!-- <bean class="org.springframework.security.vote.AffirmativeBased"> -->
+<!-- <property name="allowIfAllAbstainDecisions" value="false" /> -->
+<!-- <property name="decisionVoters"> -->
+<!-- <list> -->
+<!-- <bean class="org.springframework.security.vote.RoleVoter" /> -->
+<!-- <bean class="org.springframework.security.vote.AuthenticatedVoter" /> -->
+<!-- </list> -->
+<!-- </property> -->
+<!-- </bean> -->
+<!-- </property> -->
+<!-- </bean> -->
</beans>
\ No newline at end of file
package org.argeo.jackrabbit.remote;
import java.io.Serializable;
-import java.util.List;
import javax.jcr.LoginException;
import javax.jcr.Repository;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.server.SessionProvider;
import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.JcrUtils;
+import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;
/**
private transient String currentWorkspaceName = null;
private transient String currentJcrUser = null;
+ // private transient String anonymousUserId = "anonymous";
+
public Session getSession(HttpServletRequest request, Repository rep,
String workspace) throws LoginException, ServletException,
RepositoryException {
- String springUser = SecurityContextHolder.getContext()
- .getAuthentication().getName();
+ Authentication authentication = SecurityContextHolder.getContext()
+ .getAuthentication();
+ if (authentication == null)
+ throw new ArgeoException(
+ "Request not authenticated by Spring Security");
+ String springUser = authentication.getName();
// HTTP
- String pathInfo = request.getPathInfo();
- List<String> tokens = JcrUtils.tokenize(pathInfo);
- String httpRepository = tokens.get(0);
+ String requestJcrRepository = (String) request
+ .getAttribute(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
// HTTP session
if (httpSession != null
if (httpSession == null)
httpSession = request.getSession();
+ // Initializes current values
if (currentRepositoryName == null)
- currentRepositoryName = httpRepository;
+ currentRepositoryName = requestJcrRepository;
if (currentWorkspaceName == null)
currentWorkspaceName = workspace;
if (currentJcrUser == null)
currentJcrUser = springUser;
+ // logout if there was a change in session coordinates
if (jcrSession != null)
- if (!currentRepositoryName.equals(httpRepository)) {
+ if (!currentRepositoryName.equals(requestJcrRepository)) {
if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from repository "
- + currentRepositoryName + " to " + httpRepository
- + ", logging out.");
+ log.debug(getHttpSessionId() + " Changed from repository '"
+ + currentRepositoryName + "' to '"
+ + requestJcrRepository
+ + "', logging out cached JCR session.");
logout();
} else if (!currentWorkspaceName.equals(workspace)) {
if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from workspace "
- + currentWorkspaceName + " to " + workspace
- + ", logging out.");
+ log.debug(getHttpSessionId() + " Changed from workspace '"
+ + currentWorkspaceName + "' to '" + workspace
+ + "', logging out cached JCR session.");
logout();
} else if (!currentJcrUser.equals(springUser)) {
if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from user "
- + currentJcrUser + " to " + springUser
- + ", logging out.");
+ log.debug(getHttpSessionId() + " Changed from user '"
+ + currentJcrUser + "' to '" + springUser
+ + "', logging out cached JCR session.");
logout();
}
- // JCR session
+ // login if needed
if (jcrSession == null)
try {
Session session = login(rep, workspace);
if (!session.getUserID().equals(springUser))
- throw new ArgeoException("HTTP user '" + springUser
- + "' not in line with JCR user '"
+ throw new ArgeoException("Spring Security user '"
+ + springUser + "' not in line with JCR user '"
+ session.getUserID() + "'");
- currentRepositoryName = httpRepository;
+ currentRepositoryName = requestJcrRepository;
// do not use workspace variable which may be null
currentWorkspaceName = session.getWorkspace().getName();
currentJcrUser = session.getUserID();
throw new ArgeoException("Cannot open session to workspace "
+ workspace, e);
}
- else
- return jcrSession;
+
+ // returns cached session
+ return jcrSession;
}
protected Session login(Repository repository, String workspace)
}
public void releaseSession(Session session) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Releasing JCR session " + session);
+ if (log.isTraceEnabled())
+ log.trace(getHttpSessionId() + " Releasing JCR session " + session);
}
protected void logout() {
public void destroy() {
logout();
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId()
- + " Cleaned up provider for web session ");
+ if (getHttpSessionId() != null)
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId()
+ + " Cleaned up provider for web session ");
httpSession = null;
}
-}
\ No newline at end of file
+
+}