From: Mathieu Baudier Date: Thu, 24 Mar 2011 16:38:56 +0000 (+0000) Subject: Fix issues with multi session X-Git-Tag: argeo-commons-2.1.30~1313 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=2f1c0a952d1bbaafc243da2d5d4caa235f628777;p=lgpl%2Fargeo-commons.git Fix issues with multi session git-svn-id: https://svn.argeo.org/commons/trunk@4366 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java b/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java index 298323b3d..0e5984532 100644 --- a/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java +++ b/security/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java @@ -1,7 +1,6 @@ package org.argeo.security.equinox; import java.util.Map; -import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; @@ -44,10 +43,11 @@ public class SpringLoginModule extends SecurityContextLoginModule { public boolean login() throws LoginException { // try to retrieve Authentication from Subject - Set auths = subject.getPrincipals(Authentication.class); - if (auths.size() > 0) - SecurityContextHolder.getContext().setAuthentication( - auths.iterator().next()); + // Set auths = + // subject.getPrincipals(Authentication.class); + // if (auths.size() > 0) + // SecurityContextHolder.getContext().setAuthentication( + // auths.iterator().next()); // thread already logged in if (SecurityContextHolder.getContext().getAuthentication() != null) @@ -80,9 +80,7 @@ public class SpringLoginModule extends SecurityContextLoginModule { callbackHandler.handle(new Callback[] { label, nameCallback, passwordCallback }); } catch (Exception e) { - LoginException le = new LoginException("Callback handling failed"); - le.initCause(e); - throw le; + throw new RuntimeException("Unexpected exception when handling", e); } // Set user name and password diff --git a/security/plugins/org.argeo.security.ui.rap/plugin.xml b/security/plugins/org.argeo.security.ui.rap/plugin.xml index 844dc2621..9d6135fea 100644 --- a/security/plugins/org.argeo.security.ui.rap/plugin.xml +++ b/security/plugins/org.argeo.security.ui.rap/plugin.xml @@ -9,5 +9,17 @@ parameter="secureWebUi"> + + + + + + diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java index 569412bd6..f47eb82d4 100644 --- a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java +++ b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureActionBarAdvisor.java @@ -1,13 +1,9 @@ package org.argeo.security.ui.rap; -import java.security.Principal; +import java.security.AccessController; import javax.security.auth.Subject; -import javax.security.auth.login.LoginException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.ArgeoException; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IAction; @@ -17,19 +13,17 @@ import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; public class SecureActionBarAdvisor extends ActionBarAdvisor { - private final static Log log = LogFactory - .getLog(SecureActionBarAdvisor.class); +// private final static Log log = LogFactory +// .getLog(SecureActionBarAdvisor.class); private IAction logoutAction; private IWorkbenchAction openPerspectiveDialogAction; @@ -53,7 +47,8 @@ public class SecureActionBarAdvisor extends ActionBarAdvisor { register(showViewMenuAction); // logout - logoutAction = createLogoutAction(); + logoutAction = ActionFactory.QUIT.create(window); + //logoutAction = createLogoutAction(); register(logoutAction); // Save semantics @@ -67,13 +62,9 @@ public class SecureActionBarAdvisor extends ActionBarAdvisor { } protected IAction createLogoutAction() { - Subject subject = null; - try { - subject = SecureRapActivator.getLoginContext().getSubject(); - } catch (LoginException e1) { - throw new ArgeoException("Cannot retrieve subject", e1); - } - final Principal principal = subject.getPrincipals().iterator().next(); + Subject subject = Subject.getSubject(AccessController.getContext()); + final String username = subject.getPrincipals().iterator().next() + .getName(); IAction logoutAction = new Action() { public String getId() { @@ -81,27 +72,28 @@ public class SecureActionBarAdvisor extends ActionBarAdvisor { } public String getText() { - return "Logout " + principal.getName(); + return "Logout " + username; } public void run() { - try { - Subject subject = SecureRapActivator.getLoginContext() - .getSubject(); - String subjectStr = subject.toString(); - subject.getPrincipals().clear(); - SecureRapActivator.getLoginContext().logout(); - log.info(subjectStr + " logged out"); - } catch (LoginException e) { - log.error("Error when logging out", e); - } - try { - RWT.getRequest().getSession().setMaxInactiveInterval(1); - PlatformUI.getWorkbench().close(); - } catch (Exception e) { - if (log.isTraceEnabled()) - log.trace("Error when invalidating session", e); - } + // try { + // Subject subject = SecureRapActivator.getLoginContext() + // .getSubject(); + // String subjectStr = subject.toString(); + // subject.getPrincipals().clear(); + // SecureRapActivator.getLoginContext().logout(); + // log.info(subjectStr + " logged out"); + // } catch (LoginException e) { + // log.error("Error when logging out", e); + // } +// SecureEntryPoint.logout(username); +// PlatformUI.getWorkbench().close(); + // try { + // RWT.getRequest().getSession().setMaxInactiveInterval(1); + // } catch (Exception e) { + // if (log.isTraceEnabled()) + // log.trace("Error when invalidating session", e); + // } } }; diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureEntryPoint.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureEntryPoint.java index f30f0059b..638b33a12 100644 --- a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureEntryPoint.java +++ b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureEntryPoint.java @@ -7,7 +7,8 @@ import javax.security.auth.login.LoginException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.argeo.eclipse.ui.dialogs.Error; +import org.eclipse.equinox.security.auth.ILoginContext; +import org.eclipse.rwt.RWT; import org.eclipse.rwt.lifecycle.IEntryPoint; import org.eclipse.rwt.service.SessionStoreEvent; import org.eclipse.rwt.service.SessionStoreListener; @@ -18,52 +19,108 @@ import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.application.WorkbenchWindowAdvisor; public class SecureEntryPoint implements IEntryPoint, SessionStoreListener { - private Log log = LogFactory.getLog(SecureEntryPoint.class); + private final static Log log = LogFactory.getLog(SecureEntryPoint.class); @Override public int createUI() { - // log.debug("THREAD=" + Thread.currentThread().getId() - // + ", RWT.getSessionStore().getId()=" - // + RWT.getSessionStore().getId()); + // 15 mins session timeout + RWT.getRequest().getSession().setMaxInactiveInterval(15 * 60); + if (log.isDebugEnabled()) + log.debug("THREAD=" + Thread.currentThread().getId() + + ", sessionStore=" + RWT.getSessionStore().getId()); + + final ILoginContext loginContext = SecureRapActivator + .createLoginContext(); Integer returnCode = null; Display display = PlatformUI.createDisplay(); + + Subject subject = null; try { - Subject subject = null; - Boolean retry = true; - while (retry) { + loginContext.login(); + subject = loginContext.getSubject(); + } catch (LoginException e) { + log.error("Error when logging in.", e); + display.dispose(); + RWT.getRequest().getSession().setMaxInactiveInterval(1); + try { + Thread.sleep(2000); + } catch (InterruptedException e1) { + // silent + } + return -1; + } + + // identify after successful login + if (log.isDebugEnabled()) + log.debug("subject=" + subject); + final String username = subject.getPrincipals().iterator().next() + .getName(); + if (log.isDebugEnabled()) + log.debug(username + " logged in"); + display.disposeExec(new Runnable() { + public void run() { + log.debug("Display disposed"); + logout(loginContext, username); + // invalidate session + RWT.getRequest().getSession().setMaxInactiveInterval(1); try { - // force login in order to give Spring Security a chance to - // load - SecureRapActivator.getLoginContext().login(); - subject = SecureRapActivator.getLoginContext().getSubject(); - retry = false; - } catch (LoginException e) { - Error.show("Cannot login", e); - retry = true; - } catch (Exception e) { - Error.show("Unexpected exception while trying to login", e); - retry = false; + Thread.sleep(2000); + } catch (InterruptedException e1) { + // silent } } + }); - if (subject != null) { - returnCode = (Integer) Subject.doAs(subject, - getRunAction(display)); - SecureRapActivator.getLoginContext().logout(); - return processReturnCode(returnCode); - } else { - return -1; - } + try { + returnCode = (Integer) Subject.doAs(subject, getRunAction(display)); + loginContext.logout(); + return processReturnCode(returnCode); } catch (Exception e) { - log.error("Unexpected error",e); - return -1; - } -// finally { -// display.dispose(); -// } + if (subject != null) + logout(loginContext, username); + // RWT.getRequest().getSession().setMaxInactiveInterval(1); + log.error("Unexpected error", e); + // throw new ArgeoException("Cannot login", e); + } finally { + display.dispose(); + } + return -1; } + static void logout(ILoginContext secureContext, String username) { + try { + secureContext.logout(); + log.info("Logged out " + (username != null ? username : "") + + " (THREAD=" + Thread.currentThread().getId() + ")"); + } catch (LoginException e) { + log.error("Erorr when logging out", e); + } + } + + // static void closeWorkbench() { + // final IWorkbench workbench; + // try { + // workbench = PlatformUI.getWorkbench(); + // } catch (Exception e) { + // return; + // } + // if (workbench == null) + // return; + // final Display display = workbench.getDisplay(); + // if (display != null && !display.isDisposed()) + // display.syncExec(new Runnable() { + // + // public void run() { + // if (!display.isDisposed()) + // workbench.close(); + // } + // }); + // + // if (log.isDebugEnabled()) + // log.debug("Workbench closed"); + // } + @SuppressWarnings("rawtypes") private PrivilegedAction getRunAction(final Display display) { return new PrivilegedAction() { diff --git a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureRapActivator.java b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureRapActivator.java index b8c66cda3..2a29ba7e0 100644 --- a/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureRapActivator.java +++ b/security/plugins/org.argeo.security.ui.rap/src/main/java/org/argeo/security/ui/rap/SecureRapActivator.java @@ -2,7 +2,6 @@ package org.argeo.security.ui.rap; import java.net.URL; -import org.argeo.ArgeoException; import org.eclipse.equinox.security.auth.ILoginContext; import org.eclipse.equinox.security.auth.LoginContextFactory; import org.osgi.framework.BundleActivator; @@ -14,21 +13,29 @@ public class SecureRapActivator implements BundleActivator { public final static String CONTEXT_SPRING = "SPRING"; private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt"; - private static ILoginContext loginContext = null; + //private static ILoginContext loginContext = null; + + private static BundleContext bundleContext; public void start(BundleContext bundleContext) throws Exception { - URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE); - loginContext = LoginContextFactory.createContext(CONTEXT_SPRING, - configUrl); + SecureRapActivator.bundleContext = bundleContext; +// URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE); +// loginContext = LoginContextFactory.createContext(CONTEXT_SPRING, +// configUrl); } public void stop(BundleContext context) throws Exception { } - static ILoginContext getLoginContext() { - if (loginContext == null) - throw new ArgeoException( - "No Equinox login context available, check your configuration"); - return loginContext; +// static ILoginContext getLoginContext() { +// if (loginContext == null) +// throw new ArgeoException( +// "No Equinox login context available, check your configuration"); +// return loginContext; +// } + + static ILoginContext createLoginContext() { + URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE); + return LoginContextFactory.createContext(CONTEXT_SPRING, configUrl); } } diff --git a/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/DefaultLoginDialog.java b/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/DefaultLoginDialog.java index 19affc854..96f0535d9 100644 --- a/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/DefaultLoginDialog.java +++ b/security/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/DefaultLoginDialog.java @@ -26,6 +26,7 @@ public class DefaultLoginDialog extends AbstractLoginDialog { protected DefaultLoginDialog(Shell parentShell) { super(parentShell); + // setBlockOnOpen(false); } protected Point getInitialSize() { @@ -109,4 +110,35 @@ public class DefaultLoginDialog extends AbstractLoginDialog { public void internalHandle() { } + + // hack to simulate modal + // see + // http://dev.eclipse.org/mhonarc/newsLists/news.eclipse.platform.jface/msg00181.html + // protected void setShellStyle(int newShellStyle) { + // // turn off APPLICATION_MODAL + // int newstyle = newShellStyle & ~SWT.APPLICATION_MODAL; + // // turn on MODELESS + // newstyle |= SWT.MODELESS; + // super.setShellStyle(newstyle); + // } + // + // public int open() { + // + // int retVal = super.open(); + // // this will let the caller wait till OK, Cancel is + // // pressed, but will let the other GUI responsive + // pumpMessages(); + // return retVal; + // } + // + // protected void pumpMessages() { + // Shell sh = getShell(); + // Display disp = sh.getDisplay(); + // while (!sh.isDisposed()) { + // if (!disp.readAndDispatch()) + // disp.sleep(); + // } + // disp.update(); + // } + }