From: Mathieu Baudier Date: Mon, 17 Jan 2011 09:28:37 +0000 (+0000) Subject: Improve Eclipse security X-Git-Tag: argeo-commons-2.1.30~1516 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=8fa413581f5a42ace1817da8c84c86e8ea47fb15;p=lgpl%2Fargeo-commons.git Improve Eclipse security git-svn-id: https://svn.argeo.org/commons/trunk@4042 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java index d89ddee5a..12cda5371 100644 --- a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java +++ b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java @@ -1,14 +1,16 @@ package org.argeo.security.equinox; +import java.security.AccessController; import java.security.Principal; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.security.auth.Subject; +import javax.security.auth.login.LoginException; +import org.argeo.ArgeoException; import org.eclipse.equinox.security.auth.ILoginContext; -import org.eclipse.equinox.security.auth.LoginContextFactory; import org.springframework.security.Authentication; import org.springframework.security.GrantedAuthority; @@ -34,8 +36,8 @@ public class CurrentUser { private final static ILoginContext getLoginContext() { return EquinoxSecurity.getLoginContext(); -// return LoginContextFactory -// .createContext(EquinoxSecurity.CONTEXT_SPRING); + // return LoginContextFactory + // .createContext(EquinoxSecurity.CONTEXT_SPRING); } // private static void login() { @@ -48,17 +50,25 @@ public class CurrentUser { public final static Subject getSubject() { - Subject subject = null; + Subject subject = Subject.getSubject(AccessController.getContext()); // subject = Subject.getSubject(AccessController.getContext()); - try { - getLoginContext().login(); - subject = getLoginContext().getSubject(); - } catch (Exception e) { - throw new RuntimeException("Cannot retrieve subject", e); - } + if (subject == null) + try { + getLoginContext().login(); + subject = getLoginContext().getSubject(); + } catch (Exception e) { + throw new ArgeoException("Cannot retrieve subject", e); + } return subject; } + public static void logout() { + try { + getLoginContext().logout(); + } catch (LoginException e) { + throw new ArgeoException("Cannot log out", e); + } + } } diff --git a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java index e1a72b14f..61c5e796e 100644 --- a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java +++ b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java @@ -11,28 +11,20 @@ public class EquinoxSecurity implements BundleActivator { public final static String CONTEXT_SPRING = "SPRING"; private static final String JAAS_CONFIG_FILE = "jaas/jaas_default.txt"; - private static BundleContext bundleContext; - - public void start(BundleContext context) throws Exception { - bundleContext = context; - // URL url = new URL( - // "file:////home/mbaudier/dev/src/commons/security/eclipse/plugins/org.argeo.security.ui.rcp/jaas_config.txt"); - // // URL url = new URL( - // // - // "file:////home/mbaudier/dev/src/commons/security/eclipse/plugins/org.argeo.security.ui.rcp/jaas_config.txt"); - // ILoginContext secureContext = LoginContextFactory.createContext( - // configName, url); - getLoginContext(); + private static ILoginContext loginContext = null; + + public void start(BundleContext bundleContext) throws Exception { + // getLoginContext(); + URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE); + loginContext = LoginContextFactory.createContext(CONTEXT_SPRING, + configUrl); } public void stop(BundleContext context) throws Exception { - bundleContext = null; } static ILoginContext getLoginContext() { - String configName = CONTEXT_SPRING; - URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE); - return LoginContextFactory.createContext(configName, configUrl); + return loginContext; } } diff --git a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java index 4f8641c26..3f88a00d9 100644 --- a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java +++ b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java @@ -10,15 +10,17 @@ import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.TextOutputCallback; import javax.security.auth.login.LoginException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.security.Authentication; -import org.springframework.security.AuthenticationException; import org.springframework.security.AuthenticationManager; -import org.springframework.security.BadCredentialsException; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.jaas.SecurityContextLoginModule; public class SpringLoginModule extends SecurityContextLoginModule { + private final static Log log = LogFactory.getLog(SpringLoginModule.class); + private AuthenticationManager authenticationManager; private Subject subject; @@ -58,8 +60,8 @@ public class SpringLoginModule extends SecurityContextLoginModule { "Password", false); if (callbackHandler == null) { - // throw new LoginException("No call back handler available"); - return false; + throw new LoginException("No call back handler available"); + // return false; } try { callbackHandler.handle(new Callback[] { label, nameCallback, @@ -94,6 +96,14 @@ public class SpringLoginModule extends SecurityContextLoginModule { } } + @Override + public boolean logout() throws LoginException { + if (log.isDebugEnabled()) + log.debug("Log out " + + subject.getPrincipals().iterator().next().getName()); + return super.logout(); + } + /** * Register an {@link Authentication} in the security context. * diff --git a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/AbstractSecureApplication.java b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/AbstractSecureApplication.java new file mode 100644 index 000000000..f7c5fc5d1 --- /dev/null +++ b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/AbstractSecureApplication.java @@ -0,0 +1,101 @@ +package org.argeo.security.ui.rcp; + +import java.security.PrivilegedAction; + +import javax.security.auth.Subject; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.security.equinox.CurrentUser; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.application.WorkbenchAdvisor; + +public abstract class AbstractSecureApplication implements IApplication { + private static final Log log = LogFactory + .getLog(AbstractSecureApplication.class); + + protected abstract WorkbenchAdvisor createWorkbenchAdvisor(); + + public Object start(IApplicationContext context) throws Exception { + + Integer returnCode = null; + Display display = PlatformUI.createDisplay(); + + // Force login + String username = CurrentUser.getUsername(); + if (log.isDebugEnabled()) + log.debug("Logged in as " + username); + + try { + returnCode = (Integer) Subject.doAs(CurrentUser.getSubject(), + getRunAction(display)); + if (log.isDebugEnabled()) + log.debug("secure action completed"); + CurrentUser.logout(); + return processReturnCode(returnCode); + } catch (Exception e) { + // e.printStackTrace(); + IStatus status = new Status(IStatus.ERROR, + "org.argeo.security.rcp", "Login failed", e); + ErrorDialog.openError(null, "Error", "Login failed", status); + return returnCode; + } finally { + display.dispose(); + } + } + + protected Integer processReturnCode(Integer returnCode) { + return returnCode; + } + + @SuppressWarnings("rawtypes") + private PrivilegedAction getRunAction(final Display display) { + return new PrivilegedAction() { + + public Object run() { + int result = createAndRunWorkbench(display); + return new Integer(result); + } + }; + } + + protected Integer createAndRunWorkbench(Display display) { + return PlatformUI.createAndRunWorkbench(display, + createWorkbenchAdvisor()); + } + + public void stop() { + 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 stopped"); + String username = CurrentUser.getUsername(); + if (log.isDebugEnabled()) + log.debug("workbench stopped, logged in as " + username); + + } + +} diff --git a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/RapSecureWorkbenchWindowAdvisor.java b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/RapSecureWorkbenchWindowAdvisor.java index bfb57b475..0025330e7 100644 --- a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/RapSecureWorkbenchWindowAdvisor.java +++ b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/RapSecureWorkbenchWindowAdvisor.java @@ -4,6 +4,8 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; public class RapSecureWorkbenchWindowAdvisor extends @@ -13,12 +15,18 @@ public class RapSecureWorkbenchWindowAdvisor extends super(configurer); } + @Override + public ActionBarAdvisor createActionBarAdvisor( + IActionBarConfigurer configurer) { + return new SecureActionBarAdvisor(configurer, false); + } + public void preWindowOpen() { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); -// configurer.setInitialSize(new Point(800, 600)); + // configurer.setInitialSize(new Point(800, 600)); configurer.setShowCoolBar(false); configurer.setShowMenuBar(true); - configurer.setShowStatusLine(true); + configurer.setShowStatusLine(false); configurer.setShowPerspectiveBar(true); configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$ // Full screen, see diff --git a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureActionBarAdvisor.java b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureActionBarAdvisor.java index d5978888f..04e61002c 100644 --- a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureActionBarAdvisor.java +++ b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureActionBarAdvisor.java @@ -13,25 +13,39 @@ import org.eclipse.ui.application.IActionBarConfigurer; public class SecureActionBarAdvisor extends ActionBarAdvisor { private IWorkbenchAction exitAction; - // private IWorkbenchAction aboutAction; + private IWorkbenchAction openPerspectiveDialogAction; + private IWorkbenchAction showViewMenuAction; private IWorkbenchAction newWindowAction; - private IWorkbenchAction preferences = null; + private IWorkbenchAction preferences; + private IWorkbenchAction helpContentAction; + // private IWorkbenchAction aboutAction; - public SecureActionBarAdvisor(IActionBarConfigurer configurer) { + private final Boolean isRcp; + + public SecureActionBarAdvisor(IActionBarConfigurer configurer, Boolean isRcp) { super(configurer); + this.isRcp = isRcp; } protected void makeActions(IWorkbenchWindow window) { preferences = ActionFactory.PREFERENCES.create(window); register(preferences); + openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG + .create(window); + register(openPerspectiveDialogAction); + showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window); + register(showViewMenuAction); + helpContentAction = ActionFactory.HELP_CONTENTS.create(window); + register(helpContentAction); + exitAction = ActionFactory.QUIT.create(window); register(exitAction); - - // aboutAction = ActionFactory.ABOUT.create(window); - // register(aboutAction); - - newWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window); - register(newWindowAction); + if (isRcp) { + // aboutAction = ActionFactory.ABOUT.create(window); + // register(aboutAction); + newWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window); + register(newWindowAction); + } } protected void fillMenuBar(IMenuManager menuBar) { @@ -39,24 +53,34 @@ public class SecureActionBarAdvisor extends ActionBarAdvisor { IWorkbenchActionConstants.M_FILE); MenuManager editMenu = new MenuManager("&Edit", IWorkbenchActionConstants.M_EDIT); + MenuManager windowMenu = new MenuManager("&Window", + IWorkbenchActionConstants.M_WINDOW); MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP); menuBar.add(fileMenu); menuBar.add(editMenu); + menuBar.add(windowMenu); // Add a group marker indicating where action set menus will appear. menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); menuBar.add(helpMenu); // File - fileMenu.add(newWindowAction); - fileMenu.add(new Separator()); + if (isRcp) { + fileMenu.add(newWindowAction); + fileMenu.add(new Separator()); + } fileMenu.add(exitAction); // Edit editMenu.add(preferences); + // Window + windowMenu.add(openPerspectiveDialogAction); + windowMenu.add(showViewMenuAction); + // Help + helpMenu.add(helpContentAction); // helpMenu.add(aboutAction); } diff --git a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRap.java b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRap.java index a426d4579..964de7c39 100644 --- a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRap.java +++ b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRap.java @@ -1,53 +1,28 @@ package org.argeo.security.ui.rcp; -import java.security.PrivilegedAction; - -import javax.security.auth.Subject; - -import org.argeo.security.equinox.CurrentUser; -import org.eclipse.equinox.app.IApplication; -import org.eclipse.equinox.app.IApplicationContext; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.application.WorkbenchWindowAdvisor; -public class SecureRap implements IApplication { - public Object start(IApplicationContext context) throws Exception { - String username = CurrentUser.getUsername(); - Integer result = null; - Display display = PlatformUI.createDisplay(); - try { - result = (Integer) Subject.doAs(CurrentUser.getSubject(), - getRunAction(display)); - } catch (Exception e) { - e.printStackTrace(); - } finally { - display.dispose(); - } - return result; - } - - @SuppressWarnings("rawtypes") - private PrivilegedAction getRunAction(final Display display) { - return new PrivilegedAction() { +/** Generic secure application for RAP. */ +public class SecureRap extends AbstractSecureApplication { - public Object run() { - int result = PlatformUI.createAndRunWorkbench(display, - new ApplicationWorkbenchAdvisor()); - return new Integer(result); + @Override + protected WorkbenchAdvisor createWorkbenchAdvisor() { + return new SecureWorkbenchAdvisor() { + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + IWorkbenchWindowConfigurer configurer) { + return new RapSecureWorkbenchWindowAdvisor(configurer); } + }; } public void stop() { - final IWorkbench workbench; - try { - workbench = PlatformUI.getWorkbench(); - } catch (Exception e) { - return; - } + final IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench == null) return; final Display display = workbench.getDisplay(); @@ -60,11 +35,4 @@ public class SecureRap implements IApplication { }); } - class ApplicationWorkbenchAdvisor extends SecureWorkbenchAdvisor { - public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( - IWorkbenchWindowConfigurer configurer) { - return new RapSecureWorkbenchWindowAdvisor(configurer); - } - } - } diff --git a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRcp.java b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRcp.java index 47a535984..cd1d518b4 100644 --- a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRcp.java +++ b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureRcp.java @@ -1,70 +1,21 @@ package org.argeo.security.ui.rcp; -import java.security.PrivilegedAction; - -import javax.security.auth.Subject; - -import org.argeo.security.equinox.CurrentUser; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; import org.eclipse.equinox.app.IApplication; -import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.application.WorkbenchAdvisor; -public class SecureRcp implements IApplication { - public Object start(IApplicationContext context) throws Exception { - String username = CurrentUser.getUsername(); - Integer returnCode = null; - Display display = PlatformUI.createDisplay(); - try { - returnCode = (Integer) Subject.doAs(CurrentUser.getSubject(), - getRunAction(display)); - if (returnCode == PlatformUI.RETURN_RESTART) - return IApplication.EXIT_RESTART; - else - return IApplication.EXIT_OK; - } catch (Exception e) { - // e.printStackTrace(); - IStatus status = new Status(IStatus.ERROR, - "org.eclipse.rap.security.demo", "Login failed", e); - ErrorDialog.openError(null, "Error", "Login failed", status); - } finally { - display.dispose(); - } - return returnCode; - } +public class SecureRcp extends AbstractSecureApplication { - private PrivilegedAction getRunAction(final Display display) { - return new PrivilegedAction() { - - public Object run() { - int result = PlatformUI.createAndRunWorkbench(display, - new SecureWorkbenchAdvisor()); - return new Integer(result); - } - }; + @Override + protected WorkbenchAdvisor createWorkbenchAdvisor() { + return new SecureWorkbenchAdvisor(); } - public void stop() { - final IWorkbench workbench; - try { - workbench = PlatformUI.getWorkbench(); - } catch (Exception e) { - return; - } - if (workbench == null) - return; - final Display display = workbench.getDisplay(); - display.syncExec(new Runnable() { - - public void run() { - if (!display.isDisposed()) - workbench.close(); - } - }); + protected Integer processReturnCode(Integer returnCode) { + if (returnCode == PlatformUI.RETURN_RESTART) + return IApplication.EXIT_RESTART; + else + return IApplication.EXIT_OK; } } diff --git a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureWorkbenchWindowAdvisor.java b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureWorkbenchWindowAdvisor.java index 146ac8f10..a1022fe6a 100644 --- a/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureWorkbenchWindowAdvisor.java +++ b/security/eclipse/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/SecureWorkbenchWindowAdvisor.java @@ -14,7 +14,7 @@ public class SecureWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { public ActionBarAdvisor createActionBarAdvisor( IActionBarConfigurer configurer) { - return new SecureActionBarAdvisor(configurer); + return new SecureActionBarAdvisor(configurer, true); } public void preWindowOpen() { @@ -22,7 +22,7 @@ public class SecureWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { configurer.setInitialSize(new Point(800, 600)); configurer.setShowCoolBar(false); configurer.setShowMenuBar(true); - configurer.setShowStatusLine(true); + configurer.setShowStatusLine(false); configurer.setShowPerspectiveBar(true); configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$ }