X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fauth%2FAbstractLoginModule.java;h=89312a3dca2d1c7c95ee0df20875c6cd42e39a0b;hb=97c5b44699e82757f57ad19b74f9d9d362aee2d0;hp=36d5e0fef263616b781d28d60c1ad55df224e221;hpb=6ddb7b6b224a00344a182761e42b2241a721224f;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java index 36d5e0fef..89312a3dc 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java @@ -23,19 +23,31 @@ import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; +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.cms.internal.kernel.Activator; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.widgets.Display; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; /** Login module which caches one subject per thread. */ public abstract class AbstractLoginModule implements LoginModule { - // private final static Log log = LogFactory - // .getLog(AbstractSpringLoginModule.class); + /** + * From org.springframework.security.context. + * HttpSessionContextIntegrationFilter + */ + private final static String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT"; + + private final static Log log = LogFactory.getLog(AbstractLoginModule.class); private CallbackHandler callbackHandler; private Subject subject; @@ -62,13 +74,36 @@ public abstract class AbstractLoginModule implements LoginModule { @Override public boolean login() throws LoginException { try { - // thread already logged in Authentication currentAuth = SecurityContextHolder.getContext() .getAuthentication(); + + if (currentAuth == null) { + // Pre-auth + // TODO Do it at Spring Security level? + try { + // try to load authentication from session + HttpServletRequest httpRequest = RWT.getRequest(); + HttpSession httpSession = httpRequest.getSession(); + // log.debug(httpSession.getId()); + Object contextFromSessionObject = httpSession + .getAttribute(SPRING_SECURITY_CONTEXT_KEY); + if (contextFromSessionObject != null) { + currentAuth = (Authentication) contextFromSessionObject; + SecurityContextHolder.getContext().setAuthentication( + currentAuth); + } + } catch (Exception e) { + if (log.isTraceEnabled()) + log.trace("Could not get session", e); + // silent + } + } + + // thread already logged in if (currentAuth != null) { if (subject.getPrincipals(Authentication.class).size() == 0) { - throw new LoginException( - "Security context set but not Authentication principal"); + // throw new LoginException( + // "Security context set but not Authentication principal"); } else { Authentication principal = subject .getPrincipals(Authentication.class).iterator() @@ -80,13 +115,28 @@ public abstract class AbstractLoginModule implements LoginModule { return true; } - if (callbackHandler == null) - throw new LoginException("No callback handler available"); + // if (callbackHandler == null) + // throw new LoginException("No callback handler available"); authentication = processLogin(callbackHandler); if (authentication != null) { - SecurityContextHolder.getContext().setAuthentication( - authentication); + // + // SET THE AUTHENTICATION + // + SecurityContext securityContext = SecurityContextHolder + .getContext(); + securityContext.setAuthentication(authentication); + try { + HttpServletRequest httpRequest = RWT.getRequest(); + HttpSession httpSession = httpRequest.getSession(); + if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null) + httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, + authentication); + } catch (Exception e) { + if (log.isTraceEnabled()) + log.trace("Could not add security context to session", + e); + } return true; } else { throw new LoginException("No authentication returned"); @@ -109,6 +159,16 @@ public abstract class AbstractLoginModule implements LoginModule { @Override public boolean logout() throws LoginException { SecurityContextHolder.getContext().setAuthentication(null); + if (Display.getCurrent() != null) { + HttpServletRequest httpRequest = RWT.getRequest(); + if (httpRequest != null) { + HttpSession httpSession = httpRequest.getSession(); + if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) != null) + httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null); + // expire session + httpSession.setMaxInactiveInterval(0); + } + } return true; } @@ -139,12 +199,6 @@ public abstract class AbstractLoginModule implements LoginModule { return bc.getService(authenticationManager); } - // protected UserAdmin getUserAdmin(BundleContextCallback - // bundleContextCallback) { - // BundleContext bc = bundleContextCallback.getBundleContext(); - // return bc.getService(bc.getServiceReference(UserAdmin.class)); - // } - protected Subject getSubject() { return subject; }