]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java
Improve and simplify OSGi Boot
[lgpl/argeo-commons.git] / org.argeo.security.ui.rap / src / org / argeo / security / ui / rap / SecureEntryPoint.java
index 48d33d2d4b68bb30efc663410b72e100e5b716d3..a681527f773e67663c0150576d67324a267a6c09 100644 (file)
  */
 package org.argeo.security.ui.rap;
 
-import static org.argeo.cms.KernelHeader.ACCESS_CONTROL_CONTEXT;
-
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
 import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.login.CredentialNotFoundException;
+import javax.security.auth.login.FailedLoginException;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.x500.X500Principal;
@@ -32,25 +30,25 @@ 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.KernelHeader;
-import org.argeo.cms.auth.ArgeoLoginContext;
+import org.argeo.cms.CmsException;
+import org.argeo.cms.auth.AuthConstants;
+import org.argeo.cms.auth.ThreadDeathLoginException;
 import org.argeo.cms.widgets.auth.DefaultLoginDialog;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
-import org.argeo.util.LocaleUtils;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.rap.rwt.application.EntryPoint;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.PlatformUI;
-import org.springframework.security.authentication.BadCredentialsException;
 
 /**
  * RAP entry point with login capabilities. Once the user has been
  * authenticated, the workbench is run as a privileged action by the related
  * subject.
  */
+@Deprecated
 public class SecureEntryPoint implements EntryPoint {
+       final static String ACCESS_CONTROL_CONTEXT = "org.argeo.node.accessControlContext";
        private final static Log log = LogFactory.getLog(SecureEntryPoint.class);
 
        /**
@@ -79,35 +77,38 @@ public class SecureEntryPoint implements EntryPoint {
                HttpServletRequest httpRequest = RWT.getRequest();
                final HttpSession httpSession = httpRequest.getSession();
                AccessControlContext acc = (AccessControlContext) httpSession
-                               .getAttribute(KernelHeader.ACCESS_CONTROL_CONTEXT);
+                               .getAttribute(ACCESS_CONTROL_CONTEXT);
 
                final Subject subject;
-               if (acc != null) {
+               if (acc != null
+                               && Subject.getSubject(acc).getPrincipals(X500Principal.class)
+                                               .size() == 1) {
                        subject = Subject.getSubject(acc);
                } else {
                        subject = new Subject();
 
                        final LoginContext loginContext;
+                       DefaultLoginDialog callbackHandler;
                        try {
-                               CallbackHandler callbackHandler = new DefaultLoginDialog(
+                               callbackHandler = new DefaultLoginDialog(
                                                display.getActiveShell());
-                               loginContext = new ArgeoLoginContext(
-                                               KernelHeader.LOGIN_CONTEXT_USER, subject,
+                               loginContext = new LoginContext(
+                                               AuthConstants.LOGIN_CONTEXT_USER, subject,
                                                callbackHandler);
                        } catch (LoginException e1) {
-                               throw new ArgeoException("Cannot initialize login context", e1);
+                               throw new CmsException("Cannot initialize login context", e1);
                        }
 
                        tryLogin: while (subject.getPrincipals(X500Principal.class).size() == 0) {
                                try {
                                        loginContext.login();
                                        if (subject.getPrincipals(X500Principal.class).size() == 0)
-                                               throw new ArgeoException("Login succeeded but no auth");// fatal
+                                               throw new CmsException("Login succeeded but no auth");// fatal
 
                                        // add thread locale to RWT session
-                                       if (log.isTraceEnabled())
-                                               log.trace("Locale " + LocaleUtils.threadLocale.get());
-                                       RWT.setLocale(LocaleUtils.threadLocale.get());
+                                       // if (log.isTraceEnabled())
+                                       // log.trace("Locale " + LocaleUtils.threadLocale.get());
+                                       // RWT.setLocale(LocaleUtils.threadLocale.get());
 
                                        // once the user is logged in, longer session timeout
                                        RWT.getRequest().getSession()
@@ -115,14 +116,18 @@ public class SecureEntryPoint implements EntryPoint {
 
                                        if (log.isDebugEnabled())
                                                log.debug("Authenticated " + subject);
+                               } catch (FailedLoginException e) {
+                                       MessageDialog.openInformation(display.getActiveShell(),
+                                                       "Bad Credentials", e.getMessage());
+                                       // retry login
+                                       continue tryLogin;
+                               } catch (CredentialNotFoundException e) {
+                                       MessageDialog.openInformation(display.getActiveShell(),
+                                                       "No Credentials", e.getMessage());
+                                       // retry login
+                                       continue tryLogin;
                                } catch (LoginException e) {
-                                       BadCredentialsException bce = wasCausedByBadCredentials(e);
-                                       if (bce != null) {
-                                               MessageDialog.openInformation(display.getActiveShell(),
-                                                               "Bad Credentials", bce.getMessage());
-                                               // retry login
-                                               continue tryLogin;
-                                       }
+                                       callbackHandler.getShell().dispose();
                                        return processLoginDeath(display, e);
                                }
                        }
@@ -135,8 +140,8 @@ public class SecureEntryPoint implements EntryPoint {
                                if (log.isTraceEnabled())
                                        log.trace("Display disposed");
                                try {
-                                       LoginContext loginContext = new ArgeoLoginContext(
-                                                       KernelHeader.LOGIN_CONTEXT_USER, subject);
+                                       LoginContext loginContext = new LoginContext(
+                                                       AuthConstants.LOGIN_CONTEXT_USER, subject);
                                        loginContext.logout();
                                } catch (LoginException e) {
                                        log.error("Error when logging out", e);
@@ -170,7 +175,7 @@ public class SecureEntryPoint implements EntryPoint {
                return returnCode;
        }
 
-       private Integer processLoginDeath(Display display, LoginException e) {
+       private Integer processLoginDeath(Display display, Throwable e) {
                // check thread death
                ThreadDeath td = wasCausedByThreadDeath(e);
                if (td != null) {
@@ -184,26 +189,12 @@ public class SecureEntryPoint implements EntryPoint {
                        display.dispose();
                        return -1;
                } else {
-                       throw new ArgeoException(
+                       throw new CmsException(
                                        "Unexpected exception during authentication", e);
                }
 
        }
 
-       /** Recursively look for {@link BadCredentialsException} in the root causes. */
-       private BadCredentialsException wasCausedByBadCredentials(Throwable t) {
-               if (t instanceof BadCredentialsException)
-                       return (BadCredentialsException) t;
-
-               if (t instanceof CredentialNotFoundException)
-                       return new BadCredentialsException("Login canceled");
-
-               if (t.getCause() != null)
-                       return wasCausedByBadCredentials(t.getCause());
-               else
-                       return null;
-       }
-
        /**
         * If there is a {@link ThreadDeath} in the root causes, rethrow it
         * (important for RAP cleaning mechanism)
@@ -211,7 +202,8 @@ public class SecureEntryPoint implements EntryPoint {
        protected ThreadDeath wasCausedByThreadDeath(Throwable t) {
                if (t instanceof ThreadDeath)
                        return (ThreadDeath) t;
-
+               if (t instanceof ThreadDeathLoginException)
+                       return ((ThreadDeathLoginException) t).getThreadDeath();
                if (t.getCause() != null)
                        return wasCausedByThreadDeath(t.getCause());
                else
@@ -220,8 +212,8 @@ public class SecureEntryPoint implements EntryPoint {
 
        private void fullLogout(Subject subject, String username) {
                try {
-                       LoginContext loginContext = new ArgeoLoginContext(
-                                       KernelHeader.LOGIN_CONTEXT_USER, subject);
+                       LoginContext loginContext = new LoginContext(
+                                       AuthConstants.LOGIN_CONTEXT_USER, subject);
                        loginContext.logout();
                        HttpServletRequest httpRequest = RWT.getRequest();
                        HttpSession httpSession = httpRequest.getSession();