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
.eclipse
.equinox
.security
.auth
.ILoginContext
;
12 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
13 import org
.eclipse
.rwt
.RWT
;
14 import org
.eclipse
.rwt
.lifecycle
.IEntryPoint
;
15 import org
.eclipse
.swt
.widgets
.Display
;
16 import org
.eclipse
.ui
.PlatformUI
;
17 import org
.eclipse
.ui
.application
.IWorkbenchWindowConfigurer
;
18 import org
.eclipse
.ui
.application
.WorkbenchAdvisor
;
19 import org
.eclipse
.ui
.application
.WorkbenchWindowAdvisor
;
20 import org
.springframework
.security
.BadCredentialsException
;
23 * RAP entry point with login capabilities. On the user has been authenticated,
24 * the workbench is run as a privileged action by the related subject.
26 public class SecureEntryPoint
implements IEntryPoint
{
27 private final static Log log
= LogFactory
.getLog(SecureEntryPoint
.class);
30 * How many seconds to wait before invalidating the session if the user has
33 private Integer loginTimeout
= 1 * 60;
34 private Integer sessionTimeout
= 15 * 60;
37 public int createUI() {
38 // Short login timeout so that the modal dialog login doesn't hang
40 RWT
.getRequest().getSession().setMaxInactiveInterval(loginTimeout
);
42 if (log
.isDebugEnabled())
43 log
.debug("THREAD=" + Thread
.currentThread().getId()
44 + ", sessionStore=" + RWT
.getSessionStore().getId());
46 Integer returnCode
= null;
49 Display display
= PlatformUI
.createDisplay();
52 final ILoginContext loginContext
= SecureRapActivator
53 .createLoginContext();
54 Subject subject
= null;
55 tryLogin
: while (subject
== null && !display
.isDisposed()) {
58 subject
= loginContext
.getSubject();
59 } catch (LoginException e
) {
60 BadCredentialsException bce
= wasCausedByBadCredentials(e
);
62 MessageDialog
.openInformation(display
.getActiveShell(),
63 "Bad Credentials", bce
.getMessage());
69 ThreadDeath td
= wasCausedByThreadDeath(e
);
75 if (!display
.isDisposed()) {
76 org
.argeo
.eclipse
.ui
.Error
.show(
77 "Unexpected exception during authentication", e
);
78 // this was not just bad credentials or death thread
79 RWT
.getRequest().getSession().setMaxInactiveInterval(1);
83 throw new ArgeoException(
84 "Unexpected exception during authentication", e
);
89 // identify after successful login
90 if (log
.isDebugEnabled())
91 log
.debug("Authenticated " + subject
);
92 final String username
= subject
.getPrincipals().iterator().next()
95 // Once the user is logged in, she can have a longer session timeout
96 RWT
.getRequest().getSession().setMaxInactiveInterval(sessionTimeout
);
98 // Logout callback when the display is disposed
99 display
.disposeExec(new Runnable() {
101 log
.debug("Display disposed");
102 logout(loginContext
, username
);
110 returnCode
= (Integer
) Subject
.doAs(subject
, getRunAction(display
));
111 logout(loginContext
, username
);
115 return processReturnCode(returnCode
);
118 /** Recursively look for {@link BadCredentialsException} in the root causes. */
119 private BadCredentialsException
wasCausedByBadCredentials(Throwable t
) {
120 if (t
instanceof BadCredentialsException
)
121 return (BadCredentialsException
) t
;
123 if (t
.getCause() != null)
124 return wasCausedByBadCredentials(t
.getCause());
130 * If there is a {@link ThreadDeath} in the root causes, rethrow it
131 * (important for RAP cleaning mechanism)
133 protected ThreadDeath
wasCausedByThreadDeath(Throwable t
) {
134 if (t
instanceof ThreadDeath
)
135 return (ThreadDeath
) t
;
137 if (t
.getCause() != null)
138 return wasCausedByThreadDeath(t
.getCause());
143 protected void logout(ILoginContext secureContext
, String username
) {
145 secureContext
.logout();
146 log
.info("Logged out " + (username
!= null ? username
: "")
147 + " (THREAD=" + Thread
.currentThread().getId() + ")");
148 } catch (LoginException e
) {
149 log
.error("Erorr when logging out", e
);
153 @SuppressWarnings("rawtypes")
154 private PrivilegedAction
getRunAction(final Display display
) {
155 return new PrivilegedAction() {
156 public Object
run() {
157 int result
= createAndRunWorkbench(display
);
158 return new Integer(result
);
163 /** To be overridden */
164 protected Integer
createAndRunWorkbench(Display display
) {
165 return PlatformUI
.createAndRunWorkbench(display
,
166 createWorkbenchAdvisor());
169 /** To be overridden */
170 protected Integer
processReturnCode(Integer returnCode
) {
174 /** To be overridden */
175 protected WorkbenchAdvisor
createWorkbenchAdvisor() {
176 return new SecureWorkbenchAdvisor() {
177 public WorkbenchWindowAdvisor
createWorkbenchWindowAdvisor(
178 IWorkbenchWindowConfigurer configurer
) {
179 return new RapSecureWorkbenchWindowAdvisor(configurer
);