From 559786a622e24c7d213960a7873e105db82a03ab Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Wed, 28 Jan 2015 11:04:23 +0000 Subject: [PATCH] Centralise login in Kernel Disable Equinox security git-svn-id: https://svn.argeo.org/commons/trunk@7714 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- demo/argeo_node_rap.properties | 3 +- dep/org.argeo.dep.cms/pom.xml | 2 +- org.argeo.cms/bnd.bnd | 1 + org.argeo.cms/pom.xml | 2 +- .../org/argeo/cms/internal/kernel/Kernel.java | 26 +- .../cms/internal/kernel/NodeSecurity.java | 25 ++ .../internal/kernel/SpringLoginModule.java | 242 ++++++++++++++++++ org.argeo.eclipse.ui.workbench/bnd.bnd | 20 +- .../security/core/ThreadedLoginModule.java | 50 ++++ .../JackrabbitUserAdminService.java | 6 +- org.argeo.security.ui.rap/pom.xml | 29 +-- .../security/ui/rap/SecureEntryPoint.java | 99 ++++--- pom.xml | 8 +- 13 files changed, 430 insertions(+), 83 deletions(-) create mode 100644 org.argeo.cms/src/org/argeo/cms/internal/kernel/SpringLoginModule.java create mode 100644 org.argeo.security.core/src/org/argeo/security/core/ThreadedLoginModule.java diff --git a/demo/argeo_node_rap.properties b/demo/argeo_node_rap.properties index 3410259d2..7c3b662b2 100644 --- a/demo/argeo_node_rap.properties +++ b/demo/argeo_node_rap.properties @@ -14,10 +14,11 @@ org.eclipse.equinox.http.registry,\ org.osgi.service.http.port=7070 org.eclipse.equinox.http.jetty.log.stderr.threshold=info +org.eclipse.equinox.http.jetty.context.path=/ui argeo.i18n.availableLocales=en,fr,de,ru,ar eclipse.registry.MultiLanguage=true log4j.configuration=file:../../log4j.properties osgi.console.enable.builtin=true -org.eclipse.rap.workbenchAutostart=false \ No newline at end of file +org.eclipse.rap.workbenchAutostart=true \ No newline at end of file diff --git a/dep/org.argeo.dep.cms/pom.xml b/dep/org.argeo.dep.cms/pom.xml index 28ccd858f..9e5d3183d 100644 --- a/dep/org.argeo.dep.cms/pom.xml +++ b/dep/org.argeo.dep.cms/pom.xml @@ -9,7 +9,7 @@ .. org.argeo.dep.cms - CMS Dependencies + Commons CMS Dependencies diff --git a/org.argeo.cms/bnd.bnd b/org.argeo.cms/bnd.bnd index 825c5957f..477223485 100644 --- a/org.argeo.cms/bnd.bnd +++ b/org.argeo.cms/bnd.bnd @@ -12,4 +12,5 @@ org.h2;resolution:=optional,\ org.springframework.context,\ org.apache.jackrabbit.api,\ org.apache.jackrabbit.commons,\ +org.eclipse.rap.rwt.osgi,\ * diff --git a/org.argeo.cms/pom.xml b/org.argeo.cms/pom.xml index c01e0161d..498f04250 100644 --- a/org.argeo.cms/pom.xml +++ b/org.argeo.cms/pom.xml @@ -8,7 +8,7 @@ .. org.argeo.cms - Argeo Content Management System + Commons Content Management System jar diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java index ef2403b44..4b893f13d 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java @@ -30,6 +30,7 @@ import org.springframework.security.core.context.SecurityContextHolder; @SuppressWarnings("restriction") final class Kernel { private final static Log log = LogFactory.getLog(Kernel.class); + private static final String PROP_WORKBENCH_AUTOSTART = "org.eclipse.rap.workbenchAutostart"; private final BundleContext bundleContext; @@ -55,7 +56,6 @@ final class Kernel { repositoryFactory = new OsgiJackrabbitRepositoryFactory(); nodeSecurity = new NodeSecurity(bundleContext, node); nodeHttp = new NodeHttp(bundleContext, node, nodeSecurity); - WorkbenchApplicationConfiguration wac = new WorkbenchApplicationConfiguration(); // Publish services to OSGi nodeSecurity.publish(); @@ -63,7 +63,12 @@ final class Kernel { bundleContext.registerService(RepositoryFactory.class, repositoryFactory, null); nodeHttp.publish(); - registerWorkbench(wac); + + if ("false".equals(bundleContext + .getProperty(PROP_WORKBENCH_AUTOSTART))) { + WorkbenchApplicationConfiguration wac = new WorkbenchApplicationConfiguration(); + registerWorkbench(wac); + } } catch (Exception e) { log.error("Cannot initialize Argeo CMS", e); throw new ArgeoException("Cannot initialize", e); @@ -77,7 +82,7 @@ final class Kernel { void destroy() { long begin = System.currentTimeMillis(); - + // OSGi workbenchReg.unregister(); @@ -90,12 +95,15 @@ final class Kernel { + (duration % 1000) + "s ##"); } - private ServiceRegistration registerWorkbench( - WorkbenchApplicationConfiguration wac) { - Hashtable props = new Hashtable(); - props.put(ApplicationLauncher.PROPERTY_CONTEXT_NAME, "ui"); - return bundleContext.registerService(ApplicationConfiguration.class, - wac, props); + private void registerWorkbench(final WorkbenchApplicationConfiguration wac) { + new Thread("Worbench Launcher") { + public void run() { + Hashtable props = new Hashtable(); + props.put(ApplicationLauncher.PROPERTY_CONTEXT_NAME, "ui"); + workbenchReg = bundleContext.registerService( + ApplicationConfiguration.class, wac, props); + } + }.start(); } private void directorsCut() { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java index 7c176ea89..6ad8fb15c 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java @@ -1,6 +1,7 @@ package org.argeo.cms.internal.kernel; import javax.jcr.RepositoryException; +import javax.security.auth.spi.LoginModule; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -8,8 +9,11 @@ import org.argeo.cms.CmsException; import org.argeo.security.UserAdminService; import org.argeo.security.core.InternalAuthentication; import org.argeo.security.core.InternalAuthenticationProvider; +import org.argeo.security.core.ThreadedLoginModule; import org.argeo.security.jcr.SimpleJcrSecurityModel; import org.argeo.security.jcr.jackrabbit.JackrabbitUserAdminService; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.widgets.Display; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.springframework.security.authentication.AnonymousAuthenticationProvider; @@ -29,10 +33,12 @@ class NodeSecurity implements AuthenticationManager { private final InternalAuthenticationProvider internalAuth; private final AnonymousAuthenticationProvider anonymousAuth; private final JackrabbitUserAdminService jackrabbitUserAdmin; + private Login loginModule; private ServiceRegistration authenticationManagerReg; private ServiceRegistration userAdminReg; private ServiceRegistration userDetailsManagerReg; + private ServiceRegistration loginModuleReg; public NodeSecurity(BundleContext bundleContext, JackrabbitNode node) throws RepositoryException { @@ -49,6 +55,7 @@ class NodeSecurity implements AuthenticationManager { jackrabbitUserAdmin.setSecurityModel(new SimpleJcrSecurityModel()); jackrabbitUserAdmin.init(); + loginModule = new Login(); } public void publish() { @@ -61,6 +68,9 @@ class NodeSecurity implements AuthenticationManager { // userAdminReg = // bundleContext.registerService(UserDetailsService.class, // jackrabbitUserAdmin, null); + + loginModuleReg = bundleContext.registerService(LoginModule.class, + loginModule, null); } void destroy() { @@ -72,6 +82,7 @@ class NodeSecurity implements AuthenticationManager { userDetailsManagerReg.unregister(); userAdminReg.unregister(); authenticationManagerReg.unregister(); + loginModuleReg.unregister(); } @Override @@ -88,4 +99,18 @@ class NodeSecurity implements AuthenticationManager { throw new CmsException("Could not authenticate " + authentication); return auth; } + + private class Login extends ThreadedLoginModule { + + @Override + protected LoginModule createLoginModule() { + SpringLoginModule springLoginModule = new SpringLoginModule(); + springLoginModule.setAuthenticationManager(NodeSecurity.this); + if (Display.getCurrent() != null) { + + } + return springLoginModule; + } + + } } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/SpringLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/SpringLoginModule.java new file mode 100644 index 000000000..d2e5bceb6 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/SpringLoginModule.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.cms.internal.kernel; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.LoginException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.security.NodeAuthenticationToken; +import org.argeo.util.LocaleCallback; +import org.argeo.util.LocaleUtils; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.jaas.SecurityContextLoginModule; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; + +/** Login module which caches one subject per thread. */ +public class SpringLoginModule extends SecurityContextLoginModule { + final static String NODE_REPO_URI = "argeo.node.repo.uri"; + + private final static Log log = LogFactory.getLog(SpringLoginModule.class); + + private AuthenticationManager authenticationManager; + + private CallbackHandler callbackHandler; + + private Subject subject; + + private Long waitBetweenFailedLoginAttempts = 5 * 1000l; + + private Boolean remote = false; + private Boolean anonymous = false; + /** Comma separated list of locales */ + private String availableLocales = ""; + + private String key = null; + private String anonymousRole = "ROLE_ANONYMOUS"; + + public SpringLoginModule() { + + } + + @SuppressWarnings("rawtypes") + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + super.initialize(subject, callbackHandler, sharedState, options); + this.callbackHandler = callbackHandler; + this.subject = subject; + } + + public boolean login() throws LoginException { + try { + // thread already logged in + if (SecurityContextHolder.getContext().getAuthentication() != null) + return super.login(); + + if (remote && anonymous) + throw new LoginException( + "Cannot have a Spring login module which is remote and anonymous"); + + // reset all principals and credentials + if (log.isTraceEnabled()) + log.trace("Resetting all principals and credentials of " + + subject); + subject.getPrincipals().clear(); + subject.getPrivateCredentials().clear(); + subject.getPublicCredentials().clear(); + + Locale selectedLocale = null; + // deals first with public access since it's simple + if (anonymous) { + // multi locale + if (callbackHandler != null && availableLocales != null + && !availableLocales.trim().equals("")) { + LocaleCallback localeCallback = new LocaleCallback( + availableLocales); + callbackHandler.handle(new Callback[] { localeCallback }); + selectedLocale = localeCallback.getSelectedLocale(); + } + + // TODO integrate with JCR? + Object principal = UUID.randomUUID().toString(); + List authorities = Collections + .singletonList(new SimpleGrantedAuthority(anonymousRole)); + AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken( + key, principal, authorities); + Authentication auth = authenticationManager + .authenticate(anonymousToken); + registerAuthentication(auth); + } else { + if (callbackHandler == null) + throw new LoginException("No call back handler available"); + + // ask for username and password + NameCallback nameCallback = new NameCallback("User"); + PasswordCallback passwordCallback = new PasswordCallback( + "Password", false); + final String defaultNodeUrl = System + .getProperty(NODE_REPO_URI, + "http://localhost:7070/org.argeo.jcr.webapp/remoting/node"); + NameCallback urlCallback = new NameCallback("Site URL", + defaultNodeUrl); + LocaleCallback localeCallback = new LocaleCallback( + availableLocales); + + // handle callbacks + if (remote) + callbackHandler.handle(new Callback[] { nameCallback, + passwordCallback, urlCallback, localeCallback }); + else + callbackHandler.handle(new Callback[] { nameCallback, + passwordCallback, localeCallback }); + + selectedLocale = localeCallback.getSelectedLocale(); + + // create credentials + final String username = nameCallback.getName(); + if (username == null || username.trim().equals("")) + return false; + + char[] password = {}; + if (passwordCallback.getPassword() != null) + password = passwordCallback.getPassword(); + + NodeAuthenticationToken credentials; + if (remote) { + String url = urlCallback.getName(); + credentials = new NodeAuthenticationToken(username, + password, url); + } else { + credentials = new NodeAuthenticationToken(username, + password); + } + + Authentication authentication; + try { + authentication = authenticationManager + .authenticate(credentials); + } catch (BadCredentialsException e) { + // wait between failed login attempts + Thread.sleep(waitBetweenFailedLoginAttempts); + throw e; + } + registerAuthentication(authentication); + subject.getPrincipals().add(authentication); + } + + if (selectedLocale != null) + LocaleUtils.threadLocale.set(selectedLocale); + + return super.login(); + } catch (LoginException e) { + throw e; + } catch (ThreadDeath e) { + LoginException le = new LoginException( + "Spring Security login thread died"); + le.initCause(e); + throw le; + } catch (Exception e) { + LoginException le = new LoginException( + "Spring Security login failed"); + le.initCause(e); + throw le; + } + } + + @Override + public boolean logout() throws LoginException { + subject.getPrincipals().clear(); + return super.logout(); + } + + /** + * Register an {@link Authentication} in the security context. + * + * @param authentication + * has to implement {@link Authentication}. + */ + protected void registerAuthentication(Object authentication) { + SecurityContextHolder.getContext().setAuthentication( + (Authentication) authentication); + } + + public void setAuthenticationManager( + AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + + /** Authenticates on a remote node */ + public void setRemote(Boolean remote) { + this.remote = remote; + } + + /** + * Request anonymous authentication (incompatible with remote) + */ + public void setAnonymous(Boolean anonymous) { + this.anonymous = anonymous; + } + + /** Role identifying an anonymous user */ + public void setAnonymousRole(String anonymousRole) { + this.anonymousRole = anonymousRole; + } + + /** System key */ + public void setKey(String key) { + this.key = key; + } + + public void setAvailableLocales(String locales) { + this.availableLocales = locales; + } + +} diff --git a/org.argeo.eclipse.ui.workbench/bnd.bnd b/org.argeo.eclipse.ui.workbench/bnd.bnd index d6c44eeb9..cc95c7652 100644 --- a/org.argeo.eclipse.ui.workbench/bnd.bnd +++ b/org.argeo.eclipse.ui.workbench/bnd.bnd @@ -3,15 +3,15 @@ Bundle-ActivationPolicy: lazy Bundle-Activator: org.argeo.eclipse.ui.workbench.WorkbenchUiPlugin Require-Bundle: org.eclipse.ui;resolution:=optional,\ - org.eclipse.core.runtime,\ - org.eclipse.rap.ui;resolution:=optional,\ - org.eclipse.rap.ui.workbench;resolution:=optional +org.eclipse.core.runtime,\ +org.eclipse.rap.ui;resolution:=optional,\ +org.eclipse.rap.ui.workbench;resolution:=optional Import-Package: org.argeo.eclipse.ui.specific,\ - org.eclipse.swt.widgets;version="[0,1)",\ - org.osgi.framework;version="[1.5,2)",\ - org.osgi.service.packageadmin,\ - org.osgi.util.tracker;version="[1.4,2)",\ - org.springframework.beans.factory,\ - org.springframework.core.io.support,\ - * +org.eclipse.swt.widgets;version="[0,1)",\ +org.osgi.framework;version="[1.5,2)",\ +org.osgi.service.packageadmin,\ +org.osgi.util.tracker;version="[1.4,2)",\ +org.springframework.beans.factory,\ +org.springframework.core.io.support,\ +* diff --git a/org.argeo.security.core/src/org/argeo/security/core/ThreadedLoginModule.java b/org.argeo.security.core/src/org/argeo/security/core/ThreadedLoginModule.java new file mode 100644 index 000000000..8ddac8905 --- /dev/null +++ b/org.argeo.security.core/src/org/argeo/security/core/ThreadedLoginModule.java @@ -0,0 +1,50 @@ +package org.argeo.security.core; + +import java.util.Map; + +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +/** Attach login modules to threads. */ +public abstract class ThreadedLoginModule implements LoginModule { + private ThreadLocal loginModule = new ThreadLocal() { + + @Override + protected LoginModule initialValue() { + return createLoginModule(); + } + + }; + + protected abstract LoginModule createLoginModule(); + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + loginModule.get().initialize(subject, callbackHandler, sharedState, + options); + } + + @Override + public boolean login() throws LoginException { + return loginModule.get().login(); + } + + @Override + public boolean commit() throws LoginException { + return loginModule.get().commit(); + } + + @Override + public boolean abort() throws LoginException { + return loginModule.get().abort(); + } + + @Override + public boolean logout() throws LoginException { + return loginModule.get().logout(); + } + +} diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java b/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java index b648f32c3..fde3d850f 100644 --- a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java +++ b/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java @@ -1,6 +1,7 @@ package org.argeo.security.jcr.jackrabbit; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -301,9 +302,10 @@ public class JackrabbitUserAdminService implements UserAdminService, Authentication authentication) throws AuthenticationException { UsernamePasswordAuthenticationToken siteAuth = (UsernamePasswordAuthenticationToken) authentication; String username = siteAuth.getName(); + char[] password = (char[]) siteAuth.getCredentials(); try { SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(), - siteAuth.getCredentials().toString().toCharArray()); + password); User user = (User) getUserManager().getAuthorizable(username); if (user == null) throw new BadCredentialsException("Bad credentials"); @@ -323,6 +325,8 @@ public class JackrabbitUserAdminService implements UserAdminService, } catch (Exception e) { throw new BadCredentialsException( "Cannot authenticate " + siteAuth, e); + } finally { + Arrays.fill(password, '*'); } try { diff --git a/org.argeo.security.ui.rap/pom.xml b/org.argeo.security.ui.rap/pom.xml index e54f3a44b..1f5cf6f15 100644 --- a/org.argeo.security.ui.rap/pom.xml +++ b/org.argeo.security.ui.rap/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 org.argeo.commons @@ -53,10 +54,10 @@ - - - - + + + + @@ -64,19 +65,15 @@ org.argeo.security.ui 2.1.13-SNAPSHOT - - org.argeo.commons - org.argeo.security.equinox - 2.1.13-SNAPSHOT - + + + + + - + org.argeo.commons org.argeo.eclipse.ui.rap 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 c3754ed05..503e2746c 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 @@ -19,6 +19,7 @@ import java.security.PrivilegedAction; import javax.security.auth.Subject; import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -26,13 +27,13 @@ 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.util.LocaleUtils; +import org.argeo.security.ui.dialogs.DefaultLoginDialog; import org.eclipse.equinox.security.auth.ILoginContext; -import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.rap.rwt.RWT; -import org.eclipse.rap.rwt.application.IEntryPoint; +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; @@ -42,7 +43,7 @@ import org.springframework.security.core.context.SecurityContextHolder; * authenticated, the workbench is run as a privileged action by the related * subject. */ -public class SecureEntryPoint implements IEntryPoint { +public class SecureEntryPoint implements EntryPoint { private final static Log log = LogFactory.getLog(SecureEntryPoint.class); /** @@ -80,56 +81,74 @@ public class SecureEntryPoint implements IEntryPoint { SecurityContextHolder .setContext((SecurityContext) contextFromSessionObject); -// if (log.isDebugEnabled()) -// log.debug("THREAD=" + Thread.currentThread().getId() -// + ", sessionStore=" + RWT.getSessionStore().getId() -// + ", remote user=" + httpRequest.getRemoteUser()); + // 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 - final ILoginContext loginContext = SecureRapActivator - .createLoginContext(SecureRapActivator.CONTEXT_SPRING); - Subject subject = null; - 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); + 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"); } + } 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(); // Logout callback when the display is disposed display.disposeExec(new Runnable() { public void run() { log.debug("Display disposed"); - logout(loginContext, username); + // logout(loginContext, username); + try { + loginModule.logout(); + } catch (LoginException e) { + log.error("Error when logging out", e); + } } }); diff --git a/pom.xml b/pom.xml index 6f0d352ed..464b30736 100644 --- a/pom.xml +++ b/pom.xml @@ -28,9 +28,9 @@ org.argeo.security.jackrabbit org.argeo.security.ldap - org.argeo.security.auth.ldap - org.argeo.security.dao.ldap - org.argeo.security.dao.cli + + + org.argeo.server.core @@ -44,7 +44,7 @@ org.argeo.cms org.argeo.eclipse.ui.workbench - org.argeo.security.equinox + org.argeo.security.ui org.argeo.security.ui.admin org.argeo.security.ui.rap -- 2.30.2