Centralise login in Kernel
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 28 Jan 2015 11:04:23 +0000 (11:04 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 28 Jan 2015 11:04:23 +0000 (11:04 +0000)
Disable Equinox security

git-svn-id: https://svn.argeo.org/commons/trunk@7714 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

13 files changed:
demo/argeo_node_rap.properties
dep/org.argeo.dep.cms/pom.xml
org.argeo.cms/bnd.bnd
org.argeo.cms/pom.xml
org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/SpringLoginModule.java [new file with mode: 0644]
org.argeo.eclipse.ui.workbench/bnd.bnd
org.argeo.security.core/src/org/argeo/security/core/ThreadedLoginModule.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java
org.argeo.security.ui.rap/pom.xml
org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java
pom.xml

index 3410259d2ea45c016b72d0bab46680310fcd9e82..7c3b662b2a97b9028ae16610b170f2de6636883b 100644 (file)
@@ -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
index 28ccd858f7c30b7698d40b3d29dbee91ab487d7c..9e5d3183d49add9aca07468468c236c528587e26 100644 (file)
@@ -9,7 +9,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.dep.cms</artifactId>
-       <name>CMS Dependencies</name>
+       <name>Commons CMS Dependencies</name>
        <build>
                <plugins>
                        <plugin>
index 825c5957f169e4ea24bedb05b8be79c2b210c993..4772234852f4765e885efd5ca3f39a22301b9c6d 100644 (file)
@@ -12,4 +12,5 @@ org.h2;resolution:=optional,\
 org.springframework.context,\
 org.apache.jackrabbit.api,\
 org.apache.jackrabbit.commons,\
+org.eclipse.rap.rwt.osgi,\
 *
index c01e0161d0f9739f1b365cd9e845ffbe40f85f8e..498f042500d9e931bb3c4e2c6ea2af1e5f482d70 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.cms</artifactId>
-       <name>Argeo Content Management System</name>
+       <name>Commons Content Management System</name>
        <packaging>jar</packaging>
        <dependencies>
                <dependency>
index ef2403b445af8b665ec219929454f73e6fdcabb0..4b893f13d0b6e195be13c8354b8ab2dc756d8cb0 100644 (file)
@@ -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<ApplicationConfiguration> registerWorkbench(
-                       WorkbenchApplicationConfiguration wac) {
-               Hashtable<String, String> props = new Hashtable<String, String>();
-               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<String, String> props = new Hashtable<String, String>();
+                               props.put(ApplicationLauncher.PROPERTY_CONTEXT_NAME, "ui");
+                               workbenchReg = bundleContext.registerService(
+                                               ApplicationConfiguration.class, wac, props);
+                       }
+               }.start();
        }
 
        private void directorsCut() {
index 7c176ea89552fe1bd8a414be6c87d81a7c03a707..6ad8fb15c582f61968813cfae4c0d6c7f0202788 100644 (file)
@@ -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<AuthenticationManager> authenticationManagerReg;
        private ServiceRegistration<UserAdminService> userAdminReg;
        private ServiceRegistration<UserDetailsManager> userDetailsManagerReg;
+       private ServiceRegistration<LoginModule> 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 (file)
index 0000000..d2e5bce
--- /dev/null
@@ -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<SimpleGrantedAuthority> 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;
+       }
+
+}
index d6c44eeb98bfd7eea3ed3cc935ecb39b6a1b988c..cc95c7652b641651a755806b78631061259fab53 100644 (file)
@@ -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 (file)
index 0000000..8ddac89
--- /dev/null
@@ -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> loginModule = new ThreadLocal<LoginModule>() {
+
+               @Override
+               protected LoginModule initialValue() {
+                       return createLoginModule();
+               }
+
+       };
+
+       protected abstract LoginModule createLoginModule();
+
+       @Override
+       public void initialize(Subject subject, CallbackHandler callbackHandler,
+                       Map<String, ?> sharedState, Map<String, ?> 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();
+       }
+
+}
index b648f32c38b583481142f472ed82978b1d0f779d..fde3d850fcfb34b94ffcd3eabdbbd1af96d7251d 100644 (file)
@@ -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 {
index e54f3a44ba85b68c312e19cabea55c28e7bc1ee1..1f5cf6f15904fd8a4895ea920c83b2559a28276d 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.argeo.commons</groupId>
                </dependency>
 
                <!-- Logging -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-<!--           </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp</groupId> -->
+               <!-- <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
+               <!-- </dependency> -->
 
                <!-- Argeo Security -->
                <dependency>
                        <artifactId>org.argeo.security.ui</artifactId>
                        <version>2.1.13-SNAPSHOT</version>
                </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.security.equinox</artifactId>
-                       <version>2.1.13-SNAPSHOT</version>
-               </dependency>
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.commons</groupId> -->
+               <!-- <artifactId>org.argeo.security.equinox</artifactId> -->
+               <!-- <version>2.1.13-SNAPSHOT</version> -->
+               <!-- </dependency> -->
 
                <!-- RAP specific -->
-               <!--  <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.dep.rap</artifactId>
-                       <type>pom</type>
-                       <version>2.1.12-SNAPSHOT</version>
-               </dependency>  -->
+               <!-- <dependency> <groupId>org.argeo.commons</groupId> <artifactId>org.argeo.eclipse.dep.rap</artifactId> 
+                       <type>pom</type> <version>2.1.12-SNAPSHOT</version> </dependency> -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.eclipse.ui.rap</artifactId>
index c3754ed05cf89ef6fc1ca42ad75ae513c4400733..503e2746cf1ab36bbf5789fecf87372f3ad9f1d4 100644 (file)
@@ -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 6f0d352ed2e37d1868f36d035901866dc574f11f..464b30736f1eb7c5790d27baf43910343225be97 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -28,9 +28,9 @@
                <module>org.argeo.security.jackrabbit</module>
                <module>org.argeo.security.ldap</module>
                <!-- Security Services -->
-               <module>org.argeo.security.auth.ldap</module>
-               <module>org.argeo.security.dao.ldap</module>
-               <module>org.argeo.security.dao.cli</module>
+               <!-- <module>org.argeo.security.auth.ldap</module> -->
+               <!-- <module>org.argeo.security.dao.ldap</module> -->
+               <!-- <module>org.argeo.security.dao.cli</module> -->
                <!-- <module>org.argeo.security.dao.jackrabbit</module> -->
                <!-- Server -->
                <module>org.argeo.server.core</module>
@@ -44,7 +44,7 @@
                <module>org.argeo.cms</module>
                <!-- Workbench -->
                <module>org.argeo.eclipse.ui.workbench</module>
-               <module>org.argeo.security.equinox</module>
+               <!-- <module>org.argeo.security.equinox</module> -->
                <module>org.argeo.security.ui</module>
                <module>org.argeo.security.ui.admin</module>
                <module>org.argeo.security.ui.rap</module>