User: luke_t Date: 02/02/03 13:10:50 Modified: src/main/org/jboss/security/plugins JaasSecurityManagerService.java Log: added log warning msg if cache policy lookup in JNDI fails. Applied code formatting. Revision Changes Path 1.10 +343 -323 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.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- JaasSecurityManagerService.java 2001/11/26 03:24:54 1.9 +++ JaasSecurityManagerService.java 2002/02/03 21:10:50 1.10 @@ -1,323 +1,343 @@ -/* - * JBoss, the OpenSource EJB server - * - * 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.lang.reflect.Proxy; -import java.util.Enumeration; -import java.util.Hashtable; - -import javax.naming.InitialContext; -import javax.naming.Context; -import javax.naming.Reference; -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.CommunicationException; -import javax.security.auth.Subject; - -import javax.management.MalformedObjectNameException; -import javax.management.MBeanServer; -import javax.management.ObjectName; - -import org.jboss.logging.Logger; -import org.jboss.security.SecurityAssociation; -import org.jboss.security.SecurityProxyFactory; -import org.jboss.security.SubjectSecurityManager; -import org.jboss.util.CachePolicy; -import org.jboss.system.ServiceMBeanSupport; - -/** - * 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 - * 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> - * @author <a href="[EMAIL PROTECTED]">Rickard Oberg</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a> - */ -public class JaasSecurityManagerService - extends ServiceMBeanSupport - implements JaasSecurityManagerServiceMBean -{ - /** The logging interface */ - private static Logger theLog; - /** 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(); - // Get a theLog interface - theLog = Logger.getLogger(JaasSecurityManagerService.class); - } - - /** 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; - } - /** Set the jndi name under which the authentication cache policy is found - */ - public void setAuthenticationCacheJndiName(String jndiName) - { - this.cacheJndiName = jndiName; - } - /** flush the cache policy for the indicated security domain if the security manager - * instance supports a flushCache() method. - */ - public void flushAuthenticationCache(String securityDomain) - { - String jndiName = "java:/jaas/" + securityDomain; - try - { - InitialContext ic = new InitialContext(); - Object securityMgr = ic.lookup(jndiName); - Class clazz = securityMgr.getClass(); - Class[] argTypes = {}; - Method flush = clazz.getMethod("flushCache", argTypes); - Object[] args = {}; - flush.invoke(securityMgr, args); - } - catch(Exception e) - { - theLog.error("flushAuthenticationCache failed", e); - } - } - - public String getName() - { - return "JAAS Security Manager"; - } - - protected ObjectName getObjectName(MBeanServer server, ObjectName name) - throws MalformedObjectNameException - { - return new ObjectName(OBJECT_NAME); - } - - 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) - { - } - theLog.info("startService, cachePolicy="+cachePolicy); - // Bind the default SecurityProxyFactory instance under java:/SecurityProxyFactory - SecurityProxyFactory proxyFactory = (SecurityProxyFactory) securityProxyFactoryClass.newInstance(); - ctx.bind("java:/SecurityProxyFactory", proxyFactory); - theLog.info("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) - { - theLog.error("stopService", e); - } - } - - // ObjectFactory implementation ---------------------------------- - - public static class SecurityDomainObjectFactory implements InvocationHandler, ObjectFactory - { - static Logger theLog = Logger.getLogger(SecurityDomainObjectFactory.class); - /** 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); - theLog.info("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; - theLog.info("setCachePolicy, c="+args[0]); - m.invoke(securityMgr, args); - } - catch(Exception e2) - { // No cache policy support, this is ok - } - theLog.info("Added "+securityDomain+", "+securityMgr+" to map"); - jsmMap.put(securityDomain, securityMgr); - } - catch(Exception e2) - { - theLog.error("Failed to create sec mgr", e2); - 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") ) - { - SubjectSecurityManager ssm = (SubjectSecurityManager) binding; - Subject subject = ssm.getActiveSubject(); - binding = subject; - } - } - 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, the OpenSource EJB server + * + * 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.lang.reflect.Proxy; +import java.util.Enumeration; +import java.util.Hashtable; + +import javax.naming.InitialContext; +import javax.naming.Context; +import javax.naming.Reference; +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.CommunicationException; +import javax.security.auth.Subject; + +import javax.management.MalformedObjectNameException; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.jboss.logging.Logger; +import org.jboss.security.SecurityAssociation; +import org.jboss.security.SecurityProxyFactory; +import org.jboss.security.SubjectSecurityManager; +import org.jboss.util.CachePolicy; +import org.jboss.system.ServiceMBeanSupport; + +/** + * 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 + * 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> + * @author <a href="[EMAIL PROTECTED]">Rickard Oberg</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a> + */ +public class JaasSecurityManagerService +extends ServiceMBeanSupport +implements JaasSecurityManagerServiceMBean +{ + /** The logging interface */ + private static Logger theLog; + + /** 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(); + // Get a theLog interface + theLog = Logger.getLogger(JaasSecurityManagerService.class); + } + + /** + * 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; + } + + /** Set the jndi name under which the authentication cache policy is found */ + public void setAuthenticationCacheJndiName(String jndiName) + { + this.cacheJndiName = jndiName; + } + + /** + * flush the cache policy for the indicated security domain if the security manager + * instance supports a flushCache() method. + */ + public void flushAuthenticationCache(String securityDomain) + { + String jndiName = "java:/jaas/" + securityDomain; + try + { + InitialContext ic = new InitialContext(); + Object securityMgr = ic.lookup(jndiName); + Class clazz = securityMgr.getClass(); + Class[] argTypes = {}; + Method flush = clazz.getMethod("flushCache", argTypes); + Object[] args = {}; + flush.invoke(securityMgr, args); + } + catch(Exception e) + { + theLog.error("flushAuthenticationCache failed", e); + } + } + + public String getName() + { + return "JAAS Security Manager"; + } + + protected ObjectName getObjectName(MBeanServer server, ObjectName name) + throws MalformedObjectNameException + { + return new ObjectName(OBJECT_NAME); + } + + 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) + { + theLog.warn("No cache policy object found under name '" + cacheJndiName + "'"); + } + theLog.info("startService, cachePolicy=" + cachePolicy); + // Bind the default SecurityProxyFactory instance under java:/SecurityProxyFactory + SecurityProxyFactory proxyFactory = (SecurityProxyFactory)securityProxyFactoryClass.newInstance(); + ctx.bind("java:/SecurityProxyFactory", proxyFactory); + theLog.info("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) + { + theLog.error("stopService", e); + } + } + + // ObjectFactory implementation ---------------------------------- + + public static class SecurityDomainObjectFactory implements InvocationHandler, ObjectFactory + { + static Logger theLog = Logger.getLogger(SecurityDomainObjectFactory.class); + + /** + * 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); + theLog.info("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; + theLog.info("setCachePolicy, c=" + args[0]); + m.invoke(securityMgr, args); + } + catch(Exception e2) + { // No cache policy support, this is ok + } + theLog.info("Added " + securityDomain + ", " + securityMgr + " to map"); + jsmMap.put(securityDomain, securityMgr); + } + catch(Exception e2) + { + theLog.error("Failed to create sec mgr", e2); + 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")) + { + SubjectSecurityManager ssm = (SubjectSecurityManager)binding; + Subject subject = ssm.getActiveSubject(); + binding = subject; + } + } + 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] https://lists.sourceforge.net/lists/listinfo/jboss-development