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);