1 package org
.argeo
.security
.ui
.rap
;
3 import java
.security
.PrivilegedAction
;
5 import javax
.security
.auth
.Subject
;
6 import javax
.security
.auth
.login
.LoginException
;
8 import org
.apache
.commons
.logging
.Log
;
9 import org
.apache
.commons
.logging
.LogFactory
;
10 import org
.argeo
.ArgeoException
;
11 import org
.argeo
.eclipse
.ui
.ErrorFeedback
;
12 import org
.eclipse
.equinox
.security
.auth
.ILoginContext
;
13 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
14 import org
.eclipse
.rwt
.RWT
;
15 import org
.eclipse
.rwt
.lifecycle
.IEntryPoint
;
16 import org
.eclipse
.swt
.widgets
.Display
;
17 import org
.eclipse
.ui
.PlatformUI
;
18 import org
.springframework
.security
.BadCredentialsException
;
21 * RAP entry point with login capabilities. Once the user has been
22 * authenticated, the workbench is run as a privileged action by the related
25 public class SecureEntryPoint
implements IEntryPoint
{
26 private final static Log log
= LogFactory
.getLog(SecureEntryPoint
.class);
29 * How many seconds to wait before invalidating the session if the user has
32 private Integer loginTimeout
= 1 * 60;
33 // TODO make it configurable
34 /** Default session timeout is 8 hours (European working day length) */
35 private Integer sessionTimeout
= 8 * 60 * 60;
38 public int createUI() {
39 // Short login timeout so that the modal dialog login doesn't hang
41 RWT
.getRequest().getSession().setMaxInactiveInterval(loginTimeout
);
43 if (log
.isDebugEnabled())
44 log
.debug("THREAD=" + Thread
.currentThread().getId()
45 + ", sessionStore=" + RWT
.getSessionStore().getId());
48 final Display display
= PlatformUI
.createDisplay();
51 final ILoginContext loginContext
= SecureRapActivator
52 .createLoginContext(SecureRapActivator
.CONTEXT_SPRING
);
53 Subject subject
= null;
54 tryLogin
: while (subject
== null && !display
.isDisposed()) {
57 subject
= loginContext
.getSubject();
58 } catch (LoginException e
) {
59 BadCredentialsException bce
= wasCausedByBadCredentials(e
);
61 MessageDialog
.openInformation(display
.getActiveShell(),
62 "Bad Credentials", bce
.getMessage());
66 return processLoginDeath(display
, e
);
70 // Once the user is logged in, she can have a longer session timeout
71 RWT
.getRequest().getSession().setMaxInactiveInterval(sessionTimeout
);
72 if (log
.isDebugEnabled())
73 log
.debug("Authenticated " + subject
);
75 final String username
= subject
.getPrincipals().iterator().next()
77 // Logout callback when the display is disposed
78 display
.disposeExec(new Runnable() {
80 log
.debug("Display disposed");
81 logout(loginContext
, username
);
88 Integer returnCode
= null;
90 returnCode
= Subject
.doAs(subject
, new PrivilegedAction
<Integer
>() {
91 public Integer
run() {
92 RapWorkbenchAdvisor workbenchAdvisor
= new RapWorkbenchAdvisor(
94 int result
= PlatformUI
.createAndRunWorkbench(display
,
96 return new Integer(result
);
99 logout(loginContext
, username
);
106 private Integer
processLoginDeath(Display display
, LoginException e
) {
107 // check thread death
108 ThreadDeath td
= wasCausedByThreadDeath(e
);
113 if (!display
.isDisposed()) {
114 ErrorFeedback
.show("Unexpected exception during authentication", e
);
115 // this was not just bad credentials or death thread
116 RWT
.getRequest().getSession().setMaxInactiveInterval(1);
120 throw new ArgeoException(
121 "Unexpected exception during authentication", e
);
126 /** Recursively look for {@link BadCredentialsException} in the root causes. */
127 private BadCredentialsException
wasCausedByBadCredentials(Throwable t
) {
128 if (t
instanceof BadCredentialsException
)
129 return (BadCredentialsException
) t
;
131 if (t
.getCause() != null)
132 return wasCausedByBadCredentials(t
.getCause());
138 * If there is a {@link ThreadDeath} in the root causes, rethrow it
139 * (important for RAP cleaning mechanism)
141 protected ThreadDeath
wasCausedByThreadDeath(Throwable t
) {
142 if (t
instanceof ThreadDeath
)
143 return (ThreadDeath
) t
;
145 if (t
.getCause() != null)
146 return wasCausedByThreadDeath(t
.getCause());
151 protected void logout(ILoginContext secureContext
, String username
) {
153 secureContext
.logout();
154 log
.info("Logged out " + (username
!= null ? username
: "")
155 + " (THREAD=" + Thread
.currentThread().getId() + ")");
156 } catch (LoginException e
) {
157 log
.error("Erorr when logging out", e
);