You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by am...@apache.org on 2004/11/20 08:38:56 UTC

svn commit: r105949 - in geronimo/trunk/modules: assembly/src/plan connector/src/java/org/apache/geronimo/connector/outbound/security jetty/src/test/org/apache/geronimo/jetty security/src/java/org/apache/geronimo/security/jaas security/src/java/org/apache/geronimo/security/realm security/src/java/org/apache/geronimo/security/realm/providers security/src/test/org/apache/geronimo/security security/src/test/org/apache/geronimo/security/bridge security/src/test/org/apache/geronimo/security/jaas security/src/test/org/apache/geronimo/security/network/protocol security/src/test/org/apache/geronimo/security/remoting/jmx

Author: ammulder
Date: Fri Nov 19 23:38:55 2004
New Revision: 105949

Added:
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DirectConfigurationEntry.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleGBean.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ServerRealmConfigurationEntry.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/GenericSecurityRealm.java
Removed:
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ConfigurationEntry.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ConfigurationEntryLocal.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ConfigurationEntryRealmLocal.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ConfigurationEntryRealmRemote.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/AbstractSecurityRealm.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/KerberosSecurityRealm.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PropertiesFileSecurityRealm.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLSecurityRealm.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLSecurityRealmPasswordDigested.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SimpleSecurityRealm.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestRealm.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginSimpleRealmTest.java
Modified:
   geronimo/trunk/modules/assembly/src/plan/j2ee-secure-plan.xml
   geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/security/PasswordCredentialRealm.java
   geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/BaseSecurityTest.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DecouplingCallbackHandler.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/GeronimoLoginConfiguration.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginCoordinator.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginModuleConfiguration.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginService.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/SecurityRealm.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java
   geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/AbstractTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/CallerIdentityUserPasswordBridgeTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/ConfiguredIdentityUserPasswordBridgeTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/MappingUserPasswordBridgeTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestLoginModule.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/ConfigurationEntryTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosNonGeronimoTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginPropertiesFileTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginSQLTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/TimeoutTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/network/protocol/SubjectCarryingProtocolTest.java
   geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/remoting/jmx/RemoteLoginTest.java
Log:
Next set of changes to security
 - GenericSecurityRealm replaces individual security realm implementations
 - Multiple login modules (including a mix of client and server side login
   modules) per realm is now a fully supported configuration
 - Options moved to login modules, each of which is deployed via
   a LoginModuleGBean
 - Reduced the number of available configuration entry classes
 - Make automapping configurable on the GenericSecurityRealm
 - Fixed all tests to run against the new configuration style

Still not done with security changes, mail will be forthcoming on the
  remaining issues.


Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-secure-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-secure-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-secure-plan.xml	Fri Nov 19 23:38:55 2004
@@ -36,21 +36,30 @@
 
     <!-- Security GBeans -->
 
-    <!-- JAAS Application Config Entry -->
-    <gbean name="geronimo.security:type=ConfigurationEntry,jaasId=jaasTest" class="org.apache.geronimo.security.jaas.ConfigurationEntryRealmLocal">
-        <attribute name="applicationConfigName" type="java.lang.String">jaasTest</attribute>
-        <attribute name="realmName" type="java.lang.String">demo-properties-realm</attribute>
-        <attribute name="controlFlag" type="org.apache.geronimo.security.jaas.LoginModuleControlFlag">REQUIRED</attribute>
-        <attribute name="options" type="java.util.Properties">foo=bar</attribute>
+    <gbean name="geronimo.security:type=LoginModule,name=demo-properties-login"
+        class="org.apache.geronimo.security.jaas.LoginModuleGBean">
+        <attribute name="loginModuleClass" type="java.lang.String">org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule</attribute>
+        <attribute name="serverSide" type="boolean">true</attribute>
+        <attribute name="options" type="java.util.Properties">
+            usersURI=var/security/demo_users.properties
+            groupsURI=var/security/demo_groups.properties
+        </attribute>
     </gbean>
 
-    <!-- Demo Properties File Realm -->
-    <gbean name="geronimo.security:type=SecurityRealm,realm=demo-properties-realm" class="org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm">
+    <gbean name="geronimo.security:type=SecurityRealm,realm=demo-properties-realm"
+        class="org.apache.geronimo.security.realm.GenericSecurityRealm">
         <attribute name="realmName" type="java.lang.String">demo-properties-realm</attribute>
-        <attribute name="maxLoginModuleAge" type="long">10000</attribute>
-        <attribute name="usersURI" type="java.net.URI">var/security/demo_users.properties</attribute>
-        <attribute name="groupsURI" type="java.net.URI">var/security/demo_groups.properties</attribute>
+        <attribute name="loginModuleConfiguration" type="java.util.Properties">
+            LoginModule.1.REQUIRED=geronimo.security:type=LoginModule,name=demo-properties-login
+        </attribute>
+        <attribute name="autoMapPrincipalClasses" type="java.lang.String">org.apache.geronimo.security.realm.providers.PropertiesFileGroupPrincipal</attribute>
         <reference name="ServerInfo">geronimo.system:role=ServerInfo</reference>
+    </gbean>
+
+    <gbean name="geronimo.security:type=ConfigurationEntry,jaasId=jaasTest"
+        class="org.apache.geronimo.security.jaas.ServerRealmConfigurationEntry">
+        <attribute name="applicationConfigName" type="java.lang.String">jaasTest</attribute>
+        <attribute name="realmName" type="java.lang.String">demo-properties-realm</attribute>
     </gbean>
 
     <!-- Jetty Realm that points to the Geronimo Demo Properties File Realm -->

Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml	Fri Nov 19 23:38:55 2004
@@ -100,18 +100,30 @@
 
 
     <!-- Default security realm using properties files -->
-    <gbean name="geronimo.security:type=SecurityRealm,realm=geronimo-properties-realm" class="org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm">
+    <gbean name="geronimo.security:type=LoginModule,name=properties-login"
+        class="org.apache.geronimo.security.jaas.LoginModuleGBean">
+        <attribute name="loginModuleClass" type="java.lang.String">org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule</attribute>
+        <attribute name="serverSide" type="boolean">true</attribute>
+        <attribute name="options" type="java.util.Properties">
+            usersURI=var/security/users.properties
+            groupsURI=var/security/groups.properties
+        </attribute>
+    </gbean>
+
+    <gbean name="geronimo.security:type=SecurityRealm,realm=geronimo-properties-realm"
+           class="org.apache.geronimo.security.realm.GenericSecurityRealm">
         <attribute name="realmName" type="java.lang.String">geronimo-properties-realm</attribute>
-        <attribute name="maxLoginModuleAge" type="long">10000</attribute>
-        <attribute name="usersURI" type="java.net.URI">var/security/users.properties</attribute>
-        <attribute name="groupsURI" type="java.net.URI">var/security/groups.properties</attribute>
+        <attribute name="loginModuleConfiguration" type="java.util.Properties">
+            LoginModule.1.REQUIRED=geronimo.security:type=LoginModule,name=properties-login
+        </attribute>
         <reference name="ServerInfo">geronimo.system:role=ServerInfo</reference>
+        <attribute name="autoMapPrincipalClasses" type="java.lang.String">org.apache.geronimo.security.realm.providers.PropertiesFileGroupPrincipal</attribute>
     </gbean>
 
-    <gbean name="geronimo.security:type=ConfigurationEntry,jaasId=JMX" class="org.apache.geronimo.security.jaas.ConfigurationEntryRealmLocal">
+    <gbean name="geronimo.security:type=ConfigurationEntry,jaasId=JMX"
+           class="org.apache.geronimo.security.jaas.ServerRealmConfigurationEntry">
         <attribute name="applicationConfigName" type="java.lang.String">JMX</attribute>
         <attribute name="realmName" type="java.lang.String">geronimo-properties-realm</attribute>
-        <attribute name="controlFlag" type="org.apache.geronimo.security.jaas.LoginModuleControlFlag">REQUIRED</attribute>
     </gbean>
 
     <!-- Register GeronimoLoginConfiguration as the LoginConfiguration handler -->

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/security/PasswordCredentialRealm.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/security/PasswordCredentialRealm.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/security/PasswordCredentialRealm.java	Fri Nov 19 23:38:55 2004
@@ -22,13 +22,13 @@
 import java.util.Set;
 
 import javax.resource.spi.ManagedConnectionFactory;
-import javax.security.auth.login.AppConfigurationEntry;
 
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.GBeanInfoBuilder;
 import org.apache.geronimo.common.GeronimoSecurityException;
 import org.apache.geronimo.security.realm.SecurityRealm;
-import org.apache.geronimo.security.realm.providers.AbstractSecurityRealm;
+import org.apache.geronimo.security.jaas.JaasLoginModuleConfiguration;
+import org.apache.geronimo.security.jaas.LoginModuleControlFlag;
 import org.apache.regexp.RE;
 
 /**
@@ -37,16 +37,25 @@
  * @version $Rev$ $Date$
  *
  * */
-public class PasswordCredentialRealm extends AbstractSecurityRealm implements SecurityRealm, ManagedConnectionFactoryListener {
+public class PasswordCredentialRealm implements SecurityRealm, ManagedConnectionFactoryListener {
 
     private static final GBeanInfo GBEAN_INFO;
 
     ManagedConnectionFactory managedConnectionFactory;
+    String realmName;
 
     static final String REALM_INSTANCE = "org.apache.connector.outbound.security.PasswordCredentialRealm";
 
     public PasswordCredentialRealm(String realmName) {
-        super(realmName);
+        this.realmName = realmName;
+    }
+
+    public String getRealmName() {
+        return realmName;
+    }
+
+    public void setRealmName(String realmName) {
+        this.realmName = realmName;
     }
 
     public Set getGroupPrincipals() throws GeronimoSecurityException {
@@ -68,16 +77,15 @@
     public void refresh() throws GeronimoSecurityException {
     }
 
-    public AppConfigurationEntry[] getAppConfigurationEntries() {
+    public JaasLoginModuleConfiguration[] getAppConfigurationEntries() {
         Map options = new HashMap();
 
         // TODO: This can be a bad thing, passing a reference to a realm to the login module
         // since the SerializableACE can be sent remotely
         options.put(REALM_INSTANCE, this);
-        AppConfigurationEntry appConfigurationEntry = new AppConfigurationEntry(PasswordCredentialLoginModule.class.getName(),
-                AppConfigurationEntry.LoginModuleControlFlag.REQUISITE,
-                options);
-        return new AppConfigurationEntry[]{appConfigurationEntry};
+        JaasLoginModuleConfiguration config = new JaasLoginModuleConfiguration(getRealmName(), PasswordCredentialLoginModule.class.getName(),
+                LoginModuleControlFlag.REQUISITE, options, true);
+        return new JaasLoginModuleConfiguration[]{config};
     }
 
     public boolean isLoginModuleLocal() {
@@ -93,8 +101,10 @@
     }
 
     static {
-        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(PasswordCredentialRealm.class, AbstractSecurityRealm.getGBeanInfo());
+        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(PasswordCredentialRealm.class);
         infoFactory.addInterface(ManagedConnectionFactoryListener.class);
+        infoFactory.addAttribute("realmName", String.class, true);
+        infoFactory.setConstructor(new String[]{"realmName"});
         GBEAN_INFO = infoFactory.getBeanInfo();
     }
 

Modified: geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/BaseSecurityTest.java
==============================================================================
--- geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/BaseSecurityTest.java	(original)
+++ geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/BaseSecurityTest.java	Fri Nov 19 23:38:55 2004
@@ -22,6 +22,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Properties;
 
 import junit.framework.TestCase;
 
@@ -51,6 +52,8 @@
     protected ObjectName jaasRealmName;
     protected GBeanMBean propertiesRealmGBean;
     protected ObjectName propertiesRealmName;
+    protected GBeanMBean propertiesLMGBean;
+    protected ObjectName propertiesLMName;
     protected ObjectName loginServiceName;
     protected GBeanMBean loginServiceGBean;
     protected ObjectName securityServiceName;
@@ -118,16 +121,27 @@
         loginServiceGBean.setAttribute("algorithm", "HmacSHA1");
         loginServiceGBean.setAttribute("password", "secret");
 
-        propertiesRealmGBean = new GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
+        propertiesLMGBean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        propertiesLMName = new ObjectName("geronimo.security:type=LoginModule,name=demo-properties-login");
+        propertiesLMGBean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule");
+        propertiesLMGBean.setAttribute("serverSide", Boolean.TRUE);
+        Properties options = new Properties();
+        options.setProperty("usersURI", new File(new File("."), "src/test-resources/data/users.properties").toString());
+        options.setProperty("groupsURI", new File(new File("."), "src/test-resources/data/groups.properties").toString());
+        propertiesLMGBean.setAttribute("options", options);
+
+        propertiesRealmGBean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
         propertiesRealmName = new ObjectName("geronimo.security:type=SecurityRealm,realm=demo-properties-realm");
         propertiesRealmGBean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfoName));
         propertiesRealmGBean.setAttribute("realmName", "demo-properties-realm");
-        propertiesRealmGBean.setAttribute("defaultPrincipal", "metro");
-        propertiesRealmGBean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        propertiesRealmGBean.setAttribute("usersURI", (new File(new File("."), "src/test-resources/data/users.properties")).toURI());
-        propertiesRealmGBean.setAttribute("groupsURI", (new File(new File("."), "src/test-resources/data/groups.properties")).toURI());
+        Properties config = new Properties();
+        config.setProperty("LoginModule.1.REQUIRED", propertiesLMName.getCanonicalName());
+        propertiesRealmGBean.setAttribute("loginModuleConfiguration", config);
+        propertiesRealmGBean.setAttribute("autoMapPrincipalClasses", "org.apache.geronimo.security.realm.providers.PropertiesFileGroupPrincipal");
+        propertiesRealmGBean.setAttribute("defaultPrincipal", "metro=org.apache.geronimo.security.realm.providers.PropertiesFileUserPrincipal");
 
         start(serverInfoName, serverInfoGBean);
+        start(propertiesLMName, propertiesLMGBean);
         start(propertiesRealmName, propertiesRealmGBean);
         start(containerName, container);
         start(securityServiceName, securityServiceGBean);
@@ -158,6 +172,7 @@
         stop(securityServiceName);
         stop(containerName);
         stop(propertiesRealmName);
+        stop(propertiesLMName);
         stop(serverInfoName);
         kernel.shutdown();
     }

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DecouplingCallbackHandler.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DecouplingCallbackHandler.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DecouplingCallbackHandler.java	Fri Nov 19 23:38:55 2004
@@ -42,7 +42,7 @@
             throws IllegalArgumentException, UnsupportedCallbackException {
         if (exploring) {
             source = callbacks;
-            throw new UnsupportedCallbackException(callbacks.length > 0 ? callbacks[0] : null, "DO NOT PROCEED WITH THIS LOGIN");
+            throw new UnsupportedCallbackException(callbacks != null && callbacks.length > 0 ? callbacks[0] : null, "DO NOT PROCEED WITH THIS LOGIN");
         } else {
             if(callbacks.length != source.length) {
                 throw new IllegalArgumentException("Mismatched callbacks");
@@ -53,7 +53,18 @@
         }
     }
 
-    public void load(Callback[] callbacks) throws IllegalArgumentException {
+    /**
+     * Within the same VM, the client just populates the callbacks directly
+     * into the array held by this object.  However, remote clients will
+     * serialize their responses, so they need to be manually set back on this
+     * object to take effect.
+     *
+     * @param callbacks The callbacks populated by the client
+     */
+    public void setClientResponse(Callback[] callbacks) throws IllegalArgumentException {
+        if(source == null && callbacks == null) {
+            return; // i.e. The Kerberos LM doesn't need callbacks
+        }
         if(callbacks.length != source.length) {
             throw new IllegalArgumentException("Mismatched callbacks");
         }
@@ -75,7 +86,7 @@
 
     /**
      * Indicates that the exploring phase is over.
-     */ 
+     */
     public Callback[] finalizeCallbackList() {
         exploring = false;
         return source;

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DirectConfigurationEntry.java
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/DirectConfigurationEntry.java	Fri Nov 19 23:38:55 2004
@@ -0,0 +1,74 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ *  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.apache.geronimo.security.jaas;
+
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
+import org.apache.geronimo.gbean.GBeanLifecycle;
+import org.apache.geronimo.gbean.WaitingException;
+
+/**
+ * Exposes a LoginModule directly to JAAS clients, without any particular
+ * wrapping by Geronimo.  You do still need to declare the login module as a
+ * GBean, but it's not like it will be run through the login service or
+ * anything.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class DirectConfigurationEntry implements GBeanLifecycle {
+    private String applicationConfigName;
+    private LoginModuleControlFlag controlFlag;
+    private LoginModuleGBean module;
+
+    public DirectConfigurationEntry() {
+        // just for use by GBean infrastructure
+    }
+
+    public DirectConfigurationEntry(String applicationConfigName, LoginModuleControlFlag controlFlag, LoginModuleGBean module) {
+        this.applicationConfigName = applicationConfigName;
+        this.controlFlag = controlFlag;
+        this.module = module;
+    }
+
+    public void doStart() throws WaitingException, Exception {
+        GeronimoLoginConfiguration.register(new JaasLoginModuleConfiguration(applicationConfigName, module.getLoginModuleClass(), controlFlag, module.getOptions(), module.isServerSide()));
+    }
+
+    public void doStop() throws WaitingException, Exception {
+        GeronimoLoginConfiguration.unRegister(applicationConfigName);
+    }
+
+    public void doFail() {
+    }
+
+    public static final GBeanInfo GBEAN_INFO;
+
+    static {
+        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(DirectConfigurationEntry.class);
+        infoFactory.addAttribute("applicationConfigName", String.class, true);
+        infoFactory.addAttribute("controlFlag", LoginModuleControlFlag.class, true);
+
+        infoFactory.addReference("Module", LoginModuleGBean.class);
+
+        infoFactory.setConstructor(new String[]{"applicationConfigName", "controlFlag", "Module"});
+        GBEAN_INFO = infoFactory.getBeanInfo();
+    }
+
+    public static GBeanInfo getGBeanInfo() {
+        return GBEAN_INFO;
+    }
+}

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/GeronimoLoginConfiguration.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/GeronimoLoginConfiguration.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/GeronimoLoginConfiguration.java	Fri Nov 19 23:38:55 2004
@@ -19,6 +19,8 @@
 
 import java.util.Hashtable;
 import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
 import javax.security.auth.login.AppConfigurationEntry;
 import javax.security.auth.login.Configuration;
 
@@ -27,6 +29,8 @@
 import org.apache.geronimo.gbean.GBeanLifecycle;
 import org.apache.geronimo.gbean.WaitingException;
 import org.apache.geronimo.security.SecurityService;
+import org.apache.geronimo.security.realm.SecurityRealm;
+import org.apache.geronimo.kernel.Kernel;
 
 
 /**
@@ -42,32 +46,60 @@
 
     private static Map entries = new Hashtable();
     private Configuration oldConfiguration;
+    private Kernel kernel;
+
+    public GeronimoLoginConfiguration(Kernel kernel) {
+        this.kernel = kernel;
+    }
 
     public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
-        ConfigurationEntry entry = (ConfigurationEntry) entries.get(name);
+        AppConfigurationEntry entry = (AppConfigurationEntry) entries.get(name);
 
         if (entry == null) return null;
 
-        return entry.getAppConfigurationEntry();
+//        if(!entry.getOptions().containsKey("kernel")) {
+//            entry.getOptions().put("kernel", kernel.getKernelName());
+//        }
+
+        return new AppConfigurationEntry[]{entry};
     }
 
     public void refresh() {
     }
 
-    public static void register(ConfigurationEntry entry) {
+    /**
+     * Registers a single Geronimo LoginModule
+     */
+    public static void register(JaasLoginModuleConfiguration entry) {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) sm.checkPermission(SecurityService.CONFIGURE);
 
-        if (entries.containsKey(entry.getApplicationConfigName())) throw new java.lang.IllegalArgumentException("ConfigurationEntry already registered");
+        if (entries.containsKey(entry.getName())) throw new java.lang.IllegalArgumentException("ConfigurationEntry already registered");
+
+        entries.put(entry.getName(), getAppConfigurationEntry(entry));
+    }
+
+    private static AppConfigurationEntry getAppConfigurationEntry(JaasLoginModuleConfiguration config) {
+        return new AppConfigurationEntry(config.getLoginModuleClassName(), config.getFlag().getFlag(), config.getOptions());
+    }
+
+    /**
+     * Registers a wrapper configuration that will hit a Geronimo security
+     * realm under the covers.
+     */
+    public static void register(SecurityRealm realm) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) sm.checkPermission(SecurityService.CONFIGURE);
 
-        entries.put(entry.getApplicationConfigName(), entry);
+        if (entries.containsKey(realm.getRealmName())) throw new java.lang.IllegalArgumentException("ConfigurationEntry already registered");
+        entries.put(realm.getRealmName(), new AppConfigurationEntry("org.apache.geronimo.security.jaas.JaasLoginCoordinator", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new Properties()));
     }
 
-    public static void unRegister(ConfigurationEntry entry) {
+    public static void unRegister(String name) {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) sm.checkPermission(SecurityService.CONFIGURE);
 
-        entries.remove(entry.getApplicationConfigName());
+        entries.remove(name);
     }
 
     public void doStart() throws WaitingException, Exception {
@@ -95,6 +127,8 @@
 
     static {
         GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(GeronimoLoginConfiguration.class.getName());
+        infoFactory.addAttribute("kernel", Kernel.class, false);
+        infoFactory.setConstructor(new String[]{"kernel"});
         GBEAN_INFO = infoFactory.getBeanInfo();
     }
 }

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginCoordinator.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginCoordinator.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginCoordinator.java	Fri Nov 19 23:38:55 2004
@@ -69,7 +69,12 @@
         kernelName = (String) options.get(OPTION_KERNEL);
         service = connect();
         handler = callbackHandler;
-        this.subject = subject;
+        if(subject == null) {
+            this.subject = new Subject();
+        } else {
+            this.subject = subject;
+        }
+        //todo: shared state
     }
 
     public boolean login() throws LoginException {
@@ -190,7 +195,11 @@
 
         public boolean login() throws LoginException {
             try {
-                handler.handle(callbacks);
+                if(handler != null) {
+                    handler.handle(callbacks);
+                } else if(callbacks != null && callbacks.length > 0) {
+                    System.err.println("No callback handler available for "+callbacks.length+" callbacks!");
+                }
                 return service.performServerLogin(client, index, callbacks);
             } catch (LoginException e) {
                 throw e;

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginModuleConfiguration.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginModuleConfiguration.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginModuleConfiguration.java	Fri Nov 19 23:38:55 2004
@@ -20,7 +20,11 @@
 
 import javax.security.auth.spi.LoginModule;
 import java.io.Serializable;
+import java.io.Externalizable;
 import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.rmi.Remote;
 
 /**
  * Describes the configuration of a LoginModule -- its name, class, control
@@ -31,18 +35,24 @@
  */
 public class JaasLoginModuleConfiguration implements Serializable {
     private boolean serverSide;
+    private String name;
     private LoginModuleControlFlag flag;
     private String loginModuleName;
     private Map options;
     private transient LoginModule loginModule;
 
-    public JaasLoginModuleConfiguration(String loginModuleName, LoginModuleControlFlag flag, Map options, boolean serverSide) {
+    public JaasLoginModuleConfiguration(String name, String loginModuleName, LoginModuleControlFlag flag, Map options, boolean serverSide) {
+        this.name = name;
         this.serverSide = serverSide;
         this.flag = flag;
         this.loginModuleName = loginModuleName;
         this.options = options;
     }
 
+    public String getLoginModuleClassName() {
+        return loginModuleName;
+    }
+
     public LoginModule getLoginModule(ClassLoader loader) throws GeronimoSecurityException {
         if(loginModule == null) {
             try {
@@ -64,5 +74,26 @@
 
     public Map getOptions() {
         return options;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Strips out stuff that isn't serializable so this can be safely passed to
+     * a remote server.
+     */
+    public JaasLoginModuleConfiguration getSerializableCopy() {
+        Map other = new HashMap();
+        for (Iterator it = options.keySet().iterator(); it.hasNext();) {
+            String key = (String) it.next();
+            Object value = options.get(key);
+            if(value instanceof Serializable || value instanceof Externalizable || value instanceof Remote) {
+                other.put(key, value);
+            }
+        }
+
+        return new JaasLoginModuleConfiguration(name, loginModuleName, flag, other, serverSide);
     }
 }

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginService.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginService.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/JaasLoginService.java	Fri Nov 19 23:38:55 2004
@@ -32,13 +32,12 @@
 import javax.management.ObjectName;
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
-import javax.security.auth.login.AppConfigurationEntry;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
-
 import EDU.oswego.cs.dl.util.concurrent.ClockDaemon;
 import EDU.oswego.cs.dl.util.concurrent.ThreadFactory;
-
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.geronimo.common.GeronimoSecurityException;
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.GBeanInfoBuilder;
@@ -61,6 +60,7 @@
  */
 public class JaasLoginService implements GBeanLifecycle, JaasLoginServiceMBean {
     public static final ObjectName OBJECT_NAME = JMXUtil.getObjectName("geronimo.security:type=JaasLoginService");
+    public static final Log log = LogFactory.getLog(JaasLoginService.class);
     private final static int DEFAULT_EXPIRED_LOGIN_SCAN_INTERVAL = 300000; // 5 mins
     private final static int DEFAULT_MAX_LOGIN_DURATION =  1000 * 3600 * 24; // 1 day
     private final static ClockDaemon clockDaemon;
@@ -171,7 +171,13 @@
         if(context == null) {
             throw new ExpiredLoginModuleException();
         }
-        return context.getModules();
+        JaasLoginModuleConfiguration[] config = context.getModules();
+        // strip out non-serializable configuration options
+        JaasLoginModuleConfiguration[] result = new JaasLoginModuleConfiguration[config.length];
+        for (int i = 0; i < config.length; i++) {
+            result[i] = config[i].getSerializableCopy();
+        }
+        return result;
     }
 
     /**
@@ -192,7 +198,12 @@
         JaasLoginModuleConfiguration config = context.getModules()[loginModuleIndex];
         LoginModule module = config.getLoginModule(classLoader);
         //todo: properly handle shared state
-        module.initialize(context.getSubject(), context.getHandler(), new HashMap(), config.getOptions());
+        try {
+            module.initialize(context.getSubject(), context.getHandler(), new HashMap(), config.getOptions());
+        } catch (Exception e) {
+            System.err.println("Failed to initialize module");
+            e.printStackTrace();
+        }
         try {
             module.login();
         } catch (LoginException e) {}
@@ -219,7 +230,7 @@
         }
         JaasLoginModuleConfiguration module = context.getModules()[loginModuleIndex];
         try {
-            context.getHandler().load(results);
+            context.getHandler().setClientResponse(results);
         } catch (IllegalArgumentException iae) {
             throw new LoginException(iae.toString());
         }
@@ -315,13 +326,7 @@
             id = ++nextLoginModuleId;
         }
         JaasClientId clientId = new JaasClientId(id, hash(id));
-        AppConfigurationEntry[] entries = realm.getAppConfigurationEntries();
-        JaasLoginModuleConfiguration[] modules = new JaasLoginModuleConfiguration[entries.length];
-        for (int i = 0; i < modules.length; i++) {
-            modules[i] = new JaasLoginModuleConfiguration(entries[i].getLoginModuleName(),
-                    LoginModuleControlFlag.getInstance(entries[i].getControlFlag()), entries[i].getOptions(),
-                    realm.isLoginModuleLocal()); //todo: calculate local-ness per module
-        }
+        JaasLoginModuleConfiguration[] modules = realm.getAppConfigurationEntries();
         JaasSecurityContext context = new JaasSecurityContext(realm.getRealmName(), modules);
         activeLogins.put(clientId, context);
         return clientId;

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleGBean.java
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleGBean.java	Fri Nov 19 23:38:55 2004
@@ -0,0 +1,82 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ *  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.apache.geronimo.security.jaas;
+
+import java.util.Properties;
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
+
+/**
+ * A GBean that wraps a LoginModule, plus options to configure the LoginModule.
+ * If you want to deploy the same LoginModule with different options, you need
+ * more than one of these GBeans.  But if you want two security realms to refer
+ * to exactly the same login module configuration, you can have both realms
+ * refer to a single login module GBean.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class LoginModuleGBean {
+    private String loginModuleClass;
+    private Properties options;
+    private String objectName;
+    private boolean serverSide;
+
+    public LoginModuleGBean() {
+    }
+    
+    public LoginModuleGBean(String loginModuleClass, String objectName, boolean serverSide) {
+        this.loginModuleClass = loginModuleClass;
+        this.objectName = objectName;
+        this.serverSide = serverSide;
+    }
+
+    public Properties getOptions() {
+        return options;
+    }
+
+    public void setOptions(Properties options) {
+        this.options = options;
+    }
+
+    public String getLoginModuleClass() {
+        return loginModuleClass;
+    }
+
+    public String getObjectName() {
+        return objectName;
+    }
+
+    public boolean isServerSide() {
+        return serverSide;
+    }
+
+    public static final GBeanInfo GBEAN_INFO;
+
+    static {
+        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(LoginModuleGBean.class);
+        infoFactory.addAttribute("options", Properties.class, true);
+        infoFactory.addAttribute("loginModuleClass", String.class, true);
+        infoFactory.addAttribute("objectName", String.class, false);
+        infoFactory.addAttribute("serverSide", boolean.class, true);
+        infoFactory.setConstructor(new String[]{"loginModuleClass","objectName","serverSide"});
+        GBEAN_INFO = infoFactory.getBeanInfo();
+    }
+
+    public static GBeanInfo getGBeanInfo() {
+        return GBEAN_INFO;
+    }
+}

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ServerRealmConfigurationEntry.java
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/ServerRealmConfigurationEntry.java	Fri Nov 19 23:38:55 2004
@@ -0,0 +1,79 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ *  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.apache.geronimo.security.jaas;
+
+import java.util.Properties;
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
+import org.apache.geronimo.gbean.GBeanLifecycle;
+import org.apache.geronimo.gbean.WaitingException;
+import org.apache.geronimo.kernel.Kernel;
+
+/**
+ * Creates a LoginModule configuration that will connect a server-side
+ * component to a security realm.  The same thing could be done with a
+ * LoginModuleGBean and a DirectConfigurationEntry, but this method saves some
+ * configuration effort.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class ServerRealmConfigurationEntry implements GBeanLifecycle {
+    private String applicationConfigName;
+    private String realmName;
+    private Kernel kernel;
+
+    public ServerRealmConfigurationEntry() {
+        // just for use by GBean infrastructure
+    }
+
+    public ServerRealmConfigurationEntry(String applicationConfigName, String realmName, Kernel kernel) {
+        this.applicationConfigName = applicationConfigName;
+        this.realmName = realmName;
+        this.kernel = kernel;
+    }
+
+    public void doStart() throws WaitingException, Exception {
+        Properties options = new Properties();
+        options.put("realm", realmName);
+        options.put("kernel", kernel.getKernelName());
+        JaasLoginModuleConfiguration entry = new JaasLoginModuleConfiguration(applicationConfigName, JaasLoginCoordinator.class.getName(), LoginModuleControlFlag.REQUIRED, options, true);
+        GeronimoLoginConfiguration.register(entry);
+    }
+
+    public void doStop() throws WaitingException, Exception {
+        GeronimoLoginConfiguration.unRegister(applicationConfigName);
+    }
+
+    public void doFail() {
+    }
+
+    public static final GBeanInfo GBEAN_INFO;
+
+    static {
+        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(ServerRealmConfigurationEntry.class);
+        infoFactory.addAttribute("applicationConfigName", String.class, true);
+        infoFactory.addAttribute("realmName", String.class, true);
+        infoFactory.addAttribute("kernel", Kernel.class, false);
+
+        infoFactory.setConstructor(new String[]{"applicationConfigName", "realmName", "kernel"});
+        GBEAN_INFO = infoFactory.getBeanInfo();
+    }
+
+    public static GBeanInfo getGBeanInfo() {
+        return GBEAN_INFO;
+    }
+}

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/GenericSecurityRealm.java
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/GenericSecurityRealm.java	Fri Nov 19 23:38:55 2004
@@ -0,0 +1,263 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ *  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.apache.geronimo.security.realm;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import org.apache.geronimo.common.GeronimoSecurityException;
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
+import org.apache.geronimo.gbean.GBeanLifecycle;
+import org.apache.geronimo.gbean.WaitingException;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.kernel.jmx.MBeanProxyFactory;
+import org.apache.geronimo.security.deploy.Principal;
+import org.apache.geronimo.security.jaas.GeronimoLoginConfiguration;
+import org.apache.geronimo.security.jaas.JaasLoginModuleConfiguration;
+import org.apache.geronimo.security.jaas.LoginModuleControlFlag;
+import org.apache.geronimo.security.jaas.LoginModuleControlFlagEditor;
+import org.apache.geronimo.security.jaas.LoginModuleGBean;
+import org.apache.geronimo.system.serverinfo.ServerInfo;
+import org.apache.regexp.RE;
+
+/**
+ * A security realm that can be configured for one or more login modules.  It
+ * can handle a combination of client-side and server-side login modules for
+ * the case of remote clients, and it can auto-role-mapping for its login
+ * modules (though you must configure it for that).
+ *
+ * To configure the list of LoginModules, set the loginModuleConfiguration
+ * to a Properties object with syntax like this:
+ * <pre>
+ * LoginModule.1.REQUIRED=ObjectName1
+ * LoginModule.2.SUFFICIENT=ObjectName2
+ * ...
+ * </pre>
+ * Each ObjectName should identify a LoginModuleGBean in the server
+ * configuration.  Each LoginModuleGBean has the configuration options for its
+ * login module, and knows whether it should run on the client side or server
+ * side.
+ *
+ * This realm populates a number of special login module options for the
+ * benefit of Geronimo login modules (though some of them are only available to
+ * server-side login modules, marked as not Serializable below):
+ * <pre>
+ * Option                                      Type                   Serializable
+ * GenericSecurityRealm.KERNEL_LM_OPTION       String (Kernel name)        Yes
+ * GenericSecurityRealm.SERVERINFO_LM_OPTION   ServerInfo                  No
+ * GenericSecurityRealm.CLASSLOADER_LM_OPTION  ClassLoader                 No
+ * </pre>
+ * These options can be safely ignored by login modules that don't need them
+ * (such as any custom LoginModules you may already have lying around).
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class GenericSecurityRealm implements SecurityRealm, GBeanLifecycle, AutoMapAssistant {
+    public final static String KERNEL_LM_OPTION="org.apache.geronimo.security.realm.GenericSecurityRealm.KERNEL";
+    public final static String SERVERINFO_LM_OPTION="org.apache.geronimo.security.realm.GenericSecurityRealm.SERVERINFO";
+    public final static String CLASSLOADER_LM_OPTION="org.apache.geronimo.security.realm.GenericSecurityRealm.CLASSLOADER";
+    private String name;
+    private JaasLoginModuleConfiguration[] config;
+    private Kernel kernel;
+    private ServerInfo serverInfo;
+    private ClassLoader classLoader;
+    private String[] autoMapPrincipals;
+    private Principal defaultPrincipal;
+
+    public GenericSecurityRealm(String realmName, Kernel kernel, ServerInfo serverInfo, Properties loginModuleConfiguration, ClassLoader classLoader) throws MalformedObjectNameException {
+        this.name = realmName;
+        this.kernel = kernel;
+        this.serverInfo = serverInfo;
+        this.classLoader = classLoader;
+        processConfiguration(loginModuleConfiguration);
+    }
+
+    public void doStart() throws WaitingException, Exception {
+        GeronimoLoginConfiguration.register(this);
+    }
+
+    public void doStop() throws WaitingException, Exception {
+        GeronimoLoginConfiguration.unRegister(name);
+    }
+
+    public void doFail() {
+    }
+
+    public String getRealmName() {
+        return name;
+    }
+
+    public JaasLoginModuleConfiguration[] getAppConfigurationEntries() {
+        return config;
+    }
+
+    /**
+     * Provides the default principal to be used when an unauthenticated
+     * subject uses a container.
+     *
+     * @return the default principal
+     */
+    public Principal obtainDefaultPrincipal() {
+        return defaultPrincipal;
+    }
+
+    /**
+     * Provides a set of principal class names to be used when automatically
+     * mapping principals to roles.
+     *
+     * @return a set of principal class names
+     */
+    public Set obtainRolePrincipalClasses() {
+        Set set = new HashSet();
+        for (int i = 0; i < autoMapPrincipals.length; i++) {
+            set.add(autoMapPrincipals[i]);
+        }
+        return set;
+    }
+
+    public void setDefaultPrincipal(String code) {
+        if(code != null) {
+            String[] parts=code.split("=");
+            if(parts.length != 2) {
+                throw new IllegalArgumentException("Default Principal should have the form 'name=class'");
+            }
+            defaultPrincipal = new Principal();
+            defaultPrincipal.setPrincipalName(parts[0]);
+            defaultPrincipal.setClassName(parts[1]);
+        }
+    }
+
+    public void setAutoMapPrincipalClasses(String classes) {
+        if(classes != null) {
+            autoMapPrincipals = classes.split(",");
+        } else {
+            autoMapPrincipals = new String[0];
+        }
+    }
+
+    /**
+     * @deprecated Will be removed in favor of (some kind of realm editor object) in
+     *             a future milestone release.
+     */
+    public Set getGroupPrincipals() throws GeronimoSecurityException {
+        return null; //todo
+    }
+
+    /**
+     * @deprecated Will be removed in favor of (some kind of realm editor object) in
+     *             a future milestone release.
+     */
+    public Set getGroupPrincipals(RE regexExpression) throws GeronimoSecurityException {
+        return null; //todo
+    }
+
+    /**
+     * @deprecated Will be removed in favor of (some kind of realm editor object) in
+     *             a future milestone release.
+     */
+    public Set getUserPrincipals() throws GeronimoSecurityException {
+        return null; //todo
+    }
+
+    /**
+     * @deprecated Will be removed in favor of (some kind of realm editor object) in
+     *             a future milestone release.
+     */
+    public Set getUserPrincipals(RE regexExpression) throws GeronimoSecurityException {
+        return null; //todo
+    }
+
+    private void processConfiguration(Properties props) throws MalformedObjectNameException {
+        int i = 1;
+        List list = new ArrayList();
+        LoginModuleControlFlagEditor editor = new LoginModuleControlFlagEditor();
+        while(true) {
+            boolean found = false;
+            String prefix = "LoginModule."+i+".";
+            for (Enumeration en = props.propertyNames(); en.hasMoreElements();) {
+                String key = (String) en.nextElement();
+                if(key.startsWith(prefix)) {
+                    String flagName = key.substring(prefix.length()).toUpperCase();
+                    editor.setAsText(flagName);
+                    LoginModuleControlFlag flag = (LoginModuleControlFlag) editor.getValue();
+                    LoginModuleGBean module = (LoginModuleGBean) MBeanProxyFactory.getProxy(LoginModuleGBean.class, kernel.getMBeanServer(), new ObjectName(props.getProperty(key)));
+                    Map options = module.getOptions();
+                    if(options != null) {
+                        options = new HashMap(options);
+                    } else {
+                        options = new HashMap();
+                    }
+                    if(kernel != null && !options.containsKey(KERNEL_LM_OPTION)) {
+                        options.put(KERNEL_LM_OPTION, kernel.getKernelName());
+                    }
+                    if(serverInfo != null && !options.containsKey(SERVERINFO_LM_OPTION)) {
+                        options.put(SERVERINFO_LM_OPTION, serverInfo);
+                    }
+                    if(classLoader != null && !options.containsKey(CLASSLOADER_LM_OPTION)) {
+                        options.put(CLASSLOADER_LM_OPTION, classLoader);
+                    }
+                    JaasLoginModuleConfiguration config = new JaasLoginModuleConfiguration(module.getObjectName(), module.getLoginModuleClass(), flag, options, module.isServerSide());
+                    list.add(config);
+                    ++i;
+                    found = true;
+                    break;
+                }
+            }
+            if(!found) {
+                break;
+            }
+        }
+        config = (JaasLoginModuleConfiguration[]) list.toArray(new JaasLoginModuleConfiguration[list.size()]);
+    }
+
+
+    public static final GBeanInfo GBEAN_INFO;
+
+    static {
+        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(GenericSecurityRealm.class);
+
+        infoFactory.addInterface(SecurityRealm.class);
+        infoFactory.addAttribute("realmName", String.class, true);
+        infoFactory.addAttribute("kernel", Kernel.class, false);
+        infoFactory.addAttribute("loginModuleConfiguration", Properties.class, true);
+        infoFactory.addAttribute("classLoader", ClassLoader.class, false);
+        infoFactory.addAttribute("autoMapPrincipalClasses", String.class, true);
+        infoFactory.addAttribute("defaultPrincipal", String.class, true);
+
+        infoFactory.addReference("ServerInfo", ServerInfo.class);
+
+        infoFactory.addOperation("getAppConfigurationEntries", new Class[0]);
+        infoFactory.addOperation("obtainDefaultPrincipal", new Class[0]);
+        infoFactory.addOperation("obtainRolePrincipalClasses", new Class[0]);
+
+        infoFactory.setConstructor(new String[]{"realmName","kernel","ServerInfo","loginModuleConfiguration","classLoader"});
+
+        GBEAN_INFO = infoFactory.getBeanInfo();
+    }
+
+    public static GBeanInfo getGBeanInfo() {
+        return GBEAN_INFO;
+    }
+}

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/SecurityRealm.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/SecurityRealm.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/SecurityRealm.java	Fri Nov 19 23:38:55 2004
@@ -22,6 +22,7 @@
 import java.util.Set;
 
 import org.apache.geronimo.common.GeronimoSecurityException;
+import org.apache.geronimo.security.jaas.JaasLoginModuleConfiguration;
 import org.apache.regexp.RE;
 
 
@@ -34,11 +35,7 @@
 
     public String getRealmName();
 
-    public long getMaxLoginModuleAge();
-
-    public AppConfigurationEntry[] getAppConfigurationEntries();
-
-    public boolean isLoginModuleLocal();
+    public JaasLoginModuleConfiguration[] getAppConfigurationEntries();
 
     /**
      * @deprecated Will be removed in favor of (some kind of realm editor object) in
@@ -63,12 +60,4 @@
      *             a future milestone release.
      */
     public Set getUserPrincipals(RE regexExpression) throws GeronimoSecurityException;
-
-    /**
-     * @deprecated Will be removed a future milestone release.  The refreshing should
-     *             be done by a login module or editor when appropriate to its own
-     *             needs.
-     */
-    public void refresh() throws GeronimoSecurityException;
-
 }

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PropertiesFileLoginModule.java	Fri Nov 19 23:38:55 2004
@@ -18,13 +18,14 @@
 package org.apache.geronimo.security.realm.providers;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Set;
 import java.util.Properties;
-import java.util.HashSet;
-import java.net.URI;
+import java.util.Set;
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
@@ -33,33 +34,60 @@
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
-
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.geronimo.common.GeronimoSecurityException;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.security.realm.GenericSecurityRealm;
+import org.apache.geronimo.system.serverinfo.ServerInfo;
 
 
 /**
+ * A LoginModule that reads a list of users and group from files on disk.  The
+ * files should be formatted using standard Java properties syntax.  Expects
+ * to be run by a GenericSecurityRealm (doesn't work on its own).
+ *
  * @version $Rev$ $Date$
  */
 public class PropertiesFileLoginModule implements LoginModule {
+    public final static String USERS_URI = "usersURI";
+    public final static String GROUPS_URI = "groupsURI";
+    private static Log log = LogFactory.getLog(PropertiesFileLoginModule.class);
     final Properties users = new Properties();
     final Properties groups = new Properties();
+
     Subject subject;
     CallbackHandler handler;
     String username;
     String password;
 
     public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+        this.subject = subject;
+        this.handler = callbackHandler;
+        try {
+            Kernel kernel = Kernel.getKernel((String)options.get(GenericSecurityRealm.KERNEL_LM_OPTION));
+            ServerInfo serverInfo = (ServerInfo) options.get(GenericSecurityRealm.SERVERINFO_LM_OPTION);
+            URI usersURI = new URI((String)options.get(USERS_URI));
+            URI groupsURI = new URI((String)options.get(GROUPS_URI));
+            loadProperties(kernel, serverInfo, usersURI, groupsURI);
+        } catch (Exception e) {
+            log.error(e);
+            throw new IllegalArgumentException("Unable to configure properties file login module: "+e);
+        }
+    }
 
-        URI usersURI = (URI) options.get(PropertiesFileSecurityRealm.USERS_URI);
-        URI groupsURI = (URI) options.get(PropertiesFileSecurityRealm.GROUPS_URI);
-        assert usersURI != null;
-        assert groupsURI != null;
-
+    public void loadProperties(Kernel kernel, ServerInfo serverInfo, URI userURI, URI groupURI) throws GeronimoSecurityException {
         try {
-            users.load(usersURI.toURL().openStream());
+            URI userFile = serverInfo.resolve(userURI);
+            URI groupFile = serverInfo.resolve(groupURI);
+            InputStream stream = userFile.toURL().openStream();
+            users.load(stream);
+            stream.close();
 
             Properties temp = new Properties();
-            temp.load(groupsURI.toURL().openStream());
+            stream = groupFile.toURL().openStream();
+            temp.load(stream);
+            stream.close();
 
             Enumeration e = temp.keys();
             while (e.hasMoreElements()) {
@@ -77,13 +105,12 @@
                 }
             }
 
-        } catch (IOException e) {
+        } catch (Exception e) {
+            log.error("Properties File Login Module - data load failed", e);
             throw new GeronimoSecurityException(e);
         }
-
-        this.subject = subject;
-        this.handler = callbackHandler;
     }
+
 
     public boolean login() throws LoginException {
         Callback[] callbacks = new Callback[2];

Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java	(original)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLLoginModule.java	Fri Nov 19 23:38:55 2004
@@ -28,34 +28,48 @@
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
+import org.apache.geronimo.security.realm.GenericSecurityRealm;
 
 
 /**
+ * A login module that loads security information from a SQL database.  Expects
+ * to be run by a GenericSecurityRealm (doesn't work on its own).
+ *
  * @version $Rev$ $Date$
  */
-
 public class SQLLoginModule implements LoginModule {
-    private Subject subject;
-    private CallbackHandler handler;
-    private String cbUsername;
-    private String cbPassword;
+    public final static String USER_SELECT = "userSelect";
+    public final static String GROUP_SELECT = "groupSelect";
+    public final static String CONNECTION_URL = "jdbcURL";
+    public final static String USER = "jdbcUser";
+    public final static String PASSWORD = "jdbcPassword";
+    public final static String DRIVER = "jdbcDriver";
+    //todo: support JNDI data sources too
     private String connectionURL;
     private Properties properties;
     private Driver driver;
     private String userSelect;
     private String groupSelect;
+
+    private Subject subject;
+    private CallbackHandler handler;
+    private String cbUsername;
+    private String cbPassword;
     private final Set groups = new HashSet();
 
     public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
         this.subject = subject;
         this.handler = callbackHandler;
 
-        connectionURL = (String) options.get(SQLSecurityRealm.CONNECTION_URL);
-        properties = (Properties) options.get(SQLSecurityRealm.PROPERTIES);
-        userSelect = (String) options.get(SQLSecurityRealm.USER_SELECT);
-        groupSelect = (String) options.get(SQLSecurityRealm.GROUP_SELECT);
+        connectionURL = (String) options.get(CONNECTION_URL);
+        properties = new Properties();
+        properties.put("user", options.get(USER));
+        properties.put("password", options.get(PASSWORD));
+        userSelect = (String) options.get(USER_SELECT);
+        groupSelect = (String) options.get(GROUP_SELECT);
+        ClassLoader cl = (ClassLoader) options.get(GenericSecurityRealm.CLASSLOADER_LM_OPTION);
         try {
-            this.driver = (Driver) Class.forName((String) options.get(SQLSecurityRealm.DRIVER)).newInstance();
+            this.driver = (Driver) cl.loadClass((String) options.get(DRIVER)).newInstance();
         } catch (ClassNotFoundException e) {
             throw new IllegalArgumentException("Driver class "+driver+" is not available.  Perhaps you need to add it as a dependency in your deployment plan?");
         } catch(Exception e) {

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/AbstractTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/AbstractTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/AbstractTest.java	Fri Nov 19 23:38:55 2004
@@ -27,12 +27,13 @@
 import java.io.IOException;
 import java.net.URI;
 import java.util.Collections;
+import java.util.Properties;
 
 import junit.framework.TestCase;
 
 import org.apache.geronimo.gbean.jmx.GBeanMBean;
 import org.apache.geronimo.kernel.Kernel;
-import org.apache.geronimo.security.bridge.TestRealm;
+import org.apache.geronimo.security.bridge.TestLoginModule;
 
 
 /**
@@ -41,6 +42,7 @@
 public abstract class AbstractTest extends TestCase {
     protected Kernel kernel;
     protected ObjectName loginService;
+    protected ObjectName testLoginModule;
     protected ObjectName testRealm;
     protected ObjectName subsystemRouter;
     protected ObjectName asyncTransport;
@@ -63,11 +65,18 @@
         gbean.setAttribute("password", "secret");
         kernel.loadGBean(loginService, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.bridge.TestRealm");
-        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=testrealm");
-        gbean.setAttribute("realmName", TestRealm.REALM_NAME);
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("debug", new Boolean(true));
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        testLoginModule = new ObjectName("geronimo.security:type=LoginModule,name=TestModule");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.bridge.TestLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        kernel.loadGBean(testLoginModule, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
+        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm="+TestLoginModule.REALM_NAME);
+        gbean.setAttribute("realmName", TestLoginModule.REALM_NAME);
+        Properties props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=TestModule");
+        gbean.setAttribute("loginModuleConfiguration", props);
         kernel.loadGBean(testRealm, gbean);
 
         gbean = new GBeanMBean("org.apache.geronimo.remoting.router.SubsystemRouter");
@@ -91,6 +100,7 @@
         kernel.loadGBean(serverStub, gbean);
 
         kernel.startGBean(loginService);
+        kernel.startGBean(testLoginModule);
         kernel.startGBean(testRealm);
         kernel.startGBean(subsystemRouter);
         kernel.startGBean(asyncTransport);
@@ -108,6 +118,7 @@
 
         kernel.unloadGBean(loginService);
         kernel.unloadGBean(testRealm);
+        kernel.unloadGBean(testLoginModule);
         kernel.unloadGBean(subsystemRouter);
         kernel.unloadGBean(asyncTransport);
         kernel.unloadGBean(jmxRouter);

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/CallerIdentityUserPasswordBridgeTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/CallerIdentityUserPasswordBridgeTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/CallerIdentityUserPasswordBridgeTest.java	Fri Nov 19 23:38:55 2004
@@ -37,7 +37,7 @@
     protected void setUp() throws Exception {
         super.setUp();
         bridge = new CallerIdentityUserPasswordRealmBridge();
-        bridge.setTargetRealm(TestRealm.JAAS_NAME);
+        bridge.setTargetRealm(TestLoginModule.JAAS_NAME);
     }
 
     public void testCallerIdentityBridge() throws Exception {

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/ConfiguredIdentityUserPasswordBridgeTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/ConfiguredIdentityUserPasswordBridgeTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/ConfiguredIdentityUserPasswordBridgeTest.java	Fri Nov 19 23:38:55 2004
@@ -33,7 +33,7 @@
 
     protected void setUp() throws Exception {
         super.setUp();
-        bridge = new ConfiguredIdentityUserPasswordRealmBridge(TestRealm.JAAS_NAME, AbstractBridgeTest.USER, AbstractBridgeTest.PASSWORD);
+        bridge = new ConfiguredIdentityUserPasswordRealmBridge(TestLoginModule.JAAS_NAME, AbstractBridgeTest.USER, AbstractBridgeTest.PASSWORD);
     }
 
     public void testConfiguredIdentityBridge() throws Exception {

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/MappingUserPasswordBridgeTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/MappingUserPasswordBridgeTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/MappingUserPasswordBridgeTest.java	Fri Nov 19 23:38:55 2004
@@ -43,7 +43,7 @@
     protected void setUp() throws Exception {
         super.setUp();
         bridge = new TestMappingBridge();
-        bridge.setTargetRealm(TestRealm.JAAS_NAME);
+        bridge.setTargetRealm(TestLoginModule.JAAS_NAME);
         bridge.setPrincipalSourceType(TestPrincipalPrincipal.class);
         bridge.setPrincipalTargetCallbackName("Resource Principal");
         Map principalMap = new HashMap();

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestLoginModule.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestLoginModule.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestLoginModule.java	Fri Nov 19 23:38:55 2004
@@ -36,6 +36,8 @@
  * @version $Rev$ $Date$
  */
 public class TestLoginModule implements LoginModule {
+    public final static String REALM_NAME = "bridge-realm";
+    public final static String JAAS_NAME = "bridge";
 
     private Subject subject;
     private CallbackHandler callbackHandler;

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/ConfigurationEntryTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/ConfigurationEntryTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/ConfigurationEntryTest.java	Fri Nov 19 23:38:55 2004
@@ -46,6 +46,7 @@
     protected ObjectName serverInfo;
     protected ObjectName loginConfiguration;
     protected ObjectName loginService;
+    protected ObjectName clientCE;
     protected ObjectName testCE;
     protected ObjectName testRealm;
     protected ObjectName subsystemRouter;
@@ -54,7 +55,7 @@
     protected ObjectName serverStub;
 
     public void test() throws Exception {
-        LoginContext context = new LoginContext("properties", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
+        LoginContext context = new LoginContext("properties-client", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
 
         context.login();
         Subject subject = context.getSubject();
@@ -104,20 +105,28 @@
         gbean.setAttribute("password", "secret");
         kernel.loadGBean(loginService, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.ConfigurationEntryRealmLocal");
-        testCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties");
-        gbean.setAttribute("applicationConfigName", "properties");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.ServerRealmConfigurationEntry");
+        clientCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties-client");
+        gbean.setAttribute("applicationConfigName", "properties-client");
         gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("controlFlag", LoginModuleControlFlag.REQUIRED);
-        gbean.setAttribute("options", new Properties());
+        kernel.loadGBean(clientCE, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        testCE = new ObjectName("geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        Properties props = new Properties();
+        props.put("usersURI", new File(new File("."), "src/test-data/data/users.properties").toString());
+        props.put("groupsURI", new File(new File("."), "src/test-data/data/groups.properties").toString());
+        gbean.setAttribute("options", props);
         kernel.loadGBean(testCE, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
         testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
         gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("usersURI", (new File(new File("."), "src/test-data/data/users.properties")).toURI());
-        gbean.setAttribute("groupsURI", (new File(new File("."), "src/test-data/data/groups.properties")).toURI());
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleConfiguration", props);
         gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
         kernel.loadGBean(testRealm, gbean);
 
@@ -143,6 +152,7 @@
 
         kernel.startGBean(loginConfiguration);
         kernel.startGBean(loginService);
+        kernel.startGBean(clientCE);
         kernel.startGBean(testCE);
         kernel.startGBean(testRealm);
         kernel.startGBean(subsystemRouter);
@@ -158,6 +168,7 @@
         kernel.stopGBean(subsystemRouter);
         kernel.stopGBean(testRealm);
         kernel.stopGBean(testCE);
+        kernel.stopGBean(clientCE);
         kernel.stopGBean(loginService);
         kernel.stopGBean(loginConfiguration);
         kernel.stopGBean(serverInfo);
@@ -165,6 +176,7 @@
         kernel.unloadGBean(loginService);
         kernel.unloadGBean(testCE);
         kernel.unloadGBean(testRealm);
+        kernel.unloadGBean(clientCE);
         kernel.unloadGBean(subsystemRouter);
         kernel.unloadGBean(asyncTransport);
         kernel.unloadGBean(jmxRouter);

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosNonGeronimoTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosNonGeronimoTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosNonGeronimoTest.java	Fri Nov 19 23:38:55 2004
@@ -22,6 +22,7 @@
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import java.util.Properties;
+import java.util.Collections;
 
 import org.apache.geronimo.gbean.jmx.GBeanMBean;
 import org.apache.geronimo.security.AbstractTest;
@@ -40,6 +41,7 @@
 public class LoginKerberosNonGeronimoTest extends AbstractTest {
 
     protected ObjectName kerberosCE;
+    protected ObjectName kerberosLM;
     protected ObjectName loginConfiguration;
 
     /**
@@ -56,20 +58,26 @@
         loginConfiguration = new ObjectName("geronimo.security:type=LoginConfiguration");
         kernel.loadGBean(loginConfiguration, gbean);
 
-        Properties options = new Properties();
-        options.put("debug", "true");
-        options.put("useTicketCache", "true");
-        options.put("doNotPrompt", "true");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        kerberosLM = new ObjectName("geronimo.security:type=LoginModule,name=TOOLAZYDOGS.COM");
+        gbean.setAttribute("loginModuleClass", "com.sun.security.auth.module.Krb5LoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true)); // normally not, but in this case, it's treated as server-side
+        Properties props = new Properties();
+        props.put("debug", "true");
+        props.put("useTicketCache", "true");
+        props.put("doNotPrompt", "true");
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(kerberosLM, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.ConfigurationEntryLocal");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.DirectConfigurationEntry");
         kerberosCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=kerberos-foobar");
         gbean.setAttribute("applicationConfigName", "kerberos-foobar");
-        gbean.setAttribute("loginModuleName", "com.sun.security.auth.module.Krb5LoginModule");
         gbean.setAttribute("controlFlag", LoginModuleControlFlag.REQUIRED);
-        gbean.setAttribute("options", options);
+        gbean.setReferencePatterns("Module", Collections.singleton(kerberosLM));
         kernel.loadGBean(kerberosCE, gbean);
 
         kernel.startGBean(loginConfiguration);
+        kernel.startGBean(kerberosLM);
         kernel.startGBean(kerberosCE);
     }
 
@@ -81,9 +89,11 @@
      */
     public void tearDown() throws Exception {
         kernel.stopGBean(kerberosCE);
+        kernel.stopGBean(kerberosLM);
         kernel.stopGBean(loginConfiguration);
 
         kernel.unloadGBean(kerberosCE);
+        kernel.unloadGBean(kerberosLM);
         kernel.unloadGBean(loginConfiguration);
 
         super.tearDown();
@@ -111,6 +121,7 @@
 
             context.logout();
         } catch (LoginException e) {
+            e.printStackTrace();
             // May not have kerberos
         }
     }

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginKerberosTest.java	Fri Nov 19 23:38:55 2004
@@ -17,6 +17,7 @@
 
 package org.apache.geronimo.security.jaas;
 
+import java.util.Properties;
 import javax.management.ObjectName;
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
@@ -34,42 +35,56 @@
 public class LoginKerberosTest extends AbstractTest {
 
     protected ObjectName kerberosRealm;
-    protected ObjectName kerberosCE;
+    protected ObjectName kerberosLM;
 
     public void setUp() throws Exception {
         super.setUp();
 
-        GBeanMBean gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.KerberosSecurityRealm");
+        GBeanMBean gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        kerberosLM = new ObjectName("geronimo.security:type=LoginModule,name=TOOLAZYDOGS.COM");
+        gbean.setAttribute("loginModuleClass", "com.sun.security.auth.module.Krb5LoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true)); // normally not, but in this case, it's treated as server-side
+        Properties props = new Properties();
+        props.put("debug", "true");
+        props.put("useTicketCache", "true");
+        props.put("doNotPrompt", "true");
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(kerberosLM, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
         kerberosRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=TOOLAZYDOGS.COM");
         gbean.setAttribute("realmName", "TOOLAZYDOGS.COM");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("debug", new Boolean(true));
-        gbean.setAttribute("useTicketCache", new Boolean(true));
-        gbean.setAttribute("doNotPrompt", new Boolean(true));
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=TOOLAZYDOGS.COM");
+        gbean.setAttribute("loginModuleConfiguration", props);
         kernel.loadGBean(kerberosRealm, gbean);
+        kernel.startGBean(kerberosLM);
         kernel.startGBean(kerberosRealm);
     }
 
     public void tearDown() throws Exception {
         kernel.stopGBean(kerberosRealm);
         kernel.unloadGBean(kerberosRealm);
+        kernel.stopGBean(kerberosLM);
+        kernel.unloadGBean(kerberosLM);
 
         super.tearDown();
     }
 
-    public void testNothing() throws Exception { }
-
-    public void XtestLogin() throws Exception {
+    public void testLogin() throws Exception {
         try {
             LoginContext context = new LoginContext("kerberos-local");
 
             context.login();
             Subject subject = context.getSubject();
 
-            assertTrue("expected non-null subject", subject != null);
-            assertTrue("id of subject should be non-null", ContextManager.getSubjectId(subject) != null);
-            assertEquals("subject should have two principals", 2, subject.getPrincipals().size());
-            assertEquals("subject should have one realm principal", 1, subject.getPrincipals(RealmPrincipal.class).size());
+            assertTrue("expected non-null client-side subject", subject != null);
+            subject = ContextManager.getServerSideSubject(subject);
+
+            assertTrue("expected non-null server-side subject", subject != null);
+            assertTrue("id of server-side subject should be non-null", ContextManager.getSubjectId(subject) != null);
+            assertEquals("server-side subject should have two principals", 2, subject.getPrincipals().size());
+            assertEquals("server-side subject should have one realm principal", 1, subject.getPrincipals(RealmPrincipal.class).size());
             RealmPrincipal principal = (RealmPrincipal) subject.getPrincipals(RealmPrincipal.class).iterator().next();
             assertTrue("id of principal should be non-zero", principal.getId() != 0);
 
@@ -77,6 +92,7 @@
 
             assertTrue("id of subject should be null", ContextManager.getSubjectId(subject) == null);
         } catch (LoginException e) {
+            e.printStackTrace();
             // May not have kerberos
         }
     }

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginPropertiesFileTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginPropertiesFileTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginPropertiesFileTest.java	Fri Nov 19 23:38:55 2004
@@ -40,8 +40,10 @@
 
     protected ObjectName serverInfo;
     protected ObjectName loginConfiguration;
-    protected ObjectName propertiesRealm;
-    protected ObjectName propertiesCE;
+    protected ObjectName clientLM;
+    protected ObjectName clientCE;
+    protected ObjectName testCE;
+    protected ObjectName testRealm;
 
     public void setUp() throws Exception {
         super.setUp();
@@ -58,36 +60,62 @@
         loginConfiguration = new ObjectName("geronimo.security:type=LoginConfiguration");
         kernel.loadGBean(loginConfiguration, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
-        propertiesRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
-        gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("usersURI", (new File(new File("."), "src/test-data/data/users.properties")).toURI());
-        gbean.setAttribute("groupsURI", (new File(new File("."), "src/test-data/data/groups.properties")).toURI());
-        gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
-        kernel.loadGBean(propertiesRealm, gbean);
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        clientLM = new ObjectName("geronimo.security:type=LoginModule,name=properties-client");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.jaas.JaasLoginCoordinator");
+        gbean.setAttribute("serverSide", new Boolean(false));
+        Properties props = new Properties();
+        props.put("host", "localhost");
+        props.put("port", "4242");
+        props.put("realm", "properties-realm");
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(clientLM, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.DirectConfigurationEntry");
+        clientCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties-client");
+        gbean.setAttribute("applicationConfigName", "properties-client");
+        gbean.setAttribute("controlFlag", LoginModuleControlFlag.REQUIRED);
+        gbean.setReferencePatterns("Module", Collections.singleton(clientLM));
+        kernel.loadGBean(clientCE, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.ConfigurationEntryRealmLocal");
-        propertiesCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties");
-        gbean.setAttribute("applicationConfigName", "properties");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        testCE = new ObjectName("geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        props = new Properties();
+        props.put("usersURI", new File(new File("."), "src/test-data/data/users.properties").toString());
+        props.put("groupsURI", new File(new File("."), "src/test-data/data/groups.properties").toString());
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(testCE, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
+        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
         gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("controlFlag", LoginModuleControlFlag.REQUIRED);
-        gbean.setAttribute("options", new Properties());
-        kernel.loadGBean(propertiesCE, gbean);
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleConfiguration", props);
+        gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
+        kernel.loadGBean(testRealm, gbean);
 
         kernel.startGBean(loginConfiguration);
-        kernel.startGBean(propertiesRealm);
-        kernel.startGBean(propertiesCE);
+        kernel.startGBean(clientLM);
+        kernel.startGBean(clientCE);
+        kernel.startGBean(testCE);
+        kernel.startGBean(testRealm);
     }
 
     public void tearDown() throws Exception {
-        kernel.stopGBean(propertiesCE);
-        kernel.stopGBean(propertiesRealm);
+        kernel.stopGBean(testRealm);
+        kernel.stopGBean(testCE);
+        kernel.stopGBean(clientCE);
+        kernel.stopGBean(clientLM);
         kernel.stopGBean(loginConfiguration);
         kernel.stopGBean(serverInfo);
 
-        kernel.unloadGBean(propertiesRealm);
-        kernel.unloadGBean(propertiesCE);
+        kernel.unloadGBean(testCE);
+        kernel.unloadGBean(testRealm);
+        kernel.unloadGBean(clientCE);
+        kernel.unloadGBean(clientLM);
         kernel.unloadGBean(loginConfiguration);
         kernel.unloadGBean(serverInfo);
 
@@ -96,7 +124,7 @@
 
     public void testLogin() throws Exception {
 
-        LoginContext context = new LoginContext("properties", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
+        LoginContext context = new LoginContext("properties-client", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
 
         context.login();
         Subject subject = context.getSubject();

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginSQLTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginSQLTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/LoginSQLTest.java	Fri Nov 19 23:38:55 2004
@@ -20,6 +20,9 @@
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
+import java.util.Properties;
+import java.util.Collections;
+import java.io.File;
 import javax.management.ObjectName;
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginContext;
@@ -28,6 +31,7 @@
 import org.apache.geronimo.security.AbstractTest;
 import org.apache.geronimo.security.IdentificationPrincipal;
 import org.apache.geronimo.security.RealmPrincipal;
+import org.apache.geronimo.security.ContextManager;
 import org.apache.geronimo.kernel.management.State;
 
 
@@ -38,6 +42,7 @@
 
     private static final String hsqldbURL = "jdbc:hsqldb:target/database/LoginSQLTest";
     protected ObjectName sqlRealm;
+    protected ObjectName sqlModule;
 
     public void setUp() throws Exception {
         super.setUp();
@@ -76,23 +81,37 @@
 
         conn.close();
 
-        GBeanMBean gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.SQLSecurityRealm");
+        GBeanMBean gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        sqlModule = new ObjectName("geronimo.security:type=LoginModule,name=sql");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.SQLLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        Properties props = new Properties();
+        props.put("jdbcURL", hsqldbURL);
+        props.put("jdbcDriver", "org.hsqldb.jdbcDriver");
+        props.put("jdbcUser", "loginmodule");
+        props.put("jdbcPassword", "password");
+        props.put("userSelect", "SELECT UserName, Password FROM Users");
+        props.put("groupSelect", "SELECT GroupName, UserName FROM Groups");
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(sqlModule, gbean);
+        kernel.startGBean(sqlModule);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
         sqlRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=sql-realm");
         gbean.setAttribute("realmName", "sql-realm");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("connectionURL", hsqldbURL);
-        gbean.setAttribute("driver","org.hsqldb.jdbcDriver");
-        gbean.setAttribute("user", "loginmodule");
-        gbean.setAttribute("password", "password");
-        gbean.setAttribute("userSelect", "SELECT UserName, Password FROM Users");
-        gbean.setAttribute("groupSelect", "SELECT GroupName, UserName FROM Groups");
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=sql");
+        gbean.setAttribute("loginModuleConfiguration", props);
         kernel.loadGBean(sqlRealm, gbean);
         kernel.startGBean(sqlRealm);
+
     }
 
     public void tearDown() throws Exception {
         kernel.stopGBean(sqlRealm);
+        kernel.stopGBean(sqlModule);
         kernel.unloadGBean(sqlRealm);
+        kernel.unloadGBean(sqlModule);
 
         super.tearDown();
 
@@ -109,102 +128,21 @@
 
     }
 
-    public void testNothing() {
-    }
-
     public void testLogin() throws Exception {
         LoginContext context = new LoginContext("sql", new UsernamePasswordCallback("alan", "starcraft"));
 
         context.login();
         Subject subject = context.getSubject();
+        assertTrue("expected non-null client-side subject", subject != null);
+        subject = ContextManager.getServerSideSubject(subject);
 
-        assertTrue("expected non-null subject", subject != null);
-//        assertEquals("subject should have five principal", 5, subject.getPrincipals().size());
-//        assertEquals("subject should have two realm principals", 2, subject.getPrincipals(RealmPrincipal.class).size());
-//        assertEquals("subject should have one remote principal", 1, subject.getPrincipals(IdentificationPrincipal.class).size());
-        IdentificationPrincipal principal = (IdentificationPrincipal) subject.getPrincipals(IdentificationPrincipal.class).iterator().next();
-        assertTrue("id of principal should be non-zero", principal.getId().getSubjectId().longValue() != 0);
-
-        context.logout();
-    }
-
-    public void XtestLogoutTimeout() throws Exception {
-
-        assertEquals(new Integer(State.RUNNING_INDEX), kernel.getAttribute(sqlRealm, "state"));
-
-        ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-            LoginContext context = new LoginContext("sql", new UsernamePasswordCallback("alan", "starcraft"));
-
-            context.login();
-            Subject subject = context.getSubject();
-
-            assertTrue("expected non-null subject", subject != null);
-            assertEquals("subject should have five principal", 5, subject.getPrincipals().size());
-            assertEquals("subject should have two realm principals", 2, subject.getPrincipals(RealmPrincipal.class).size());
-            assertEquals("subject should have one remote principal", 1, subject.getPrincipals(IdentificationPrincipal.class).size());
-            IdentificationPrincipal principal = (IdentificationPrincipal) subject.getPrincipals(IdentificationPrincipal.class).iterator().next();
-            assertTrue("id of principal should be non-zero", principal.getId().getSubjectId().longValue() != 0);
-
-            Thread.sleep(20 * 1000);
-
-            try {
-                context.logout();
-                fail("The login module should have expired");
-            } catch (ExpiredLoginModuleException e) {
-                context.login();
-
-                subject = context.getSubject();
-
-                assertTrue("expected non-null subject", subject != null);
-                assertEquals("subject should have five principal", 5, subject.getPrincipals().size());
-                assertEquals("subject should have two realm principals", 2, subject.getPrincipals(RealmPrincipal.class).size());
-                assertEquals("subject should have one remote principal", 1, subject.getPrincipals(IdentificationPrincipal.class).size());
-                principal = (IdentificationPrincipal) subject.getPrincipals(IdentificationPrincipal.class).iterator().next();
-                assertTrue("id of principal should be non-zero", principal.getId().getSubjectId().longValue() != 0);
-
-                context.logout();
-            }
-        } finally {
-            Thread.currentThread().setContextClassLoader(oldCl);
-        }
-    }
-
-    public void XtestReloginTimeout() throws Exception {
-        LoginContext context = new LoginContext("sql", new UsernamePasswordCallback("alan", "starcraft"));
-
-        context.login();
-        Subject subject = context.getSubject();
-
-        assertTrue("expected non-null subject", subject != null);
-        assertEquals("subject should have five principal", 5, subject.getPrincipals().size());
-        assertEquals("subject should have two realm principals", 2, subject.getPrincipals(RealmPrincipal.class).size());
-        assertEquals("subject should have one remote principal", 1, subject.getPrincipals(IdentificationPrincipal.class).size());
+        assertTrue("expected non-null server-side subject", subject != null);
+        assertEquals("server-side subject should have five principal", 5, subject.getPrincipals().size());
+        assertEquals("server-side subject should have two realm principals", 2, subject.getPrincipals(RealmPrincipal.class).size());
+        assertEquals("server-side subject should have one remote principal", 1, subject.getPrincipals(IdentificationPrincipal.class).size());
         IdentificationPrincipal principal = (IdentificationPrincipal) subject.getPrincipals(IdentificationPrincipal.class).iterator().next();
         assertTrue("id of principal should be non-zero", principal.getId().getSubjectId().longValue() != 0);
 
         context.logout();
-        context.login();
-        context.logout();
-
-        // Waiting this long should cause the login module w/ an artificially
-        // low age limit to expire.  The next call to login should automatically
-        // create a new one.
-        Thread.sleep(4 * 1000);
-
-        context.login();
-
-        subject = context.getSubject();
-
-        assertTrue("expected non-null subject", subject != null);
-        assertEquals("subject should have five principal", 5, subject.getPrincipals().size());
-        assertEquals("subject should have two realm principals", 2, subject.getPrincipals(RealmPrincipal.class).size());
-        assertEquals("subject should have one remote principal", 1, subject.getPrincipals(IdentificationPrincipal.class).size());
-        principal = (IdentificationPrincipal) subject.getPrincipals(IdentificationPrincipal.class).iterator().next();
-        assertTrue("id of principal should be non-zero", principal.getId().getSubjectId().longValue() != 0);
-
-        context.logout();
     }
-
 }

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/TimeoutTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/TimeoutTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/jaas/TimeoutTest.java	Fri Nov 19 23:38:55 2004
@@ -31,7 +31,7 @@
 import org.apache.geronimo.security.ContextManager;
 import org.apache.geronimo.security.IdentificationPrincipal;
 import org.apache.geronimo.security.RealmPrincipal;
-import org.apache.geronimo.security.bridge.TestRealm;
+import org.apache.geronimo.security.bridge.TestLoginModule;
 import org.apache.geronimo.system.serverinfo.ServerInfo;
 import org.apache.geronimo.kernel.Kernel;
 
@@ -43,8 +43,10 @@
 
     protected ObjectName serverInfo;
     protected ObjectName loginConfiguration;
-    protected ObjectName propertiesRealm;
-    protected ObjectName propertiesCE;
+    protected ObjectName testCE;
+    protected ObjectName testRealm;
+    protected ObjectName clientLM;
+    protected ObjectName clientCE;
 
     public void setUp() throws Exception {
         kernel = new Kernel("test.kernel", "simple.geronimo.test");
@@ -63,13 +65,6 @@
         gbean.setAttribute("password", "secret");
         kernel.loadGBean(loginService, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.bridge.TestRealm");
-        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=testrealm");
-        gbean.setAttribute("realmName", TestRealm.REALM_NAME);
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("debug", new Boolean(true));
-        kernel.loadGBean(testRealm, gbean);
-
         gbean = new GBeanMBean("org.apache.geronimo.remoting.router.SubsystemRouter");
         subsystemRouter = new ObjectName("geronimo.remoting:router=SubsystemRouter");
         kernel.loadGBean(subsystemRouter, gbean);
@@ -91,7 +86,6 @@
         kernel.loadGBean(serverStub, gbean);
 
         kernel.startGBean(loginService);
-        kernel.startGBean(testRealm);
         kernel.startGBean(subsystemRouter);
         kernel.startGBean(asyncTransport);
         kernel.startGBean(jmxRouter);
@@ -107,36 +101,62 @@
         loginConfiguration = new ObjectName("geronimo.security:type=LoginConfiguration");
         kernel.loadGBean(loginConfiguration, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
-        propertiesRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        testCE = new ObjectName("geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        Properties props = new Properties();
+        props.put("usersURI", new File(new File("."), "src/test-data/data/users.properties").toString());
+        props.put("groupsURI", new File(new File("."), "src/test-data/data/groups.properties").toString());
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(testCE, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
+        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
         gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("usersURI", (new File(new File("."), "src/test-data/data/users.properties")).toURI());
-        gbean.setAttribute("groupsURI", (new File(new File("."), "src/test-data/data/groups.properties")).toURI());
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleConfiguration", props);
         gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
-        kernel.loadGBean(propertiesRealm, gbean);
+        kernel.loadGBean(testRealm, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.ConfigurationEntryRealmLocal");
-        propertiesCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties");
-        gbean.setAttribute("applicationConfigName", "properties");
-        gbean.setAttribute("realmName", "properties-realm");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        clientLM = new ObjectName("geronimo.security:type=LoginModule,name=properties-client");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.jaas.JaasLoginCoordinator");
+        gbean.setAttribute("serverSide", new Boolean(false));
+        props = new Properties();
+        props.put("host", "localhost");
+        props.put("port", "4242");
+        props.put("realm", "properties-realm");
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(clientLM, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.DirectConfigurationEntry");
+        clientCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties-client");
+        gbean.setAttribute("applicationConfigName", "properties-client");
         gbean.setAttribute("controlFlag", LoginModuleControlFlag.REQUIRED);
-        gbean.setAttribute("options", new Properties());
-        kernel.loadGBean(propertiesCE, gbean);
+        gbean.setReferencePatterns("Module", Collections.singleton(clientLM));
+        kernel.loadGBean(clientCE, gbean);
 
         kernel.startGBean(loginConfiguration);
-        kernel.startGBean(propertiesRealm);
-        kernel.startGBean(propertiesCE);
+        kernel.startGBean(clientLM);
+        kernel.startGBean(clientCE);
+        kernel.startGBean(testCE);
+        kernel.startGBean(testRealm);
     }
 
     public void tearDown() throws Exception {
-        kernel.stopGBean(propertiesCE);
-        kernel.stopGBean(propertiesRealm);
+        kernel.stopGBean(testRealm);
+        kernel.stopGBean(testCE);
+        kernel.stopGBean(clientCE);
+        kernel.stopGBean(clientLM);
         kernel.stopGBean(loginConfiguration);
         kernel.stopGBean(serverInfo);
 
-        kernel.unloadGBean(propertiesRealm);
-        kernel.unloadGBean(propertiesCE);
+        kernel.unloadGBean(testCE);
+        kernel.unloadGBean(testRealm);
+        kernel.unloadGBean(clientCE);
+        kernel.unloadGBean(clientLM);
         kernel.unloadGBean(loginConfiguration);
         kernel.unloadGBean(serverInfo);
 
@@ -144,11 +164,9 @@
         kernel.stopGBean(jmxRouter);
         kernel.stopGBean(asyncTransport);
         kernel.stopGBean(subsystemRouter);
-        kernel.stopGBean(testRealm);
         kernel.stopGBean(loginService);
 
         kernel.unloadGBean(loginService);
-        kernel.unloadGBean(testRealm);
         kernel.unloadGBean(subsystemRouter);
         kernel.unloadGBean(asyncTransport);
         kernel.unloadGBean(jmxRouter);
@@ -159,7 +177,7 @@
 
     public void testTimeout() throws Exception {
 
-        LoginContext context = new LoginContext("properties", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
+        LoginContext context = new LoginContext("properties-client", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
 
         context.login();
         Subject subject = context.getSubject();

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/network/protocol/SubjectCarryingProtocolTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/network/protocol/SubjectCarryingProtocolTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/network/protocol/SubjectCarryingProtocolTest.java	Fri Nov 19 23:38:55 2004
@@ -52,6 +52,7 @@
 import org.apache.geronimo.pool.ClockPool;
 import org.apache.geronimo.pool.ThreadPool;
 import org.apache.geronimo.security.AbstractTest;
+import org.apache.geronimo.security.bridge.TestLoginModule;
 import org.apache.geronimo.security.jaas.GeronimoLoginConfiguration;
 import org.apache.geronimo.security.jaas.LoginModuleControlFlag;
 import org.apache.geronimo.system.serverinfo.ServerInfo;
@@ -65,8 +66,8 @@
     final static private Log log = LogFactory.getLog(SubjectCarryingProtocolTest.class);
 
     protected ObjectName serverInfo;
-    protected ObjectName propertiesRealm;
-    protected ObjectName propertiesCE;
+    protected ObjectName testCE;
+    protected ObjectName testRealm;
 
     private Subject clientSubject;
     private Subject serverSubject;
@@ -260,7 +261,7 @@
     }
 
     public void setUp() throws Exception {
-        Configuration.setConfiguration(new GeronimoLoginConfiguration());
+//        Configuration.setConfiguration(new GeronimoLoginConfiguration());
 
         startLatch = new Latch();
         shutdownLatch = new Latch();
@@ -276,25 +277,27 @@
         kernel.loadGBean(serverInfo, gbean);
         kernel.startGBean(serverInfo);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
-        propertiesRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
-        gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("usersURI", (new File(new File("."), "src/test-data/data/users.properties")).toURI());
-        gbean.setAttribute("groupsURI", (new File(new File("."), "src/test-data/data/groups.properties")).toURI());
-        gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
-        kernel.loadGBean(propertiesRealm, gbean);
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        testCE = new ObjectName("geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        Properties props = new Properties();
+        props.put("usersURI", new File(new File("."), "src/test-data/data/users.properties").toString());
+        props.put("groupsURI", new File(new File("."), "src/test-data/data/groups.properties").toString());
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(testCE, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.ConfigurationEntryRealmLocal");
-        propertiesCE = new ObjectName("geronimo.security:type=ConfigurationEntry,jaasId=properties");
-        gbean.setAttribute("applicationConfigName", "properties");
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
+        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
         gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("controlFlag", LoginModuleControlFlag.REQUIRED);
-        gbean.setAttribute("options", new Properties());
-        kernel.loadGBean(propertiesCE, gbean);
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleConfiguration", props);
+        gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
+        kernel.loadGBean(testRealm, gbean);
 
-        kernel.startGBean(propertiesRealm);
-        kernel.startGBean(propertiesCE);
+        kernel.startGBean(testCE);
+        kernel.startGBean(testRealm);
 
         LoginContext context = new LoginContext("properties", new AbstractTest.UsernamePasswordCallback("alan", "starcraft"));
         context.login();
@@ -308,11 +311,11 @@
     }
 
     public void tearDown() throws Exception {
-        kernel.stopGBean(propertiesCE);
-        kernel.stopGBean(propertiesRealm);
+        kernel.stopGBean(testRealm);
+        kernel.stopGBean(testCE);
         kernel.stopGBean(serverInfo);
-        kernel.unloadGBean(propertiesRealm);
-        kernel.unloadGBean(propertiesCE);
+        kernel.unloadGBean(testCE);
+        kernel.unloadGBean(testRealm);
         kernel.unloadGBean(serverInfo);
 
         super.tearDown();

Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/remoting/jmx/RemoteLoginTest.java
==============================================================================
--- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/remoting/jmx/RemoteLoginTest.java	(original)
+++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/remoting/jmx/RemoteLoginTest.java	Fri Nov 19 23:38:55 2004
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.net.URI;
 import java.util.Collections;
+import java.util.Properties;
 import javax.management.ObjectName;
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
@@ -48,7 +49,8 @@
     Kernel kernel;
     ObjectName serverInfo;
     ObjectName loginService;
-    ObjectName kerberosRealm;
+    protected ObjectName testCE;
+    protected ObjectName testRealm;
     ObjectName subsystemRouter;
     ObjectName secureSubsystemRouter;
     ObjectName asyncTransport;
@@ -108,14 +110,24 @@
         gbean.setAttribute("password", "secret");
         kernel.loadGBean(loginService, gbean);
 
-        gbean = new GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
-        kerberosRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
+        gbean = new GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
+        testCE = new ObjectName("geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule");
+        gbean.setAttribute("serverSide", new Boolean(true));
+        Properties props = new Properties();
+        props.put("usersURI", new File(new File("."), "src/test-data/data/users.properties").toString());
+        props.put("groupsURI", new File(new File("."), "src/test-data/data/groups.properties").toString());
+        gbean.setAttribute("options", props);
+        kernel.loadGBean(testCE, gbean);
+
+        gbean = new GBeanMBean("org.apache.geronimo.security.realm.GenericSecurityRealm");
+        testRealm = new ObjectName("geronimo.security:type=SecurityRealm,realm=properties-realm");
         gbean.setAttribute("realmName", "properties-realm");
-        gbean.setAttribute("maxLoginModuleAge", new Long(1 * 1000));
-        gbean.setAttribute("usersURI", (new File(new File("."), "src/test-data/data/users.properties")).toURI());
-        gbean.setAttribute("groupsURI", (new File(new File("."), "src/test-data/data/groups.properties")).toURI());
+        props = new Properties();
+        props.setProperty("LoginModule.1.REQUIRED","geronimo.security:type=LoginModule,name=properties");
+        gbean.setAttribute("loginModuleConfiguration", props);
         gbean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfo));
-        kernel.loadGBean(kerberosRealm, gbean);
+        kernel.loadGBean(testRealm, gbean);
 
         gbean = new GBeanMBean("org.apache.geronimo.remoting.router.SubsystemRouter");
         subsystemRouter = new ObjectName("geronimo.remoting:router=SubsystemRouter");
@@ -159,7 +171,8 @@
         kernel.loadGBean(serverStub, gbean);
 
         kernel.startGBean(loginService);
-        kernel.startGBean(kerberosRealm);
+        kernel.startGBean(testCE);
+        kernel.startGBean(testRealm);
         kernel.startGBean(subsystemRouter);
         kernel.startGBean(secureSubsystemRouter);
         kernel.startGBean(asyncTransport);
@@ -191,12 +204,14 @@
         kernel.stopGBean(asyncTransport);
         kernel.stopGBean(secureSubsystemRouter);
         kernel.stopGBean(subsystemRouter);
-        kernel.stopGBean(kerberosRealm);
+        kernel.stopGBean(testRealm);
+        kernel.stopGBean(testCE);
         kernel.stopGBean(loginService);
         kernel.stopGBean(serverInfo);
 
         kernel.unloadGBean(loginService);
-        kernel.unloadGBean(kerberosRealm);
+        kernel.unloadGBean(testCE);
+        kernel.unloadGBean(testRealm);
         kernel.unloadGBean(subsystemRouter);
         kernel.unloadGBean(secureSubsystemRouter);
         kernel.unloadGBean(asyncTransport);