System authentication
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / security / core / AuthenticatedApplicationContextInitialization.java
index 5faa2a75110f265621290e7a04cb84294c0ffbde..6c477ee9f97161426216cc9da4d4dcceefd46e79 100644 (file)
 package org.argeo.security.core;
 
 import java.beans.PropertyDescriptor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.security.auth.Subject;
+
+import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.PropertyValues;
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
+import org.springframework.beans.factory.support.AbstractBeanFactory;
+import org.springframework.beans.factory.support.SecurityContextProvider;
+import org.springframework.beans.factory.support.SimpleSecurityContextProvider;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ApplicationEvent;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
@@ -31,41 +40,51 @@ import org.springframework.context.event.ContextRefreshedEvent;
  * methods of the application context where it has been defined.
  */
 public class AuthenticatedApplicationContextInitialization extends
-               AbstractSystemExecution implements InstantiationAwareBeanPostProcessor,
-               ApplicationListener<ApplicationEvent> {
+               AbstractSystemExecution implements DependencyInitializationAwareBeanPostProcessor,
+               ApplicationListener<ApplicationEvent>, ApplicationContextAware {
        // private Log log = LogFactory
        // .getLog(AuthenticatedApplicationContextInitialization.class);
        /** If non empty, restricts to these beans */
        private List<String> beanNames = new ArrayList<String>();
 
-       @SuppressWarnings("rawtypes")
-       public Object postProcessBeforeInstantiation(Class beanClass,
-                       String beanName) throws BeansException {
-               // we authenticate when any bean is instantiated
-               // we will deauthenticate only when the application context has been
-               // refreshed in order to be able to deal with factory beans has well
-               if (!isAuthenticatedBySelf()) {
-                       if (beanNames.size() == 0)
-                               authenticateAsSystem();
-                       else if (beanNames.contains(beanName))
-                               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;
-       }
+//     @SuppressWarnings("rawtypes")
+//     public Object postProcessBeforeInstantiation(Class beanClass,
+//                     String beanName) throws BeansException {
+//             // we authenticate when any bean is instantiated
+//             // we will deauthenticate only when the application context has been
+//             // refreshed in order to be able to deal with factory beans has well
+//             // if (!isAuthenticatedBySelf()) {
+//             // if (beanNames.size() == 0)
+//             // authenticateAsSystem();
+//             // else if (beanNames.contains(beanName))
+//             // 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 {
+               if (beanNames.size() == 0 || beanNames.contains(beanName))
+                       authenticateAsSystem();
+               // try {
+               // if (beanNames.size() == 0 || beanNames.contains(beanName)) {
+               // LoginContext lc = new LoginContext("INIT", subject);
+               // lc.login();
+               // }
+               // } catch (LoginException e) {
+               // throw new ArgeoException("Cannot login as initialization", e);
+               // }
                return bean;
        }
 
@@ -75,7 +94,17 @@ public class AuthenticatedApplicationContextInitialization extends
                // we expect the underlying thread to die and thus the system
                // authentication to be lost. We have currently no way to catch the
                // exception and perform the deauthentication by ourselves.
-               // deauthenticateAsSystem();
+               if (beanNames.size() == 0 || beanNames.contains(beanName))
+                       deauthenticateAsSystem();
+               // try {
+               // if (beanNames.size() == 0 || beanNames.contains(beanName)) {
+               // LoginContext lc = new LoginContext("INIT", subject);
+               // lc.logout();
+               // }
+               // } catch (LoginException e) {
+               // // TODO Auto-generated catch block
+               // e.printStackTrace();
+               // }
                return bean;
        }
 
@@ -91,4 +120,23 @@ public class AuthenticatedApplicationContextInitialization extends
                this.beanNames = beanNames;
        }
 
+       @Override
+       public void setApplicationContext(ApplicationContext applicationContext)
+                       throws BeansException {
+               if (applicationContext.getAutowireCapableBeanFactory() instanceof AbstractBeanFactory) {
+                       final AbstractBeanFactory beanFactory = ((AbstractBeanFactory) applicationContext
+                                       .getAutowireCapableBeanFactory());
+                       // retrieve subject's access control context
+                       // and set it as the bean factory security context
+                       Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
+                               @Override
+                               public Void run() {
+                                       SecurityContextProvider scp = new SimpleSecurityContextProvider(
+                                                       AccessController.getContext());
+                                       beanFactory.setSecurityContextProvider(scp);
+                                       return null;
+                               }
+                       });
+               }
+       }
 }