import javax.security.auth.Subject;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
/** Provides base method for executing code with system authorization. */
public abstract class AbstractSystemExecution {
+ private final static Log log = LogFactory
+ .getLog(AbstractSystemExecution.class);
private AuthenticationManager authenticationManager;
private String systemAuthenticationKey;
+ /** Whether the current thread was authenticated by this component. */
+ private ThreadLocal<Boolean> authenticatedBySelf = new ThreadLocal<Boolean>() {
+ protected Boolean initialValue() {
+ return false;
+ }
+ };
+
/**
* Authenticate the calling thread to the underlying
* {@link AuthenticationManager}
*/
protected void authenticateAsSystem() {
+ if (authenticatedBySelf.get())
+ return;
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication currentAuth = securityContext.getAuthentication();
if (currentAuth != null)
Authentication auth = authenticationManager
.authenticate(new InternalAuthentication(key));
securityContext.setAuthentication(auth);
+ authenticatedBySelf.set(true);
+ if (log.isTraceEnabled())
+ log.trace("System authenticated");
}
/** Removes the authentication from the calling thread. */
protected void deauthenticateAsSystem() {
// remove the authentication
SecurityContext securityContext = SecurityContextHolder.getContext();
- securityContext.setAuthentication(null);
+ if (securityContext.getAuthentication() != null) {
+ securityContext.setAuthentication(null);
+ authenticatedBySelf.set(false);
+ if (log.isTraceEnabled())
+ log.trace("System deauthenticated");
+ }
}
public void setAuthenticationManager(
package org.argeo.security.core;
+import java.beans.PropertyDescriptor;
+
import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.PropertyValues;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
/**
- * Executes with a system authentication the initialization methods of the
- * application context where it has been defined.
+ * Executes with a system authentication the instantiation and initialization
+ * methods of the application context where it has been defined.
*/
-public class SystemExecutionBeanPostProcessor extends
- AbstractSystemExecution implements BeanPostProcessor {
+public class SystemExecutionBeanPostProcessor extends AbstractSystemExecution
+ implements InstantiationAwareBeanPostProcessor, ApplicationListener {
+
+ @SuppressWarnings("rawtypes")
+ public Object postProcessBeforeInstantiation(Class beanClass,
+ String beanName) throws BeansException {
+ authenticateAsSystem();
+ return null;
+ }
+
+ public boolean postProcessAfterInstantiation(Object bean, String beanName)
+ throws BeansException {
+ return true;
+ }
+
+ public PropertyValues postProcessPropertyValues(PropertyValues pvs,
+ PropertyDescriptor[] pds, Object bean, String beanName)
+ throws BeansException {
+ return pvs;
+ }
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (event instanceof ContextRefreshedEvent) {
+ // make sure that we have deauthenticated after the application
+ // context was initialized/refreshed
+ deauthenticateAsSystem();
+ }
+ }
+
}