import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.rwt.RWT;
import org.eclipse.rwt.lifecycle.IEntryPoint;
-import org.eclipse.rwt.service.SessionStoreEvent;
-import org.eclipse.rwt.service.SessionStoreListener;
-import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
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;
-public class SecureEntryPoint implements IEntryPoint, SessionStoreListener {
+/**
+ * RAP entry point with login capabilities. On 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);
- @SuppressWarnings("unchecked")
+ /**
+ * 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() {
- // 15 mins session timeout
- RWT.getRequest().getSession().setMaxInactiveInterval(15 * 60);
+ // 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("THREAD=" + Thread.currentThread().getId()
+ ", sessionStore=" + RWT.getSessionStore().getId());
- final ILoginContext loginContext = SecureRapActivator
- .createLoginContext();
Integer returnCode = null;
+
+ // create display
Display display = PlatformUI.createDisplay();
+ // log in
+ final ILoginContext loginContext = SecureRapActivator
+ .createLoginContext();
Subject subject = null;
- try {
- loginContext.login();
- subject = loginContext.getSubject();
- } catch (LoginException e) {
- log.error("Error when logging in.", e);
- MessageDialog.openInformation(display.getActiveShell(),
- "Login failed", "Login failed");
- display.dispose();
- RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ tryLogin: while (subject == null) {
try {
- Thread.sleep(2000);
- } catch (InterruptedException e1) {
- // silent
+ loginContext.login();
+ subject = loginContext.getSubject();
+ } catch (LoginException e) {
+ if (e.getCause() != null) {
+ Throwable firstCause = e.getCause();
+ // log.error("Cause", firstCause);
+ if (firstCause instanceof LoginException
+ && firstCause.getCause() != null) {
+ Throwable secondCause = firstCause.getCause();
+ if (secondCause instanceof BadCredentialsException) {
+ MessageDialog.openInformation(
+ display.getActiveShell(),
+ "Bad Credentials",
+ "Your credentials are incorrect");
+ // retry login
+ continue tryLogin;
+ } else if (secondCause instanceof ThreadDeath) {
+ // rethrow thread death caused by dialog UI timeout
+ throw (ThreadDeath) secondCause;
+ }
+
+ } else if (firstCause instanceof ThreadDeath) {
+ throw (ThreadDeath) firstCause;
+ }
+ }
+ // this was not just bad credentials returns
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ display.dispose();
+ return -1;
}
- // throw new RuntimeException("Login failed", e);
- return -1;
}
// identify after successful login
if (log.isDebugEnabled())
- log.debug("subject=" + subject);
+ log.debug("Authenticated " + subject);
final String username = subject.getPrincipals().iterator().next()
.getName();
- if (log.isDebugEnabled())
- log.debug(username + " logged in");
+
+ // 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);
// invalidate session
- RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ //RWT.getRequest().getSession().setMaxInactiveInterval(1);
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
}
});
+ //
+ // RUN THE WORKBENCH
+ //
try {
returnCode = (Integer) Subject.doAs(subject, getRunAction(display));
- loginContext.logout();
- return processReturnCode(returnCode);
- } catch (Exception e) {
- if (subject != null)
- logout(loginContext, username);
- // RWT.getRequest().getSession().setMaxInactiveInterval(1);
- log.error("Unexpected error", e);
- // throw new ArgeoException("Cannot login", e);
+ logout(loginContext, username);
} finally {
display.dispose();
}
- return -1;
+ return processReturnCode(returnCode);
}
- static void logout(ILoginContext secureContext, String username) {
+ protected void logout(ILoginContext secureContext, String username) {
try {
secureContext.logout();
log.info("Logged out " + (username != null ? username : "")
}
}
- // 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");
- // }
-
- static class FailedLogin extends MessageDialog {
-
- public FailedLogin(Shell parentShell, String dialogTitle,
- Image dialogTitleImage, String dialogMessage,
- int dialogImageType, String[] dialogButtonLabels,
- int defaultIndex) {
- super(parentShell, "Failed ", dialogTitleImage, dialogMessage,
- dialogImageType, dialogButtonLabels, defaultIndex);
- // TODO Auto-generated constructor stub
- }
-
- }
-
@SuppressWarnings("rawtypes")
private PrivilegedAction getRunAction(final Display display) {
return new PrivilegedAction() {
};
}
+ /** 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(
};
}
-
- @Override
- public void beforeDestroy(SessionStoreEvent event) {
- if (log.isDebugEnabled())
- log.debug("RWT session " + event.getSessionStore().getId()
- + " about to be destroyed. THREAD="
- + Thread.currentThread().getId());
-
- }
-
}