xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
+ <bean
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
+ <property name="locations">
+ <value>osgibundle:security.properties</value>
+ </property>
+ </bean>
+
<bean id="springLoginModule" class="org.argeo.security.equinox.SpringLoginModule"
scope="prototype">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
+ <bean id="anonymousSpringLoginModule" class="org.argeo.security.equinox.SpringLoginModule"
+ scope="prototype">
+ <property name="anonymous" value="true" />
+ <property name="anonymousRole" value="${argeo.security.anonymousRole}" />
+ <property name="key" value="${argeo.security.systemKey}" />
+ <property name="authenticationManager" ref="authenticationManager" />
+ </bean>
+
<bean id="osSpringLoginModule" class="org.argeo.security.equinox.OsSpringLoginModule"
scope="prototype">
<property name="authenticationManager" ref="authenticationManager" />
<plugin>
<!-- Argeo -->
<extension id="springLoginModule" name="Argeo Spring" point="org.eclipse.equinox.security.loginModule">
- <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Argeo Spring Login Module"/>
+ <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Username/password authentication"/>
</extension>
- <extension id="springLoginModuleRemote" name="Argeo Spring" point="org.eclipse.equinox.security.loginModule">
- <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Argeo Spring Login Module"/>
+ <extension id="springLoginModuleRemote" name="Argeo Spring Remote" point="org.eclipse.equinox.security.loginModule">
+ <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Delegates authentication to a remote URL (typically JCR)"/>
+ </extension>
+
+ <extension id="anonymousSpringLoginModule" name="Argeo Spring Anonymous" point="org.eclipse.equinox.security.loginModule">
+ <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Public access without authentication"/>
</extension>
<extension id="osSpringLoginModule" name="Argeo Spring OS" point="org.eclipse.equinox.security.loginModule">
- <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Argeo Spring OS Login Module"/>
+ <loginModule class="org.argeo.eclipse.spring.SpringExtensionFactory" description="Use the operating system authentication of the JVM"/>
</extension>
<!-- Java -->
--- /dev/null
+argeo.security.systemKey=argeo
+
+argeo.security.anonymousRole=ROLE_ANONYMOUS
package org.argeo.security.equinox;
import java.util.Map;
+import java.util.UUID;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.BadCredentialsException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
import org.springframework.security.providers.jaas.SecurityContextLoginModule;
/** Login module which caches one subject per thread. */
private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
private Boolean remote = false;
+ private Boolean anonymous = false;
+
+ private String key = null;
+ private String anonymousRole = "ROLE_ANONYMOUS";
public SpringLoginModule() {
if (SecurityContextHolder.getContext().getAuthentication() != null)
return super.login();
+ if (remote && anonymous)
+ throw new LoginException(
+ "Cannot have a Spring login module which is remote and anonymous");
+
// reset all principals and credentials
if (log.isTraceEnabled())
log.trace("Resetting all principals and credentials of "
if (subject.getPublicCredentials() != null)
subject.getPublicCredentials().clear();
+ // deals first with public access since it's simple
+ if (anonymous) {
+ // TODO integrate with JCR?
+ Object principal = UUID.randomUUID().toString();
+ GrantedAuthority[] authorities = { new GrantedAuthorityImpl(
+ anonymousRole) };
+ AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
+ key, principal, authorities);
+ Authentication auth = authenticationManager
+ .authenticate(anonymousToken);
+ registerAuthentication(auth);
+ return super.login();
+ }
+
if (callbackHandler == null)
throw new LoginException("No call back handler available");
this.authenticationManager = authenticationManager;
}
+ /** Authenticates on a remote node */
public void setRemote(Boolean remote) {
this.remote = remote;
}
+
+ /**
+ * Request anonymous authentication (incompatible with remote)
+ */
+ public void setAnonymous(Boolean anonymous) {
+ this.anonymous = anonymous;
+ }
+
+ /** Role identifying an anonymous user */
+ public void setAnonymousRole(String anonymousRole) {
+ this.anonymousRole = anonymousRole;
+ }
+
+ /** System key */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
}
extensionId="org.argeo.security.equinox.springLoginModule";
};
+SPRING_ANONYMOUS {
+ org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
+ extensionId="org.argeo.security.equinox.anonymousSpringLoginModule";
+};
+
SPRING_SECURITY_CONTEXT {
org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
extensionId="org.argeo.security.equinox.springSecurityContextLoginModule";
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="openChangePasswordDialog" class="org.argeo.security.ui.commands.OpenChangePasswordDialog"
+ scope="prototype">
+ <property name="userDetailsManager" ref="userDetailsManager" />
+ </bean>
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xmlns:osgi="http://www.springframework.org/schema/osgi"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
+ osgi:default-timeout="30000">\r
+\r
+ <reference id="userDetailsManager"\r
+ interface="org.springframework.security.userdetails.UserDetailsManager"\r
+ cardinality="0..1" />\r
+</beans:beans>
\ No newline at end of file
--- /dev/null
+<html>
+<head></head>
+<body>
+<center>
+<table height="100%">
+<tr>
+ <td style="vertical-align:middle">
+ <a
+ style="font-family:sans-serif;color:#0066CC;text-decoration:none;"
+ href="javascript:location.reload(true);"
+ title="Refresh"
+ >Refresh...</a>
+ </td>
+</tr>
+</table>
+</center>
+</body>
+</html>
\ No newline at end of file
bin.includes = plugin.xml,\
META-INF/,\
- branding/
+ branding/,\
+ icons/
source.. = src/main/java/
output.. = target/classes/
<extension
point="org.eclipse.rap.ui.entrypoint">
<entrypoint
- class="org.argeo.security.ui.rap.SecureEntryPoint"
id="org.argeo.security.ui.rap.secureEntryPoint"
+ class="org.argeo.security.ui.rap.SecureEntryPoint"
parameter="secureWebUi">
</entrypoint>
+ <entrypoint
+ id="org.argeo.security.ui.rap.anonymousEntryPoint"
+ class="org.argeo.security.ui.rap.AnonymousEntryPoint"
+ parameter="publicWebUi">
+ </entrypoint>
</extension>
<extension
defaultEntrypointId="org.argeo.security.ui.rap.secureEntryPoint"
title="Argeo Web UI"
favicon="branding/favicon.ico"
- body="branding/default.htm">
+ body="branding/public.html">
+ </branding>
+ <branding
+ id="org.argeo.security.ui.rap.branding"
+ servletName="public"
+ defaultEntrypointId="org.argeo.security.ui.rap.anonymousEntryPoint"
+ title="Argeo Public Web UI"
+ favicon="branding/favicon.ico"
+ body="branding/public.html">
</branding>
</extension>
</callbackHandlerMapping>
</extension>
+ <extension point="org.eclipse.ui.menus">
+ <menuContribution locationURI="toolbar:org.eclipse.ui.main.toolbar">
+ <toolbar id="org.argeo.security.ui.rap.userToolbar">
+ <command
+ commandId="org.argeo.security.ui.rap.mainMenuCommand"
+ icon="icons/main.gif"
+ id="org.argeo.security.ui.rap.mainMenu"
+ style="pulldown">
+ </command>
+ <command commandId="org.eclipse.ui.file.save"/>
+ <command commandId="org.eclipse.ui.file.saveAll"/>
+ </toolbar>
+ </menuContribution>
+ <menuContribution locationURI="menu:org.argeo.security.ui.rap.mainMenu">
+ <command
+ commandId="org.argeo.security.ui.rap.userMenuCommand"
+ icon="icons/home.gif"
+ id="org.argeo.security.ui.rap.userMenu">
+ </command>
+ <command
+ commandId="org.eclipse.ui.window.preferences"
+ icon="icons/preferences.png"/>
+ <command
+ commandId="org.argeo.security.ui.rap.openChangePasswordDialog"
+ icon="icons/password.gif"
+ label="Change password"/>
+ <separator
+ name="org.argeo.security.ui.rap.beforeFile"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.file.closeAll"
+ icon="icons/closeAll.gif"/>
+ <command commandId="org.eclipse.ui.file.save"/>
+ <command commandId="org.eclipse.ui.file.saveAll"/>
+ <separator
+ name="org.argeo.security.ui.rap.beforeExit"
+ visible="true">
+ </separator>
+ <!--<command commandId="org.eclipse.ui.views.showView"/>-->
+ <!--<command commandId="org.eclipse.ui.perspectives.showPerspective"/>-->
+ <command
+ commandId="org.eclipse.ui.file.exit"
+ icon="icons/exit.png"/>
+ </menuContribution>
+ </extension>
+
+ <extension point="org.eclipse.ui.commands">
+ <command
+ id="org.argeo.security.ui.rap.openChangePasswordDialog"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Change Password">
+ </command>
+ <command
+ id="org.argeo.security.ui.rap.mainMenuCommand"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Main">
+ </command>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.activities">
+ <activity
+ description="Not anonymous"
+ id="org.argeo.security.ui.rap.notAnonymousActivity"
+ name="NotAnonymous">
+ <enabledWhen>
+ <not>
+ <with variable="roles">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="ROLE_ANONYMOUS" />
+ </iterate>
+ </with>
+ </not>
+ </enabledWhen>
+ </activity>
+ <activityPatternBinding
+ activityId="org.argeo.security.ui.rap.notAnonymousActivity"
+ pattern="org.argeo.security.ui.rap/org.argeo.security.ui.rap.userMenuCommand"/>
+ <activityPatternBinding
+ activityId="org.argeo.security.ui.rap.notAnonymousActivity"
+ pattern="org.argeo.security.ui.rap/org.eclipse.ui.window.preferences"/>
+ <activityPatternBinding
+ activityId="org.argeo.security.ui.rap.notAnonymousActivity"
+ pattern="org.argeo.security.ui.rap/org.argeo.security.ui.rap.openChangePasswordDialog"/>
+ </extension>
</plugin>
<Bundle-Activator>org.argeo.security.ui.rap.SecureRapActivator</Bundle-Activator>
<Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
<Require-Bundle>org.eclipse.rap.ui,org.eclipse.core.runtime</Require-Bundle>
- <Import-Package>org.springframework.core,*</Import-Package>
+ <Import-Package>org.springframework.core,org.argeo.eclipse.spring,*</Import-Package>
</instructions>
</configuration>
</plugin>
--- /dev/null
+package org.argeo.security.ui.rap;
+
+import java.security.PrivilegedAction;
+
+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.equinox.security.auth.ILoginContext;
+import org.eclipse.rwt.RWT;
+import org.eclipse.rwt.lifecycle.IEntryPoint;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * RAP entry point which authenticates the subject as anonymous, for public
+ * unauthenticated access.
+ */
+public class AnonymousEntryPoint implements IEntryPoint {
+ private final static Log log = LogFactory.getLog(AnonymousEntryPoint.class);
+
+ /**
+ * How many seconds to wait before invalidating the session if the user has
+ * not yet logged in.
+ */
+ private Integer loginTimeout = 1 * 60;
+ private Integer sessionTimeout = 15 * 60;
+
+ @Override
+ public int createUI() {
+ // Short login timeout so that the modal dialog login doesn't hang
+ // around too long
+ RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
+
+ if (log.isDebugEnabled())
+ log.debug("Anonymous THREAD=" + Thread.currentThread().getId()
+ + ", sessionStore=" + RWT.getSessionStore().getId());
+
+ // create display
+ final Display display = PlatformUI.createDisplay();
+
+ // log in
+ final ILoginContext loginContext = SecureRapActivator
+ .createLoginContext(SecureRapActivator.CONTEXT_SPRING_ANONYMOUS);
+ Subject subject = null;
+ try {
+ loginContext.login();
+ subject = loginContext.getSubject();
+ } catch (LoginException e) {
+ throw new ArgeoException(
+ "Unexpected exception during authentication", e);
+ }
+
+ // identify after successful login
+ if (log.isDebugEnabled())
+ log.debug("Authenticated " + subject);
+ final String username = subject.getPrincipals().iterator().next()
+ .getName();
+
+ // Once the user is logged in, she can have a longer session timeout
+ RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
+
+ // Logout callback when the display is disposed
+ display.disposeExec(new Runnable() {
+ public void run() {
+ log.debug("Display disposed");
+ logout(loginContext, username);
+ }
+ });
+
+ //
+ // RUN THE WORKBENCH
+ //
+ Integer returnCode = null;
+ try {
+ returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
+ public Integer run() {
+ RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor(
+ null);
+ int result = PlatformUI.createAndRunWorkbench(display,
+ workbenchAdvisor);
+ return new Integer(result);
+ }
+ });
+ logout(loginContext, username);
+ } finally {
+ display.dispose();
+ }
+ return returnCode;
+ }
+
+ private 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);
+ }
+ }
+}
--- /dev/null
+package org.argeo.security.ui.rap;
+
+import org.argeo.security.ui.rap.commands.UserMenu;
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.commands.ICommandService;
+
+/** Eclipse rap specific action bar advisor */
+public class RapActionBarAdvisor extends ActionBarAdvisor {
+ private final static String ID_BASE = "org.argeo.security.ui.rap";
+ // private final static Log log = LogFactory
+ // .getLog(SecureActionBarAdvisor.class);
+
+ /** Null means anonymous */
+ private String username = null;
+
+// private IAction logoutAction;
+// private IWorkbenchAction openPerspectiveDialogAction;
+// private IWorkbenchAction showViewMenuAction;
+// private IWorkbenchAction preferences;
+// private IWorkbenchAction saveAction;
+// private IWorkbenchAction saveAllAction;
+// private IWorkbenchAction closeAllAction;
+
+ public RapActionBarAdvisor(IActionBarConfigurer configurer, String username) {
+ super(configurer);
+ this.username = username;
+ }
+
+ 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);
+//
+// // logout
+// logoutAction = ActionFactory.QUIT.create(window);
+// // logoutAction = createLogoutAction();
+// register(logoutAction);
+//
+// // Save semantics
+// saveAction = ActionFactory.SAVE.create(window);
+// register(saveAction);
+// saveAllAction = ActionFactory.SAVE_ALL.create(window);
+// register(saveAllAction);
+// closeAllAction = ActionFactory.CLOSE_ALL.create(window);
+// register(closeAllAction);
+
+ }
+
+ protected void fillMenuBar(IMenuManager menuBar) {
+// MenuManager fileMenu = new MenuManager("&File",
+// IWorkbenchActionConstants.M_FILE);
+// MenuManager editMenu = new MenuManager("&Edit",
+// IWorkbenchActionConstants.M_EDIT);
+// MenuManager windowMenu = new MenuManager("&Window",
+// IWorkbenchActionConstants.M_WINDOW);
+//
+// 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));
+//
+// // File
+// fileMenu.add(saveAction);
+// fileMenu.add(saveAllAction);
+// fileMenu.add(closeAllAction);
+// fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+// fileMenu.add(new Separator());
+// fileMenu.add(logoutAction);
+//
+// // Edit
+// editMenu.add(preferences);
+//
+// // Window
+// windowMenu.add(openPerspectiveDialogAction);
+// windowMenu.add(showViewMenuAction);
+ }
+
+ @Override
+ protected void fillCoolBar(ICoolBarManager coolBar) {
+ if (username != null) {
+ ICommandService cmdService = (ICommandService) getActionBarConfigurer()
+ .getWindowConfigurer().getWorkbenchConfigurer()
+ .getWorkbench().getService(ICommandService.class);
+ Category userMenus = cmdService.getCategory(ID_BASE + ".userMenus");
+ if (!userMenus.isDefined())
+ userMenus.define("User Menus", "User related menus");
+
+ Command userMenu = cmdService.getCommand(ID_BASE
+ + ".userMenuCommand");
+ if (userMenu.isDefined())
+ userMenu.undefine();
+ userMenu.define(username, "User menu actions", userMenus);
+ userMenu.setHandler(new UserMenu());
+
+ // userToolbar.add(new UserMenuAction());
+ // coolBar.add(userToolbar);
+ } else {// anonymous
+ IToolBarManager userToolbar = new ToolBarManager(SWT.FLAT
+ | SWT.RIGHT);
+ //userToolbar.add(logoutAction);
+ coolBar.add(userToolbar);
+ }
+ // IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT |
+ // SWT.RIGHT);
+ // saveToolbar.add(saveAction);
+ // saveToolbar.add(saveAllAction);
+ // coolBar.add(saveToolbar);
+ }
+
+ // class UserMenuAction extends Action implements IWorkbenchAction {
+ //
+ // public UserMenuAction() {
+ // super(username, IAction.AS_DROP_DOWN_MENU);
+ // // setMenuCreator(new UserMenu());
+ // }
+ //
+ // @Override
+ // public String getId() {
+ // return "org.argeo.security.ui.rap.userMenu";
+ // }
+ //
+ // @Override
+ // public void dispose() {
+ // }
+ //
+ // }
+
+ // class UserMenu implements IMenuCreator {
+ // private Menu menu;
+ //
+ // public Menu getMenu(Control parent) {
+ // Menu menu = new Menu(parent);
+ // addActionToMenu(menu, logoutAction);
+ // return menu;
+ // }
+ //
+ // private void addActionToMenu(Menu menu, IAction action) {
+ // ActionContributionItem item = new ActionContributionItem(action);
+ // item.fill(menu, -1);
+ // }
+ //
+ // public void dispose() {
+ // if (menu != null) {
+ // menu.dispose();
+ // }
+ // }
+ //
+ // public Menu getMenu(Menu parent) {
+ // // Not use
+ // return null;
+ // }
+ //
+ // }
+
+ // protected IAction createLogoutAction() {
+ // Subject subject = Subject.getSubject(AccessController.getContext());
+ // final String username = subject.getPrincipals().iterator().next()
+ // .getName();
+ //
+ // IAction logoutAction = new Action() {
+ // public String getId() {
+ // return SecureRapActivator.ID + ".logoutAction";
+ // }
+ //
+ // public String getText() {
+ // 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);
+ // // }
+ // // 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);
+ // // }
+ // }
+ //
+ // };
+ // return logoutAction;
+ // }
+
+}
+++ /dev/null
-package org.argeo.security.ui.rap;
-
-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
- SecureWorkbenchWindowAdvisor {
- public RapSecureWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
- super(configurer);
- }
-
- @Override
- public ActionBarAdvisor createActionBarAdvisor(
- IActionBarConfigurer configurer) {
- return new SecureActionBarAdvisor(configurer, false);
- }
-
- public void preWindowOpen() {
- IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
- configurer.setShowCoolBar(true);
- configurer.setShowMenuBar(true);
- configurer.setShowStatusLine(false);
- configurer.setShowPerspectiveBar(true);
- configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$
- // Full screen, see
- // http://dev.eclipse.org/newslists/news.eclipse.technology.rap/msg02697.html
- configurer.setShellStyle(SWT.NONE);
- Rectangle bounds = Display.getCurrent().getBounds();
- configurer.setInitialSize(new Point(bounds.width, bounds.height));
- }
-
-}
--- /dev/null
+package org.argeo.security.ui.rap;
+
+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.IWorkbenchWindow;
+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;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/** Eclipse RAP specific window advisor */
+public class RapWindowAdvisor extends WorkbenchWindowAdvisor {
+
+ private String username;
+
+ public RapWindowAdvisor(IWorkbenchWindowConfigurer configurer,
+ String username) {
+ super(configurer);
+ this.username = username;
+ }
+
+ @Override
+ public ActionBarAdvisor createActionBarAdvisor(
+ IActionBarConfigurer configurer) {
+ return new RapActionBarAdvisor(configurer, username);
+ }
+
+ public void preWindowOpen() {
+ IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+ configurer.setShowCoolBar(true);
+ configurer.setShowMenuBar(false);
+ configurer.setShowStatusLine(false);
+ configurer.setShowPerspectiveBar(true);
+ configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$
+ // Full screen, see
+ // http://dev.eclipse.org/newslists/news.eclipse.technology.rap/msg02697.html
+ configurer.setShellStyle(SWT.NONE);
+ Rectangle bounds = Display.getCurrent().getBounds();
+ configurer.setInitialSize(new Point(bounds.width, bounds.height));
+ }
+
+ @Override
+ public void postWindowOpen() {
+ String defaultPerspective = getWindowConfigurer()
+ .getWorkbenchConfigurer().getWorkbench()
+ .getPerspectiveRegistry().getDefaultPerspective();
+ if (defaultPerspective == null) {
+ IWorkbenchWindow window = getWindowConfigurer().getWindow();
+ if (window == null)
+ return;
+
+ IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
+ .create(window);
+ openPerspectiveDialogAction.run();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.security.ui.rap;
+
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/** Eclipse RAP specific workbench advisor */
+public class RapWorkbenchAdvisor extends WorkbenchAdvisor {
+ public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
+ private String initialPerspective = System.getProperty(
+ INITIAL_PERSPECTIVE_PROPERTY, null);
+
+ private String username;
+
+ public RapWorkbenchAdvisor(String username) {
+ this.username = username;
+ }
+
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
+ IWorkbenchWindowConfigurer configurer) {
+ return new RapWindowAdvisor(configurer, username);
+ }
+
+ public String getInitialWindowPerspectiveId() {
+ if (initialPerspective != null) {
+ // check whether this user can see the declared perspective
+ // (typically the perspective won't be listed if this user doesn't
+ // have the right to see it)
+ IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
+ .getPerspectiveRegistry()
+ .findPerspectiveWithId(initialPerspective);
+ if (pd == null)
+ return null;
+ }
+ return initialPerspective;
+ }
+}
+++ /dev/null
-package org.argeo.security.ui.rap;
-
-import java.security.AccessController;
-
-import javax.security.auth.Subject;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.ICoolBarManager;
-import org.eclipse.jface.action.IMenuManager;
-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.swt.SWT;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchWindow;
-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 IAction logoutAction;
- private IWorkbenchAction openPerspectiveDialogAction;
- private IWorkbenchAction showViewMenuAction;
- private IWorkbenchAction preferences;
- private IWorkbenchAction saveAction;
- private IWorkbenchAction saveAllAction;
- private IWorkbenchAction closeAllAction;
-
- public SecureActionBarAdvisor(IActionBarConfigurer configurer, Boolean isRcp) {
- super(configurer);
- }
-
- 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);
-
- // logout
- logoutAction = ActionFactory.QUIT.create(window);
- //logoutAction = createLogoutAction();
- register(logoutAction);
-
- // Save semantics
- saveAction = ActionFactory.SAVE.create(window);
- register(saveAction);
- saveAllAction = ActionFactory.SAVE_ALL.create(window);
- register(saveAllAction);
- closeAllAction = ActionFactory.CLOSE_ALL.create(window);
- register(closeAllAction);
-
- }
-
- protected IAction createLogoutAction() {
- Subject subject = Subject.getSubject(AccessController.getContext());
- final String username = subject.getPrincipals().iterator().next()
- .getName();
-
- IAction logoutAction = new Action() {
- public String getId() {
- return SecureRapActivator.ID + ".logoutAction";
- }
-
- public String getText() {
- 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);
- // }
-// 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);
- // }
- }
-
- };
- return logoutAction;
- }
-
- protected void fillMenuBar(IMenuManager menuBar) {
- MenuManager fileMenu = new MenuManager("&File",
- IWorkbenchActionConstants.M_FILE);
- MenuManager editMenu = new MenuManager("&Edit",
- IWorkbenchActionConstants.M_EDIT);
- MenuManager windowMenu = new MenuManager("&Window",
- IWorkbenchActionConstants.M_WINDOW);
-
- 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));
-
- // File
- fileMenu.add(saveAction);
- fileMenu.add(saveAllAction);
- fileMenu.add(closeAllAction);
- fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
- fileMenu.add(new Separator());
- fileMenu.add(logoutAction);
-
- // Edit
- editMenu.add(preferences);
-
- // Window
- windowMenu.add(openPerspectiveDialogAction);
- windowMenu.add(showViewMenuAction);
- }
-
- @Override
- protected void fillCoolBar(ICoolBarManager coolBar) {
- IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
- saveToolbar.add(saveAction);
- saveToolbar.add(saveAllAction);
- coolBar.add(saveToolbar);
- }
-
-}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
import org.eclipse.equinox.security.auth.ILoginContext;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.rwt.RWT;
import org.eclipse.rwt.lifecycle.IEntryPoint;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.springframework.security.BadCredentialsException;
/**
- * RAP entry point with login capabilities. On the user has been authenticated,
- * the workbench is run as a privileged action by the related subject.
+ * RAP entry point with login capabilities. Once the user has been
+ * authenticated, the workbench is run as a privileged action by the related
+ * subject.
*/
public class SecureEntryPoint implements IEntryPoint {
private final static Log log = LogFactory.getLog(SecureEntryPoint.class);
* not yet logged in.
*/
private Integer loginTimeout = 1 * 60;
- private Integer sessionTimeout = 15 * 60;
+ // TODO make it configurable
+ /** Default session timeout is 8 hours (European working day length) */
+ private Integer sessionTimeout = 8 * 60 * 60;
@Override
public int createUI() {
log.debug("THREAD=" + Thread.currentThread().getId()
+ ", sessionStore=" + RWT.getSessionStore().getId());
- Integer returnCode = null;
-
// create display
- Display display = PlatformUI.createDisplay();
+ final Display display = PlatformUI.createDisplay();
// log in
final ILoginContext loginContext = SecureRapActivator
- .createLoginContext();
+ .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
Subject subject = null;
tryLogin: while (subject == null && !display.isDisposed()) {
try {
// retry login
continue tryLogin;
}
-
- // check thread death
- ThreadDeath td = wasCausedByThreadDeath(e);
- if (td != null) {
- display.dispose();
- throw td;
- }
-
- if (!display.isDisposed()) {
- org.argeo.eclipse.ui.Error.show(
- "Unexpected exception during authentication", e);
- // this was not just bad credentials or death thread
- RWT.getRequest().getSession().setMaxInactiveInterval(1);
- display.dispose();
- return -1;
- } else {
- throw new ArgeoException(
- "Unexpected exception during authentication", e);
- }
+ return processLoginDeath(display, e);
}
}
- // identify after successful login
+ // Once the user is logged in, she can have a longer session timeout
+ RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
if (log.isDebugEnabled())
log.debug("Authenticated " + subject);
+
final String username = subject.getPrincipals().iterator().next()
.getName();
-
- // Once the user is logged in, she can have a longer session timeout
- RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
-
// Logout callback when the display is disposed
display.disposeExec(new Runnable() {
public void run() {
//
// RUN THE WORKBENCH
//
+ Integer returnCode = null;
try {
- returnCode = (Integer) Subject.doAs(subject, getRunAction(display));
+ returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
+ public Integer run() {
+ RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor(
+ username);
+ int result = PlatformUI.createAndRunWorkbench(display,
+ workbenchAdvisor);
+ return new Integer(result);
+ }
+ });
logout(loginContext, username);
} finally {
display.dispose();
}
- return processReturnCode(returnCode);
+ return returnCode;
+ }
+
+ private Integer processLoginDeath(Display display, LoginException e) {
+ // check thread death
+ ThreadDeath td = wasCausedByThreadDeath(e);
+ if (td != null) {
+ display.dispose();
+ throw td;
+ }
+ if (!display.isDisposed()) {
+ ErrorFeedback.show("Unexpected exception during authentication", e);
+ // this was not just bad credentials or death thread
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ display.dispose();
+ return -1;
+ } else {
+ throw new ArgeoException(
+ "Unexpected exception during authentication", e);
+ }
+
}
/** Recursively look for {@link BadCredentialsException} in the root causes. */
log.error("Erorr when logging out", e);
}
}
-
- @SuppressWarnings("rawtypes")
- private PrivilegedAction getRunAction(final Display display) {
- return new PrivilegedAction() {
- public Object run() {
- int result = createAndRunWorkbench(display);
- return new Integer(result);
- }
- };
- }
-
- /** To be overridden */
- protected Integer createAndRunWorkbench(Display display) {
- return PlatformUI.createAndRunWorkbench(display,
- createWorkbenchAdvisor());
- }
-
- /** To be overridden */
- protected Integer processReturnCode(Integer returnCode) {
- return returnCode;
- }
-
- /** To be overridden */
- protected WorkbenchAdvisor createWorkbenchAdvisor() {
- return new SecureWorkbenchAdvisor() {
- public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
- IWorkbenchWindowConfigurer configurer) {
- return new RapSecureWorkbenchWindowAdvisor(configurer);
- }
-
- };
- }
}
public final static String ID = "org.argeo.security.ui.rap";
public final static String CONTEXT_SPRING = "SPRING";
+ public final static String CONTEXT_SPRING_ANONYMOUS = "SPRING_ANONYMOUS";
private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
- private static BundleContext bundleContext;
+ private BundleContext bundleContext;
+ private static SecureRapActivator activator = null;
public void start(BundleContext bundleContext) throws Exception {
- SecureRapActivator.bundleContext = bundleContext;
+ activator = this;
+ this.bundleContext = bundleContext;
}
public void stop(BundleContext context) throws Exception {
+ bundleContext = null;
+ activator = null;
}
- static ILoginContext createLoginContext() {
- URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE);
- return LoginContextFactory.createContext(CONTEXT_SPRING, configUrl);
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public static SecureRapActivator getActivator() {
+ return activator;
+ }
+
+ static ILoginContext createLoginContext(String contextName) {
+ URL configUrl = getActivator().getBundleContext().getBundle()
+ .getEntry(JAAS_CONFIG_FILE);
+ return LoginContextFactory.createContext(contextName, configUrl);
}
}
+++ /dev/null
-package org.argeo.security.ui.rap;
-
-import org.eclipse.ui.IPerspectiveDescriptor;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-public class SecureWorkbenchAdvisor extends WorkbenchAdvisor {
- public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
- private String initialPerspective = System.getProperty(
- INITIAL_PERSPECTIVE_PROPERTY, null);
-
- public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
- IWorkbenchWindowConfigurer configurer) {
- return new SecureWorkbenchWindowAdvisor(configurer);
- }
-
- public String getInitialWindowPerspectiveId() {
- if (initialPerspective != null) {
- // check whether this user can see the declared perspective
- // (typically the perspective won't be listed if this user doesn't
- // have the right to see it)
- IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
- .getPerspectiveRegistry()
- .findPerspectiveWithId(initialPerspective);
- if(pd==null)
- return null;
- }
- return initialPerspective;
- }
-}
+++ /dev/null
-package org.argeo.security.ui.rap;
-
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.ui.IWorkbenchWindow;
-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;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-public class SecureWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
-
- public SecureWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
- super(configurer);
- }
-
- public ActionBarAdvisor createActionBarAdvisor(
- IActionBarConfigurer configurer) {
- return new SecureActionBarAdvisor(configurer, true);
- }
-
- public void preWindowOpen() {
- IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
- configurer.setInitialSize(new Point(1200, 900));
- configurer.setShowCoolBar(true);
- configurer.setShowMenuBar(true);
- configurer.setShowStatusLine(false);
-
- configurer.setShowPerspectiveBar(true);
- configurer.setTitle("Argeo Secure UI"); //$NON-NLS-1$
- }
-
- @Override
- public void postWindowOpen() {
- String defaultPerspective = getWindowConfigurer()
- .getWorkbenchConfigurer().getWorkbench()
- .getPerspectiveRegistry().getDefaultPerspective();
- if (defaultPerspective == null) {
- IWorkbenchWindow window = getWindowConfigurer().getWindow();
- if (window == null)
- return;
-
- IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
- .create(window);
- openPerspectiveDialogAction.run();
- }
- }
-
-}
--- /dev/null
+package org.argeo.security.ui.rap.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+
+/** Default action of the user menu */
+public class UserMenu extends AbstractHandler {
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ return null;
+ }
+
+}
class="org.argeo.security.ui.dialogs.DefaultLoginDialog">
</callbackHandler>
</extension>
- <extension
- point="org.eclipse.ui.commands">
- <command
- defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
- id="org.argeo.security.ui.openChangePasswordDialog"
- name="OpenChangePasswordDialog">
- </command>
- </extension>
- <extension
- point="org.eclipse.ui.menus">
- <menuContribution
- locationURI="menu:file?after=additions">
- <command
- commandId="org.argeo.security.ui.openChangePasswordDialog"
- icon="icons/password.gif"
- label="Change password"
- style="push"
- tooltip="Change password">
- </command>
- </menuContribution>
- </extension>
- <extension
- point="org.eclipse.ui.services">
+ <extension point="org.eclipse.ui.services">
<sourceProvider
provider="org.argeo.security.ui.RolesSourceProvider">
<variable
</variable>
</sourceProvider>
</extension>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ class="org.argeo.security.ui.views.UserProfile"
+ icon="icons/user.gif"
+ id="org.argeo.security.ui.userProfile"
+ name="Profile"
+ restorable="true">
+ </view>
+ </extension>
+ <extension
+ point="org.eclipse.ui.perspectives">
+ <perspective
+ class="org.argeo.security.ui.UserHomePerspective"
+ icon="icons/home.gif"
+ id="org.argeo.security.ui.userHomePerspective"
+ name="Home">
+ </perspective>
+ </extension>
</plugin>
--- /dev/null
+package org.argeo.security.ui;
+
+import org.argeo.security.ui.views.UserProfile;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class UserHomePerspective implements IPerspectiveFactory {
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(true);
+ layout.setFixed(false);
+
+ IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
+ 0.65f, editorArea);
+ left.addView(UserProfile.ID);
+// left.addView(RolesView.ID);
+ }
+
+}
--- /dev/null
+package org.argeo.security.ui.views;
+
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.argeo.security.ui.internal.CurrentUser;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.part.ViewPart;
+
+public class UserProfile extends ViewPart {
+ public static String ID = SecurityUiPlugin.PLUGIN_ID + ".userProfile";
+
+ @Override
+ public void createPartControl(Composite parent) {
+ new Label(parent, SWT.NONE).setText(CurrentUser.getUsername());
+ }
+
+ @Override
+ public void setFocus() {
+ }
+
+}
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.core.DefaultSecurityManager;
+import org.apache.jackrabbit.core.security.AnonymousPrincipal;
import org.apache.jackrabbit.core.security.SecurityConstants;
import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
import org.argeo.ArgeoException;
if (log.isTraceEnabled())
log.trace(subject);
- // skip Jackrabbit system user
+ // skip anonymous user (no rights)
+ if (!subject.getPrincipals(AnonymousPrincipal.class).isEmpty())
+ return super.getUserID(subject, workspaceName);
+ // skip Jackrabbit system user (all rights)
if (!subject.getPrincipals(ArgeoSystemPrincipal.class).isEmpty())
return super.getUserID(subject, workspaceName);