Author: ammulder Date: Mon Nov 8 00:05:31 2004 New Revision: 56911 Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleConfiguration.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginUtils.java Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/security/PasswordCredentialRealm.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LocalLoginModule.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleCacheObject.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleControlFlag.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginService.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginServiceMBean.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModule.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModuleLocalWrapper.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/SerializableACE.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/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/SimpleSecurityRealm.java geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestRealm.java Log: Initial steps toward support for multiple LoginModules per realms (GERONIMO-424)
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 Mon Nov 8 00:05:31 2004 @@ -68,7 +68,7 @@ public void refresh() throws GeronimoSecurityException { } - public AppConfigurationEntry getAppConfigurationEntry() { + public AppConfigurationEntry[] getAppConfigurationEntries() { Map options = new HashMap(); // TODO: This can be a bad thing, passing a reference to a realm to the login module @@ -77,7 +77,7 @@ AppConfigurationEntry appConfigurationEntry = new AppConfigurationEntry(PasswordCredentialLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUISITE, options); - return appConfigurationEntry; + return new AppConfigurationEntry[]{appConfigurationEntry}; } public boolean isLoginModuleLocal() { Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LocalLoginModule.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LocalLoginModule.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LocalLoginModule.java Mon Nov 8 00:05:31 2004 @@ -64,7 +64,7 @@ loginService = (LoginServiceMBean) MBeanProxyFactory.getProxy(LoginServiceMBean.class, kernel.getMBeanServer(), LoginService.LOGIN_SERVICE); - this.loginModuleId = loginService.allocateLoginModule(realmName); + this.loginModuleId = loginService.allocateLoginModules(realmName); } catch (Exception e) { throw (GeronimoSecurityException) new GeronimoSecurityException("Initialize error: " + e.toString() + "\n").initCause(e); } @@ -77,7 +77,7 @@ return tryLogin(); } catch (ExpiredLoginModuleException ele) { try { - loginModuleId = loginService.allocateLoginModule(realmName); + loginModuleId = loginService.allocateLoginModules(realmName); return tryLogin(); } catch (Exception e) { throw (LoginException) new LoginException().initCause(e); @@ -143,7 +143,7 @@ Collection collection = loginService.getCallbacks(loginModuleId); Callback[] callbacks = new Callback[0]; - callbacks = (Callback[]) collection.toArray(new Callback[]{}); + callbacks = (Callback[]) collection.toArray(new Callback[collection.size()]); try { callbackHandler.handle(callbacks); Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleCacheObject.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleCacheObject.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleCacheObject.java Mon Nov 8 00:05:31 2004 @@ -30,7 +30,7 @@ private final LoginModuleId loginModuleId; private String realmName; private Subject subject; - private LoginModule loginModule; + private LoginModuleConfiguration[] loginModules; private CallbackHandler callbackHandler; private long created; private boolean done; @@ -73,12 +73,12 @@ this.subject = subject; } - LoginModule getLoginModule() { - return loginModule; + LoginModuleConfiguration[] getLoginModules() { + return loginModules; } - void setLoginModule(LoginModule loginModule) { - this.loginModule = loginModule; + void setLoginModules(LoginModuleConfiguration[] loginModules) { + this.loginModules = loginModules; } CallbackHandler getCallbackHandler() { Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleConfiguration.java ============================================================================== --- (empty file) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleConfiguration.java Mon Nov 8 00:05:31 2004 @@ -0,0 +1,26 @@ +package org.apache.geronimo.security.jaas; + +import javax.security.auth.spi.LoginModule; + +/** + * + * + * @version $Revision 1.0 $ + */ +public class LoginModuleConfiguration { + private LoginModule module; + private LoginModuleControlFlag controlFlag; + + public LoginModuleConfiguration(LoginModule module, LoginModuleControlFlag controlFlag) { + this.module = module; + this.controlFlag = controlFlag; + } + + public LoginModule getModule() { + return module; + } + + public LoginModuleControlFlag getControlFlag() { + return controlFlag; + } +} Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleControlFlag.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleControlFlag.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginModuleControlFlag.java Mon Nov 8 00:05:31 2004 @@ -51,4 +51,13 @@ Object readResolve() throws ObjectStreamException { return values[ordinal]; } + + public static LoginModuleControlFlag getInstance(AppConfigurationEntry.LoginModuleControlFlag flag) { + for(int i = 0; i < values.length; i++) { + if(values[i].flag == flag) { + return values[i]; + } + } + return null; + } } Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginService.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginService.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginService.java Mon Nov 8 00:05:31 2004 @@ -31,6 +31,8 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.List; +import java.util.Arrays; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; @@ -144,39 +146,44 @@ this.password = password; } - public SerializableACE getAppConfigurationEntry(String realmName) { + public SerializableACE[] getAppConfigurationEntries(String realmName) { for (Iterator iter = getRealms().iterator(); iter.hasNext();) { SecurityRealm securityRealm = (SecurityRealm) iter.next(); if (realmName.equals(securityRealm.getRealmName())) { - javax.security.auth.login.AppConfigurationEntry entry = securityRealm.getAppConfigurationEntry(); - - HashMap options = new HashMap(); - - options.put(LoginModuleConstants.REALM_NAME, realmName); - options.put(LoginModuleConstants.MODULE, entry.getLoginModuleName()); - - SerializableACE wrapper; - - if (securityRealm.isLoginModuleLocal()) { - wrapper = new SerializableACE("org.apache.geronimo.security.jaas.RemoteLoginModuleLocalWrapper", - SerializableACE.LoginModuleControlFlag.REQUIRED, - options); - - } else { - options.putAll(entry.getOptions()); - wrapper = new SerializableACE("org.apache.geronimo.security.jaas.RemoteLoginModuleRemoteWrapper", - SerializableACE.LoginModuleControlFlag.REQUIRED, - options); + javax.security.auth.login.AppConfigurationEntry[] entries = securityRealm.getAppConfigurationEntries(); + SerializableACE[] results = new SerializableACE[entries.length]; + for(int i = 0; i < entries.length; i++) { + AppConfigurationEntry entry = entries[i]; + + HashMap options = new HashMap(); + + options.put(LoginModuleConstants.REALM_NAME, realmName); + options.put(LoginModuleConstants.MODULE, entry.getLoginModuleName()); + + SerializableACE wrapper; + + if (securityRealm.isLoginModuleLocal()) { + wrapper = new SerializableACE("org.apache.geronimo.security.jaas.RemoteLoginModuleLocalWrapper", + LoginModuleControlFlag.REQUIRED, + options); + + } else { + options.putAll(entry.getOptions()); + wrapper = new SerializableACE("org.apache.geronimo.security.jaas.RemoteLoginModuleRemoteWrapper", + LoginModuleControlFlag.REQUIRED, + options); + } + results[i] = wrapper; } - return wrapper; + return results; } } return null; } - public LoginModuleId allocateLoginModule(String realmName) { + public LoginModuleId allocateLoginModules(String realmName) { LoginModuleCacheObject lm = null; synchronized (LoginService.class) { @@ -185,38 +192,43 @@ SecurityRealm securityRealm = (SecurityRealm) iter.next(); if (realmName.equals(securityRealm.getRealmName())) { - AppConfigurationEntry entry = securityRealm.getAppConfigurationEntry(); - - final String finalClass = entry.getLoginModuleName(); - - LoginModule module = (LoginModule) AccessController.doPrivileged(new java.security.PrivilegedExceptionAction() { - public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException { - return Class.forName(finalClass, true, classLoader).newInstance(); - } - }); + AppConfigurationEntry[] entries = securityRealm.getAppConfigurationEntries(); Subject subject = new Subject(); CallbackProxy callback = new CallbackProxy(); - module.initialize(subject, callback, new HashMap(), entry.getOptions()); + LoginModuleConfiguration[] modules = new LoginModuleConfiguration[entries.length]; + for(int i = 0; i < entries.length; i++) { + AppConfigurationEntry entry = entries[i]; + + final String finalClass = entry.getLoginModuleName(); + + LoginModule module = (LoginModule) AccessController.doPrivileged(new java.security.PrivilegedExceptionAction() { + public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + return Class.forName(finalClass, true, classLoader).newInstance(); + } + }); + module.initialize(subject, callback, new HashMap(), entry.getOptions()); + modules[i] = new LoginModuleConfiguration(module, LoginModuleControlFlag.getInstance(entry.getControlFlag())); + } lm = allocateLoginModuleCacheObject(securityRealm.getMaxLoginModuleAge()); lm.setRealmName(realmName); - lm.setLoginModule(module); + lm.setLoginModules(modules); lm.setSubject(subject); lm.setCallbackHandler(callback); - log.trace("LoginModule [" + lm.getLoginModuleId() + "] created for realm " + realmName); break; } } } catch (Exception e) { + e.printStackTrace(); return null; } } return lm.getLoginModuleId(); } - public void removeLoginModule(LoginModuleId loginModuleId) throws ExpiredLoginModuleException { + public void removeLoginModules(LoginModuleId loginModuleId) throws ExpiredLoginModuleException { LoginModuleCacheObject lm = (LoginModuleCacheObject) loginCache.get(loginModuleId); if (lm == null) throw new ExpiredLoginModuleException(); @@ -224,26 +236,27 @@ log.trace("LoginModule [" + lm.getLoginModuleId() + "] marked done"); } + //todo: this is pretty cheesy public Collection getCallbacks(LoginModuleId loginModuleId) throws ExpiredLoginModuleException { LoginModuleCacheObject lm = (LoginModuleCacheObject) loginCache.get(loginModuleId); if (lm == null) throw new ExpiredLoginModuleException(); - LoginModule module = lm.getLoginModule(); - CallbackProxy callback = (CallbackProxy) lm.getCallbackHandler(); + LoginModuleConfiguration[] modules = lm.getLoginModules(); - try { - module.login(); - } catch (LoginException e) { - } - try { - module.abort(); - } catch (LoginException e) { - } - ArrayList callbacks = new ArrayList(); - for (int i = 0; i < callback.callbacks.length; i++) { - callbacks.add(callback.callbacks[i]); + CallbackProxy proxy = (CallbackProxy) lm.getCallbackHandler(); + proxy.setExploring(); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration module = modules[i]; + try { + module.getModule().login(); + } catch (LoginException e) { + } + try { + module.getModule().abort(); + } catch (LoginException e) { + } } - return callbacks; + return proxy.finalizeCallbackList(); } /** @@ -251,41 +264,55 @@ * that a login module will use and to fill in the reply that a remote * client has provided. */ - class CallbackProxy implements CallbackHandler { - Callback[] callbacks; + static class CallbackProxy implements CallbackHandler { + private List callbacks = new ArrayList(); + private boolean exploring = true; public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - if (this.callbacks == null) { - this.callbacks = callbacks; + if (exploring) { + this.callbacks.addAll(Arrays.asList(callbacks)); throw new UnsupportedCallbackException(callbacks[0], "DO NOT PROCEED WITH THIS LOGIN"); } else { - assert this.callbacks.length == callbacks.length : "Callback lengths should not have changed"; + assert this.callbacks.size() == callbacks.length : "Callback lengths should not have changed"; for (int i = 0; i < callbacks.length; i++) { - callbacks[i] = this.callbacks[i]; + callbacks[i] = (Callback) this.callbacks.get(i); } } } + + public void setExploring() { + exploring = true; + callbacks.clear(); + } + + public List finalizeCallbackList() { + exploring = false; + return callbacks; + } } public boolean login(LoginModuleId loginModuleId, Collection callbacks) throws LoginException { LoginModuleCacheObject lm = (LoginModuleCacheObject) loginCache.get(loginModuleId); if (lm == null) throw new ExpiredLoginModuleException(); - - LoginModule module = lm.getLoginModule(); - + LoginModuleConfiguration[] modules = lm.getLoginModules(); + if(modules.length == 0) { + throw new LoginException("No login modules configured for realm "+lm.getRealmName()); + } CallbackProxy callback = (CallbackProxy) lm.getCallbackHandler(); - callback.callbacks = (Callback[]) callbacks.toArray(new Callback[]{}); - - return module.login(); + callback.callbacks = new ArrayList(callbacks); + return LoginUtils.computeLogin(modules); } public boolean commit(LoginModuleId loginModuleId) throws LoginException { LoginModuleCacheObject lm = (LoginModuleCacheObject) loginCache.get(loginModuleId); if (lm == null) throw new ExpiredLoginModuleException(); - LoginModule module = lm.getLoginModule(); - if (!module.commit()) return false; + LoginModuleConfiguration[] modules = lm.getLoginModules(); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration configuration = modules[i]; + configuration.getModule().commit(); + } Subject subject = lm.getSubject(); RealmPrincipal principal; @@ -310,9 +337,13 @@ LoginModuleCacheObject lm = (LoginModuleCacheObject) loginCache.get(loginModuleId); if (lm == null) throw new ExpiredLoginModuleException(); - LoginModule module = lm.getLoginModule(); + LoginModuleConfiguration[] modules = lm.getLoginModules(); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration configuration = modules[i]; + configuration.getModule().abort(); + } - return module.abort(); + return true; } public boolean logout(LoginModuleId loginModuleId) throws LoginException { @@ -320,10 +351,13 @@ if (lm == null) throw new ExpiredLoginModuleException(); lm.getSubject().getPrincipals(RealmPrincipal.class).clear(); - - LoginModule module = lm.getLoginModule(); - - return module.logout(); + lm.getSubject().getPrincipals(IdentificationPrincipal.class).clear(); + LoginModuleConfiguration[] modules = lm.getLoginModules(); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration configuration = modules[i]; + configuration.getModule().logout(); + } + return true; } public Subject retrieveSubject(LoginModuleId loginModuleId) throws LoginException { @@ -439,8 +473,8 @@ static { GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(LoginService.class); - infoFactory.addOperation("getAppConfigurationEntry", new Class[]{String.class}); - infoFactory.addOperation("allocateLoginModule", new Class[]{String.class}); + infoFactory.addOperation("getAppConfigurationEntries", new Class[]{String.class}); + infoFactory.addOperation("allocateLoginModules", new Class[]{String.class}); infoFactory.addOperation("getCallbacks", new Class[]{LoginModuleId.class}); infoFactory.addOperation("login", new Class[]{LoginModuleId.class, Collection.class}); infoFactory.addOperation("commit", new Class[]{LoginModuleId.class}); Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginServiceMBean.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginServiceMBean.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginServiceMBean.java Mon Nov 8 00:05:31 2004 @@ -29,6 +29,10 @@ /** * An MBean that maintains a list of security realms. * + * A LoginModuleId represents the configuration of a single security realm, + * which may in fact include multiple login modules under the covers, but + * that is not really important here. + * * @version $Rev$ $Date$ */ public interface LoginServiceMBean { @@ -37,11 +41,11 @@ void setRealms(Collection realms); - SerializableACE getAppConfigurationEntry(String realmName); + SerializableACE[] getAppConfigurationEntries(String realmName); - LoginModuleId allocateLoginModule(String realmName) throws LoginException; + LoginModuleId allocateLoginModules(String realmName) throws LoginException; - void removeLoginModule(LoginModuleId loginModuleId) throws ExpiredLoginModuleException; + void removeLoginModules(LoginModuleId loginModuleId) throws ExpiredLoginModuleException; Collection getCallbacks(LoginModuleId loginModuleId) throws ExpiredLoginModuleException; Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginUtils.java ============================================================================== --- (empty file) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/LoginUtils.java Mon Nov 8 00:05:31 2004 @@ -0,0 +1,49 @@ +package org.apache.geronimo.security.jaas; + +import javax.security.auth.login.LoginException; + +/** + * + * + * @version $Revision 1.0 $ + */ +public class LoginUtils { + public static boolean computeLogin(LoginModuleConfiguration[] modules) throws LoginException { + Boolean success = null; + Boolean backup = null; + // see http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration module = modules[i]; + boolean result = module.getModule().login(); + if(module.getControlFlag() == LoginModuleControlFlag.REQUIRED) { + if(success == null || success.booleanValue()) { + success = result ? Boolean.TRUE : Boolean.FALSE; + } + } else if(module.getControlFlag() == LoginModuleControlFlag.REQUISITE) { + if(!result) { + return false; + } else if(success == null) { + success = Boolean.TRUE; + } + } else if(module.getControlFlag() == LoginModuleControlFlag.SUFFICIENT) { + if(result && (success == null || success.booleanValue())) { + return true; + } + } else if(module.getControlFlag() == LoginModuleControlFlag.OPTIONAL) { + if(backup == null || backup.booleanValue()) { + backup = result ? Boolean.TRUE : Boolean.FALSE; + } + } + } + // all required and requisite modules succeeded, or at least one required module failed + if(success != null) { + return success.booleanValue(); + } + // no required or requisite modules, no sufficient modules succeeded, fall back to optional modules + if(backup != null) { + return backup.booleanValue(); + } + // perhaps only a sufficient module, and it failed + return false; + } +} Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModule.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModule.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModule.java Mon Nov 8 00:05:31 2004 @@ -45,7 +45,7 @@ private boolean debug; private URI connectURI; private LoginServiceMBean remoteLoginService; - private LoginModule wrapper; + private LoginModuleConfiguration[] modules; private static ClassLoader classLoader; static { @@ -68,19 +68,25 @@ connectURI = new URI(uri); remoteLoginService = RemoteLoginServiceFactory.create(connectURI.getHost(), connectURI.getPort()); - SerializableACE entry = remoteLoginService.getAppConfigurationEntry(realm); + SerializableACE[] entries = remoteLoginService.getAppConfigurationEntries(realm); + modules = new LoginModuleConfiguration[entries.length]; + for(int i = 0; i < entries.length; i++) { + SerializableACE entry = entries[i]; + + final String finalClass = entry.getLoginModuleName(); + LoginModule wrapper; + wrapper = (LoginModule) AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + return Class.forName(finalClass, true, classLoader).newInstance(); + } + }); - final String finalClass = entry.getLoginModuleName(); - wrapper = (LoginModule) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException { - return Class.forName(finalClass, true, classLoader).newInstance(); - } - }); + HashMap map = new HashMap(entry.getOptions()); + map.put(LOGIN_SERVICE, remoteLoginService); - HashMap map = new HashMap(entry.getOptions()); - map.put(LOGIN_SERVICE, remoteLoginService); - - wrapper.initialize(subject, callbackHandler, sharedState, map); + wrapper.initialize(subject, callbackHandler, sharedState, map); + modules[i] = new LoginModuleConfiguration(wrapper, entry.getControlFlag()); + } if (debug) { System.out.print("[GeronimoLoginModule] Debug is " + debug + " uri " + uri + " realm " + realm + "\n"); @@ -98,22 +104,34 @@ } public boolean login() throws LoginException { - if (wrapper == null) throw new LoginException("RemoteLoginModule not properly initialzied"); - return wrapper.login(); + if (modules == null || modules.length == 0) throw new LoginException("RemoteLoginModule not properly initialzied"); + return LoginUtils.computeLogin(modules); } public boolean commit() throws LoginException { - if (wrapper == null) throw new LoginException("RemoteLoginModule not properly initialzied"); - return wrapper.commit(); + if (modules == null || modules.length == 0) throw new LoginException("RemoteLoginModule not properly initialzied"); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration configuration = modules[i]; + configuration.getModule().commit(); + } + return true; } public boolean abort() throws LoginException { - if (wrapper == null) throw new LoginException("RemoteLoginModule not properly initialzied"); - return wrapper.abort(); + if (modules == null || modules.length == 0) throw new LoginException("RemoteLoginModule not properly initialzied"); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration configuration = modules[i]; + configuration.getModule().abort(); + } + return true; } public boolean logout() throws LoginException { - if (wrapper == null) throw new LoginException("RemoteLoginModule not properly initialzied"); - return wrapper.logout(); + if (modules == null || modules.length == 0) throw new LoginException("RemoteLoginModule not properly initialzied"); + for(int i = 0; i < modules.length; i++) { + LoginModuleConfiguration configuration = modules[i]; + configuration.getModule().logout(); + } + return true; } } Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModuleLocalWrapper.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModuleLocalWrapper.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/RemoteLoginModuleLocalWrapper.java Mon Nov 8 00:05:31 2004 @@ -55,7 +55,7 @@ this.realmName = (String) options.get(LoginModuleConstants.REALM_NAME); this.remoteLoginService = (LoginServiceMBean) options.get(RemoteLoginModule.LOGIN_SERVICE); try { - this.loginModuleId = remoteLoginService.allocateLoginModule(realmName); + this.loginModuleId = remoteLoginService.allocateLoginModules(realmName); } catch (LoginException e) { } } @@ -81,7 +81,7 @@ return tryLogin(); } catch (ExpiredLoginModuleException ele) { try { - loginModuleId = remoteLoginService.allocateLoginModule(realmName); + loginModuleId = remoteLoginService.allocateLoginModules(realmName); return tryLogin(); } catch (Exception e) { throw (LoginException) new LoginException().initCause(e); @@ -157,7 +157,7 @@ */ protected void finalize() throws Throwable { if (loginModuleId != null) { - remoteLoginService.removeLoginModule(loginModuleId); + remoteLoginService.removeLoginModules(loginModuleId); } } } Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/SerializableACE.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/SerializableACE.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/jaas/SerializableACE.java Mon Nov 8 00:05:31 2004 @@ -48,7 +48,7 @@ Map getOptions() { return options; } - +/* public static final class LoginModuleControlFlag implements Serializable { // Be careful here. If you change the ordinals, this class must be changed on evey client. @@ -78,4 +78,5 @@ return values[ordinal]; } } +*/ } 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 Mon Nov 8 00:05:31 2004 @@ -34,19 +34,41 @@ public String getRealmName(); + public long getMaxLoginModuleAge(); + + public AppConfigurationEntry[] getAppConfigurationEntries(); + + public boolean isLoginModuleLocal(); + + /** + * @deprecated Will be removed in favor of (some kind of realm editor object) in + * a future milestone release. + */ public Set getGroupPrincipals() throws GeronimoSecurityException; + /** + * @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; + /** + * @deprecated Will be removed in favor of (some kind of realm editor object) in + * a future milestone release. + */ public Set getUserPrincipals() throws GeronimoSecurityException; + /** + * @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; + /** + * @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; - public AppConfigurationEntry getAppConfigurationEntry(); - - public boolean isLoginModuleLocal(); - - public long getMaxLoginModuleAge(); } Modified: 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/AbstractSecurityRealm.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/AbstractSecurityRealm.java Mon Nov 8 00:05:31 2004 @@ -80,7 +80,7 @@ infoFactory.addOperation("getUserPrincipals"); infoFactory.addOperation("getUserPrincipals", new Class[]{RE.class}); infoFactory.addOperation("refresh"); - infoFactory.addOperation("getAppConfigurationEntry"); + infoFactory.addOperation("getAppConfigurationEntries"); infoFactory.setConstructor(new String[]{"realmName"}); Modified: 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/KerberosSecurityRealm.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/KerberosSecurityRealm.java Mon Nov 8 00:05:31 2004 @@ -207,7 +207,7 @@ log.info("Kerberos Realm - " + getRealmName() + " - refresh"); } - public javax.security.auth.login.AppConfigurationEntry getAppConfigurationEntry() { + public javax.security.auth.login.AppConfigurationEntry[] getAppConfigurationEntries() { HashMap options = new HashMap(); options.put("debug", (debug ? "true" : "false")); @@ -228,7 +228,7 @@ AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options); - return entry; + return new AppConfigurationEntry[]{entry}; } public boolean isLoginModuleLocal() { Modified: 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/PropertiesFileSecurityRealm.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/PropertiesFileSecurityRealm.java Mon Nov 8 00:05:31 2004 @@ -179,7 +179,7 @@ } } - public AppConfigurationEntry getAppConfigurationEntry() { + public AppConfigurationEntry[] getAppConfigurationEntries() { HashMap options = new HashMap(); options.put(REALM_INSTANCE, this); @@ -187,7 +187,7 @@ AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options); - return entry; + return new AppConfigurationEntry[]{entry}; } public boolean isLoginModuleLocal() { Modified: 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/SQLSecurityRealm.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SQLSecurityRealm.java Mon Nov 8 00:05:31 2004 @@ -267,7 +267,7 @@ return password; } - public AppConfigurationEntry getAppConfigurationEntry() { + public AppConfigurationEntry[] getAppConfigurationEntries() { HashMap options = new HashMap(); options.put(USER_SELECT, userSelect); @@ -280,7 +280,7 @@ AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options); - return entry; + return new AppConfigurationEntry[]{entry}; } public boolean isLoginModuleLocal() { Modified: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SimpleSecurityRealm.java ============================================================================== --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SimpleSecurityRealm.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/realm/providers/SimpleSecurityRealm.java Mon Nov 8 00:05:31 2004 @@ -112,13 +112,13 @@ log.info("Simple Realm - " + getRealmName() + " - refresh"); } - public javax.security.auth.login.AppConfigurationEntry getAppConfigurationEntry() { + public javax.security.auth.login.AppConfigurationEntry[] getAppConfigurationEntries() { AppConfigurationEntry entry = new AppConfigurationEntry(loginModuleName, AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options); - return entry; + return new AppConfigurationEntry[]{entry}; } public boolean isLoginModuleLocal() { Modified: geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestRealm.java ============================================================================== --- geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestRealm.java (original) +++ geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/bridge/TestRealm.java Mon Nov 8 00:05:31 2004 @@ -61,10 +61,10 @@ public void refresh() throws GeronimoSecurityException { } - public AppConfigurationEntry getAppConfigurationEntry() { - return new AppConfigurationEntry(TestLoginModule.class.getName(), + public AppConfigurationEntry[] getAppConfigurationEntries() { + return new AppConfigurationEntry[]{new AppConfigurationEntry(TestLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUISITE, - new HashMap()); + new HashMap())}; } public boolean isLoginModuleLocal() {