User: starksm Date: 01/07/19 03:18:57 Modified: src/main/org/jboss/security/plugins Tag: Branch_2_4 JaasSecurityManager.java JaasSecurityManagerService.java Log: Fix problem with security manager override. Add support for accessing the active subject from the ENC namespace Revision Changes Path No revision No revision 1.7.2.3 +2 -1 jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManager.java Index: JaasSecurityManager.java =================================================================== RCS file: /cvsroot/jboss/jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManager.java,v retrieving revision 1.7.2.2 retrieving revision 1.7.2.3 diff -u -r1.7.2.2 -r1.7.2.3 --- JaasSecurityManager.java 2001/07/14 16:50:56 1.7.2.2 +++ JaasSecurityManager.java 2001/07/19 10:18:57 1.7.2.3 @@ -7,6 +7,7 @@ package org.jboss.security.plugins; import java.io.IOException; +import java.io.Serializable; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; @@ -51,7 +52,7 @@ @author <a href="[EMAIL PROTECTED]">Oleg Nitz</a> @author [EMAIL PROTECTED] -@version $Revision: 1.7.2.2 $ +@version $Revision: 1.7.2.3 $ */ public class JaasSecurityManager implements SubjectSecurityManager, RealmMapping { 1.2.2.1 +237 -200 jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManagerService.java Index: JaasSecurityManagerService.java =================================================================== RCS file: /cvsroot/jboss/jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManagerService.java,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -r1.2 -r1.2.2.1 --- JaasSecurityManagerService.java 2001/06/15 08:26:02 1.2 +++ JaasSecurityManagerService.java 2001/07/19 10:18:57 1.2.2.1 @@ -4,12 +4,14 @@ * Distributable under LGPL license. * See terms of license at gnu.org. */ - + package org.jboss.security.plugins; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.net.URL; +import java.lang.reflect.Proxy; +import java.util.Enumeration; import java.util.Hashtable; import java.util.ArrayList; import java.util.Iterator; @@ -20,11 +22,16 @@ import javax.naming.RefAddr; import javax.naming.StringRefAddr; import javax.naming.Name; +import javax.naming.NameClassPair; +import javax.naming.NameParser; +import javax.naming.NamingEnumeration; import javax.naming.NamingException; +import javax.naming.OperationNotSupportedException; import javax.naming.spi.ObjectFactory; import javax.naming.spi.NamingManager; import javax.naming.CommunicationException; import javax.naming.CannotProceedException; +import javax.security.auth.Subject; import javax.management.MBeanServer; import javax.management.ObjectName; @@ -32,19 +39,18 @@ import org.jboss.logging.Log; import org.jboss.security.SecurityAssociation; import org.jboss.security.SecurityProxyFactory; +import org.jboss.security.SubjectSecurityManager; import org.jboss.util.ServiceMBeanSupport; -import org.jnp.server.NamingServer; -import org.jnp.interfaces.NamingContext; import org.jboss.util.CachePolicy; /** * This is a JMX service which manages JAAS based SecurityManagers. * JAAS SecurityManagers are responsible for validating credentials - * associated with principals. The service defaults to the + * associated with principals. The service defaults to the * org.jboss.security.plugins.JaasSecurityManager implementation but * this can be changed via the securityManagerClass property. - * + * * @see JaasSecurityManager * @see SubjectSecurityManager * @author <a href="[EMAIL PROTECTED]">Oleg Nitz</a> @@ -52,213 +58,244 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a> */ public class JaasSecurityManagerService - extends ServiceMBeanSupport - implements JaasSecurityManagerServiceMBean +extends ServiceMBeanSupport +implements JaasSecurityManagerServiceMBean { - /** The class that provides the security manager implementation */ - private static String securityMgrClassName; - /** The loaded securityMgrClassName */ - private static Class securityMgrClass; - /** The security credential cache policy, shared by all security mgrs */ - private static CachePolicy cachePolicy; - private static String cacheJndiName; - /** The class that provides the SecurityProxyFactory implementation */ - private static String securityProxyFactoryClassName; - private static Class securityProxyFactoryClass; - - static NamingServer srv; - static Hashtable jsmMap = new Hashtable(); - - public JaasSecurityManagerService() - { - // use thread-local principal and credential propagation - SecurityAssociation.setServer(); - try - { // Use JaasSecurityManager as the default - setSecurityManagerClassName("org.jboss.security.plugins.JaasSecurityManager"); - // Use SubjectSecurityProxyFactory as the default SecurityProxyFactory - setSecurityProxyFactoryClassName("org.jboss.security.SubjectSecurityProxyFactory"); - } - catch(ClassNotFoundException e) - { - } - } - - public String getSecurityManagerClassName() - { - return securityMgrClassName; - } - public void setSecurityManagerClassName(String className) - throws ClassNotFoundException - { - securityMgrClassName = className; - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - securityMgrClass = loader.loadClass(securityMgrClassName); - } - public String getSecurityProxyFactoryClassName() - { - return securityProxyFactoryClassName; - } - public void setSecurityProxyFactoryClassName(String className) - throws ClassNotFoundException - { - securityProxyFactoryClassName = className; - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - securityProxyFactoryClass = loader.loadClass(securityProxyFactoryClassName); - } + /** The class that provides the security manager implementation */ + private static String securityMgrClassName = "org.jboss.security.plugins.JaasSecurityManager"; + /** The loaded securityMgrClassName */ + private static Class securityMgrClass; + /** The security credential cache policy, shared by all security mgrs */ + private static CachePolicy cachePolicy; + private static String cacheJndiName; + /** The class that provides the SecurityProxyFactory implementation */ + private static String securityProxyFactoryClassName = "org.jboss.security.SubjectSecurityProxyFactory"; + private static Class securityProxyFactoryClass = org.jboss.security.SubjectSecurityProxyFactory.class; + + private static Hashtable jsmMap = new Hashtable(); + private static NameParser parser; + + static + { + // use thread-local principal and credential propagation + SecurityAssociation.setServer(); + } + + /** The constructor does nothing as the security manager is created + on each lookup into java:/jaas/xxx. This is also why all variables + in this class are static. + */ + public JaasSecurityManagerService() + { + } + + public String getSecurityManagerClassName() + { + return securityMgrClassName; + } + public void setSecurityManagerClassName(String className) + throws ClassNotFoundException + { + securityMgrClassName = className; + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + securityMgrClass = loader.loadClass(securityMgrClassName); + } + public String getSecurityProxyFactoryClassName() + { + return securityProxyFactoryClassName; + } + public void setSecurityProxyFactoryClassName(String className) + throws ClassNotFoundException + { + securityProxyFactoryClassName = className; + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + securityProxyFactoryClass = loader.loadClass(securityProxyFactoryClassName); + } /** Get the jndi name under which the authentication cache policy is found */ - public String getAuthenticationCacheJndiName() - { - return cacheJndiName; - } + public String getAuthenticationCacheJndiName() + { + return cacheJndiName; + } /** Set the jndi name under which the authentication cache policy is found */ - public void setAuthenticationCacheJndiName(String jndiName) - { - this.cacheJndiName = jndiName; - } - - public String getName() - { - return "JAAS Security Manager"; - } - + public void setAuthenticationCacheJndiName(String jndiName) + { + this.cacheJndiName = jndiName; + } + + public String getName() + { + return "JAAS Security Manager"; + } + protected ObjectName getObjectName(MBeanServer server, ObjectName name) - throws javax.management.MalformedObjectNameException + throws javax.management.MalformedObjectNameException { return new ObjectName(OBJECT_NAME); } - - protected void startService() throws Exception - { - srv = new NamingServer(); - - InitialContext ic = new InitialContext(); - - // Bind reference to SM subcontext in JNDI - // Uses JNDI federation to handle the "java:/jaas" context ourselves - RefAddr refAddr = new StringRefAddr("nns", "JSM"); - String factoryName = SecurityDomainObjectFactory.class.getName(); - Reference jsmsRef = new Reference("javax.naming.Context", refAddr, factoryName, null); - Context ctx = new InitialContext(); - ctx.rebind("java:/jaas", jsmsRef); - - try - { - if( cacheJndiName != null ) - cachePolicy = (CachePolicy) ctx.lookup(cacheJndiName); - } - catch(NamingException e) - { - } - System.out.println("JAAS.startService, cachePolicy="+cachePolicy); - // Bind the default SecurityProxyFactory instance under java:/SecurityProxyFactory - SecurityProxyFactory proxyFactory = (SecurityProxyFactory) securityProxyFactoryClass.newInstance(); - ctx.bind("java:/SecurityProxyFactory", proxyFactory); - System.out.println("JAAS.startService, SecurityProxyFactory="+proxyFactory); - } - - protected void stopService() - { - InitialContext ic; - try - { - ic = new InitialContext(); - ic.unbind("java:/jaas"); - } - catch (CommunicationException e) - { - // Do nothing, the naming services is already stopped - } - catch (Exception e) - { - log.exception(e); - } - } - + + protected void startService() throws Exception + { + InitialContext ic = new InitialContext(); + + // Bind reference to SM subcontext in JNDI + // Uses JNDI federation to handle the "java:/jaas" context ourselves + RefAddr refAddr = new StringRefAddr("nns", "JSM"); + String factoryName = SecurityDomainObjectFactory.class.getName(); + Reference jsmsRef = new Reference("javax.naming.Context", refAddr, factoryName, null); + Context ctx = new InitialContext(); + ctx.rebind("java:/jaas", jsmsRef); + parser = ctx.getNameParser(""); + + try + { + if( cacheJndiName != null ) + cachePolicy = (CachePolicy) ctx.lookup(cacheJndiName); + } + catch(NamingException e) + { + } + System.out.println("JAAS.startService, cachePolicy="+cachePolicy); + // Bind the default SecurityProxyFactory instance under java:/SecurityProxyFactory + SecurityProxyFactory proxyFactory = (SecurityProxyFactory) securityProxyFactoryClass.newInstance(); + ctx.bind("java:/SecurityProxyFactory", proxyFactory); + System.out.println("JAAS.startService, SecurityProxyFactory="+proxyFactory); + } + + protected void stopService() + { + InitialContext ic; + try + { + ic = new InitialContext(); + ic.unbind("java:/jaas"); + } + catch (CommunicationException e) + { + // Do nothing, the naming services is already stopped + } + catch (Exception e) + { + log.exception(e); + } + } + // ObjectFactory implementation ---------------------------------- - - public static class SecurityDomainObjectFactory implements ObjectFactory - { - /** - * Object factory implementation. This method is a bit tricky as it is called twice for each - * JSM lookup. Let's say the lookup is for "java:jaas/MySecurity". Then this will first be - * called as JNDI starts the "jaas" federation. In that call we make sure that the next call - * will go through, i.e. we check that the "MySecurity" binding is availble. Then we return - * the implementation of the "jaas" context. Then, when the "MySecurity" is dereferenced we - * look up the JSM from an internal static hash table. - * - * Note: it is possible to break this by doing the lookup in two phases: first lookup "java:jaas" - * and then do a second lookup of "MySecurity". If that is done then the first lookup has no way of - * knowing what name to check (i.e. it can't make sure that "MySecurity" is available in the - * "java:jaas" context! - * - * @param obj - * @param name - * @param nameCtx - * @param environment - * @return - * @exception Exception - */ - public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) - throws Exception - { - if (name != null) - { - // Handle securityManager lookup - if (name.size() == 0) - return nameCtx; - return jsmMap.get(name); - } - else - { - // Handle "java:jaas" context - CannotProceedException cpe = (CannotProceedException)environment.get(NamingManager.CPE); - Name remainingName = cpe.getRemainingName(); - - Context ctx = new NamingContext(environment, null, srv); - // Make sure that JSM is available + + public static class SecurityDomainObjectFactory implements InvocationHandler, ObjectFactory + { + /** Object factory implementation. This method returns a Context proxy + that is only able to handle a lookup operation for an atomic name of + a security domain. + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) + throws Exception + { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Class[] interfaces = {Context.class}; + Context ctx = (Context) Proxy.newProxyInstance(loader, interfaces, this); + return ctx; + } + + private Object newSecurityMgr(String securityDomain) throws NamingException + { + Object securityMgr = null; + try + { // Create instance of securityMgrClass + Class[] parameterTypes = {String.class}; + Constructor ctor = securityMgrClass.getConstructor(parameterTypes); + Object[] args = {securityDomain}; + securityMgr = ctor.newInstance(args); + System.out.println("JAAS.Created securityMgr="+securityMgr); + // See if the security mgr supports an externalized cache policy try { - srv.lookup(remainingName); + parameterTypes[0] = CachePolicy.class; + Method m = securityMgrClass.getMethod("setCachePolicy", parameterTypes); + args[0] = cachePolicy; + System.out.println("JAAS.setCachePolicy, c="+args[0]); + m.invoke(securityMgr, args); } - catch(Exception e) + catch(Exception e2) + { // No cache policy support, this is ok + } + System.out.println("JAAS.Added "+securityDomain+", "+securityMgr+" to map"); + jsmMap.put(securityDomain, securityMgr); + } + catch(Exception e2) + { + e2.printStackTrace(); + throw new NamingException("Failed to create sec mgr:"+e2.getMessage()); + } + return securityMgr; + } + + public Object invoke(Object obj, Method method, Object[] args) throws Throwable + { + String methodName = method.getName(); + if( methodName.equals("toString") == true ) + return "java:/jaas Context proxy"; + if( methodName.equals("list") == true ) + return new DomainEnumeration(jsmMap.keys()); + + if( methodName.equals("lookup") == false ) + throw new OperationNotSupportedException("Only lookup is supported, op="+method); + String securityDomain = null; + Name name = null; + if( args[0] instanceof String ) + name = parser.parse((String) args[0]); + else + name = (Name)args[0]; + securityDomain = name.get(0); + Object binding = jsmMap.get(securityDomain); + if( binding == null ) + { + binding = newSecurityMgr(securityDomain); + jsmMap.put(securityDomain, binding); + } + // Look for requests against the security manager + if( name.size() == 2 ) + { + String request = name.get(1); + if( binding instanceof SubjectSecurityManager && request.equals("subject") ) { - // Not found - add reference to JNDI, and a real security mgr to a map - Reference jsmRef = new Reference(securityMgrClass.getName(), getClass().getName(), null); - ctx.rebind(remainingName, jsmRef); - String securityDomain = remainingName.toString(); - try - { // Create instance of securityMgrClass - Class[] parameterTypes = {String.class}; - Constructor ctor = securityMgrClass.getConstructor(parameterTypes); - Object[] args = {securityDomain}; - Object securityMgr = ctor.newInstance(args); -System.out.println("JAAS.Created securityMgr="+securityMgr); - // See if the security mgr supports an externalized cache policy - try - { - parameterTypes[0] = CachePolicy.class; - Method m = securityMgrClass.getMethod("setCachePolicy", parameterTypes); - args[0] = cachePolicy; -System.out.println("JAAS.setCachePolicy, c="+args[0]); - m.invoke(securityMgr, args); - } - catch(Exception e2) - { // No cache policy support, this is ok - } -System.out.println("JAAS.Added "+remainingName+", "+securityMgr+" to map"); - jsmMap.put(remainingName, securityMgr); - } - catch(Exception e2) - { -e2.printStackTrace(); - throw e2; - } + SubjectSecurityManager ssm = (SubjectSecurityManager) binding; + Subject subject = ssm.getActiveSubject(); + binding = subject; } - return ctx; - } - } - } + } + return binding; + } + } + static class DomainEnumeration implements NamingEnumeration + { + Enumeration domains; + DomainEnumeration(Enumeration domains) + { + this.domains = domains; + } + + public void close() + { + } + public boolean hasMoreElements() + { + return domains.hasMoreElements(); + } + public boolean hasMore() + { + return domains.hasMoreElements(); + } + public Object next() + { + String name = (String) domains.nextElement(); + NameClassPair pair = new NameClassPair(name, securityMgrClassName); + return pair; + } + public Object nextElement() + { + return domains.nextElement(); + } + } } _______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] http://lists.sourceforge.net/lists/listinfo/jboss-development