X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.security.ui.rap%2Fsrc%2Forg%2Fargeo%2Fsecurity%2Fui%2Frap%2FSecureEntryPoint.java;h=6a582f83f75e948dc60b8fb9680e3aa9b49033a4;hb=94114b7d025df8452c96a23554ec96c32e6c459b;hp=503e2746cf1ab36bbf5789fecf87372f3ad9f1d4;hpb=559786a622e24c7d213960a7873e105db82a03ab;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java b/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java index 503e2746c..6a582f83f 100644 --- a/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java +++ b/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java @@ -15,28 +15,33 @@ */ package org.argeo.security.ui.rap; +import static org.argeo.cms.auth.AuthConstants.ACCESS_CONTROL_CONTEXT; + +import java.security.AccessControlContext; +import java.security.AccessController; import java.security.PrivilegedAction; import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; +import javax.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.workbench.ErrorFeedback; -import org.argeo.security.ui.dialogs.DefaultLoginDialog; -import org.eclipse.equinox.security.auth.ILoginContext; +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.widgets.auth.DefaultLoginDialog; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; +import org.argeo.util.LocaleUtils; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.application.EntryPoint; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; -import org.osgi.framework.BundleContext; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; /** * RAP entry point with login capabilities. Once the user has been @@ -46,12 +51,6 @@ import org.springframework.security.core.context.SecurityContextHolder; public class SecureEntryPoint implements EntryPoint { private final static Log log = LogFactory.getLog(SecureEntryPoint.class); - /** - * From org.springframework.security.context. - * HttpSessionContextIntegrationFilter - */ - protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT"; - /** * How many seconds to wait before invalidating the session if the user has * not yet logged in. @@ -72,80 +71,71 @@ public class SecureEntryPoint implements EntryPoint { // around too long RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout); - // Try to load security context thanks to the session processing filter - HttpServletRequest httpRequest = RWT.getRequest(); - HttpSession httpSession = httpRequest.getSession(); - Object contextFromSessionObject = httpSession - .getAttribute(SPRING_SECURITY_CONTEXT_KEY); - if (contextFromSessionObject != null) - SecurityContextHolder - .setContext((SecurityContext) contextFromSessionObject); - - // if (log.isDebugEnabled()) - // log.debug("THREAD=" + Thread.currentThread().getId() - // + ", sessionStore=" + RWT.getSessionStore().getId() - // + ", remote user=" + httpRequest.getRemoteUser()); - - // create display final Display display = PlatformUI.createDisplay(); - Subject subject = new Subject(); - - // log in - BundleContext bc = SecureRapActivator.getActivator().getBundleContext(); - final LoginModule loginModule = bc.getService(bc - .getServiceReference(LoginModule.class)); - loginModule.initialize(subject, - new DefaultLoginDialog(display.getActiveShell()), null, null); - try { - if (!loginModule.login()) { - throw new ArgeoException("Login failed"); + + // load context from session + HttpServletRequest httpRequest = RWT.getRequest(); + final HttpSession httpSession = httpRequest.getSession(); + AccessControlContext acc = (AccessControlContext) httpSession + .getAttribute(AuthConstants.ACCESS_CONTROL_CONTEXT); + + final Subject subject; + if (acc != null + && Subject.getSubject(acc).getPrincipals(X500Principal.class) + .size() == 1) { + subject = Subject.getSubject(acc); + } else { + subject = new Subject(); + + final LoginContext loginContext; + try { + CallbackHandler callbackHandler = new DefaultLoginDialog( + display.getActiveShell()); + loginContext = new LoginContext( + AuthConstants.LOGIN_CONTEXT_USER, subject, + callbackHandler); + } catch (LoginException e1) { + throw new ArgeoException("Cannot initialize login context", e1); } - } catch (LoginException e1) { - throw new ArgeoException("Login failed", e1); - } - // final ILoginContext loginContext = SecureRapActivator - // .createLoginContext(SecureRapActivator.CONTEXT_SPRING); - // tryLogin: while (subject == null && !display.isDisposed()) { - // try { - // loginContext.login(); - // subject = loginContext.getSubject(); - // - // // add security context to session - // if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null) - // httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, - // SecurityContextHolder.getContext()); - // // add thread locale to RWT session - // log.info("Locale " + LocaleUtils.threadLocale.get()); - // RWT.setLocale(LocaleUtils.threadLocale.get()); - // - // // 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); - // } catch (LoginException e) { - // BadCredentialsException bce = wasCausedByBadCredentials(e); - // if (bce != null) { - // MessageDialog.openInformation(display.getActiveShell(), - // "Bad Credentials", bce.getMessage()); - // // retry login - // continue tryLogin; - // } - // return processLoginDeath(display, e); - // } - // } - - final String username = subject.getPrincipals().iterator().next() - .getName(); + tryLogin: while (subject.getPrincipals(X500Principal.class).size() == 0) { + try { + loginContext.login(); + if (subject.getPrincipals(X500Principal.class).size() == 0) + throw new ArgeoException("Login succeeded but no auth");// fatal + + // add thread locale to RWT session + if (log.isTraceEnabled()) + log.trace("Locale " + LocaleUtils.threadLocale.get()); + RWT.setLocale(LocaleUtils.threadLocale.get()); + + // once the user is logged in, longer session timeout + RWT.getRequest().getSession() + .setMaxInactiveInterval(sessionTimeout); + + if (log.isDebugEnabled()) + log.debug("Authenticated " + subject); + } catch (FailedLoginException e) { + MessageDialog.openInformation(display.getActiveShell(), + "Bad Credentials", e.getMessage()); + // retry login + continue tryLogin; + } catch (LoginException e) { + return processLoginDeath(display, e); + } + } + } + final String username = subject.getPrincipals(X500Principal.class) + .iterator().next().getName(); // Logout callback when the display is disposed display.disposeExec(new Runnable() { public void run() { - log.debug("Display disposed"); - // logout(loginContext, username); + if (log.isTraceEnabled()) + log.trace("Display disposed"); try { - loginModule.logout(); + LoginContext loginContext = new LoginContext( + AuthConstants.LOGIN_CONTEXT_USER, subject); + loginContext.logout(); } catch (LoginException e) { log.error("Error when logging out", e); } @@ -159,13 +149,19 @@ public class SecureEntryPoint implements EntryPoint { try { returnCode = Subject.doAs(subject, new PrivilegedAction() { public Integer run() { + // add security context to session + httpSession.setAttribute(ACCESS_CONTROL_CONTEXT, + AccessController.getContext()); + + // start workbench RapWorkbenchAdvisor workbenchAdvisor = createRapWorkbenchAdvisor(username); int result = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); return new Integer(result); } }); - // logout(loginContext, username); + // Explicit exit from workbench + fullLogout(subject, username); } finally { display.dispose(); } @@ -192,17 +188,6 @@ public class SecureEntryPoint implements EntryPoint { } - /** Recursively look for {@link BadCredentialsException} in the root causes. */ - private BadCredentialsException wasCausedByBadCredentials(Throwable t) { - if (t instanceof BadCredentialsException) - return (BadCredentialsException) t; - - if (t.getCause() != null) - return wasCausedByBadCredentials(t.getCause()); - else - return null; - } - /** * If there is a {@link ThreadDeath} in the root causes, rethrow it * (important for RAP cleaning mechanism) @@ -217,18 +202,19 @@ public class SecureEntryPoint implements EntryPoint { return null; } - protected void logout(ILoginContext secureContext, String username) { + private void fullLogout(Subject subject, String username) { try { + LoginContext loginContext = new LoginContext( + AuthConstants.LOGIN_CONTEXT_USER, subject); + loginContext.logout(); HttpServletRequest httpRequest = RWT.getRequest(); HttpSession httpSession = httpRequest.getSession(); - httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null); + httpSession.setAttribute(ACCESS_CONTROL_CONTEXT, null); RWT.getRequest().getSession().setMaxInactiveInterval(1); - SecurityContextHolder.clearContext(); - secureContext.logout(); log.info("Logged out " + (username != null ? username : "") + " (THREAD=" + Thread.currentThread().getId() + ")"); } catch (LoginException e) { - log.error("Erorr when logging out", e); + log.error("Error when logging out", e); } } }