]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java
Introduce Single User login
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / auth / AbstractLoginModule.java
index 427ec83188f2db7d70b17620dbe109513065a114..89312a3dca2d1c7c95ee0df20875c6cd42e39a0b 100644 (file)
@@ -23,19 +23,31 @@ import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 import org.argeo.cms.internal.kernel.Activator;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.swt.widgets.Display;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 /** Login module which caches one subject per thread. */
 public abstract class AbstractLoginModule implements LoginModule {
-       // private final static Log log = LogFactory
-       // .getLog(AbstractSpringLoginModule.class);
+       /**
+        * From org.springframework.security.context.
+        * HttpSessionContextIntegrationFilter
+        */
+       private final static String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
+
+       private final static Log log = LogFactory.getLog(AbstractLoginModule.class);
        private CallbackHandler callbackHandler;
        private Subject subject;
 
@@ -62,9 +74,32 @@ public abstract class AbstractLoginModule implements LoginModule {
        @Override
        public boolean login() throws LoginException {
                try {
-                       // thread already logged in
                        Authentication currentAuth = SecurityContextHolder.getContext()
                                        .getAuthentication();
+
+                       if (currentAuth == null) {
+                               // Pre-auth
+                               // TODO Do it at Spring Security level?
+                               try {
+                                       // try to load authentication from session
+                                       HttpServletRequest httpRequest = RWT.getRequest();
+                                       HttpSession httpSession = httpRequest.getSession();
+                                       // log.debug(httpSession.getId());
+                                       Object contextFromSessionObject = httpSession
+                                                       .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
+                                       if (contextFromSessionObject != null) {
+                                               currentAuth = (Authentication) contextFromSessionObject;
+                                               SecurityContextHolder.getContext().setAuthentication(
+                                                               currentAuth);
+                                       }
+                               } catch (Exception e) {
+                                       if (log.isTraceEnabled())
+                                               log.trace("Could not get session", e);
+                                       // silent
+                               }
+                       }
+
+                       // thread already logged in
                        if (currentAuth != null) {
                                if (subject.getPrincipals(Authentication.class).size() == 0) {
                                        // throw new LoginException(
@@ -85,8 +120,23 @@ public abstract class AbstractLoginModule implements LoginModule {
 
                        authentication = processLogin(callbackHandler);
                        if (authentication != null) {
-                               SecurityContextHolder.getContext().setAuthentication(
-                                               authentication);
+                               //
+                               // SET THE AUTHENTICATION
+                               //
+                               SecurityContext securityContext = SecurityContextHolder
+                                               .getContext();
+                               securityContext.setAuthentication(authentication);
+                               try {
+                                       HttpServletRequest httpRequest = RWT.getRequest();
+                                       HttpSession httpSession = httpRequest.getSession();
+                                       if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)
+                                               httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
+                                                               authentication);
+                               } catch (Exception e) {
+                                       if (log.isTraceEnabled())
+                                               log.trace("Could not add security context to session",
+                                                               e);
+                               }
                                return true;
                        } else {
                                throw new LoginException("No authentication returned");
@@ -109,6 +159,16 @@ public abstract class AbstractLoginModule implements LoginModule {
        @Override
        public boolean logout() throws LoginException {
                SecurityContextHolder.getContext().setAuthentication(null);
+               if (Display.getCurrent() != null) {
+                       HttpServletRequest httpRequest = RWT.getRequest();
+                       if (httpRequest != null) {
+                               HttpSession httpSession = httpRequest.getSession();
+                               if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) != null)
+                                       httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null);
+                               // expire session
+                               httpSession.setMaxInactiveInterval(0);
+                       }
+               }
                return true;
        }
 
@@ -139,12 +199,6 @@ public abstract class AbstractLoginModule implements LoginModule {
                return bc.getService(authenticationManager);
        }
 
-       // protected UserAdmin getUserAdmin(BundleContextCallback
-       // bundleContextCallback) {
-       // BundleContext bc = bundleContextCallback.getBundleContext();
-       // return bc.getService(bc.getServiceReference(UserAdmin.class));
-       // }
-
        protected Subject getSubject() {
                return subject;
        }