Improve system authenticated bean post-processing
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.core / src / main / java / org / argeo / security / core / AbstractSystemExecution.java
index 55f0fefcc156c9bd37d3c5c186f0657f3ce1cc8d..23a111b9430e51e50c5c5b507a560c7514ed2bde 100644 (file)
@@ -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<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)
@@ -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(