From: Mathieu Baudier Date: Wed, 20 Apr 2011 11:47:12 +0000 (+0000) Subject: Improve system authenticated bean post-processing X-Git-Tag: argeo-commons-2.1.30~1274 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=3e638706693d06f4b5a16c8fe0197b8c7e7794b3;p=lgpl%2Fargeo-commons.git Improve system authenticated bean post-processing ASSIGNED - bug 17: Generalize agent management and registration beyond JMS https://bugzilla.argeo.org/show_bug.cgi?id=17 git-svn-id: https://svn.argeo.org/commons/trunk@4464 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/AbstractSystemExecution.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/AbstractSystemExecution.java index 55f0fefcc..23a111b94 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/AbstractSystemExecution.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/AbstractSystemExecution.java @@ -4,6 +4,8 @@ import java.security.AccessController; 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; @@ -12,14 +14,25 @@ import org.springframework.security.context.SecurityContextHolder; /** 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 authenticatedBySelf = new ThreadLocal() { + 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) @@ -43,13 +56,21 @@ public abstract class AbstractSystemExecution { 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( diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemExecutionBeanPostProcessor.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemExecutionBeanPostProcessor.java index 017317361..a2086bb9c 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemExecutionBeanPostProcessor.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/SystemExecutionBeanPostProcessor.java @@ -1,14 +1,38 @@ 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 { @@ -26,4 +50,12 @@ public class SystemExecutionBeanPostProcessor extends 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(); + } + } + }