User: starksm
Date: 01/11/09 02:25:55
Modified: src/main/org/jboss/security/plugins Tag: Branch_2_4
JaasSecurityManagerServiceMBean.java
JaasSecurityManagerService.java
Log:
Add support for authentication caches per domain and setting
the default timed cache timeout and resolution
Revision Changes Path
No revision
No revision
1.1.2.3 +53 -25
jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManagerServiceMBean.java
Index: JaasSecurityManagerServiceMBean.java
===================================================================
RCS file:
/cvsroot/jboss/jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManagerServiceMBean.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- JaasSecurityManagerServiceMBean.java 2001/09/26 06:36:35 1.1.2.2
+++ JaasSecurityManagerServiceMBean.java 2001/11/09 10:25:55 1.1.2.3
@@ -10,40 +10,68 @@
/** The interface for the JaasSecurityManagerService mbean.
@author [EMAIL PROTECTED]
- @version $Revision: 1.1.2.2 $
-*/
+ @version $Revision: 1.1.2.3 $
+ */
public interface JaasSecurityManagerServiceMBean
- extends org.jboss.util.ServiceMBean
+extends org.jboss.util.ServiceMBean
{
// Constants -----------------------------------------------------
public static final String OBJECT_NAME = "Security:name=JaasSecurityManager";
-
+
// Public --------------------------------------------------------
/** Get the name of the class that provides the security manager implementation.
*/
- public String getSecurityManagerClassName();
+ public String getSecurityManagerClassName();
/** Set the name of the class that provides the security manager implementation.
+ @exception ClassNotFoundException, thrown if the className cannot be found
+ using the thread context class loader.
+ @exception ClassCastException, thrown if the className does not implement the
+ org.jboss.security.AuthenticationManager interface.
*/
- public void setSecurityManagerClassName(String className) throws
ClassNotFoundException;
- /** Get the name of the class that provides the SecurityProxyFactory
implementation.
- */
- public String getSecurityProxyFactoryClassName();
- /** Set the name of the class that provides the SecurityProxyFactory
implementation.
- */
- public void setSecurityProxyFactoryClassName(String className) throws
ClassNotFoundException;
+ public void setSecurityManagerClassName(String className)
+ throws ClassNotFoundException, ClassCastException;
+ /** Get the name of the class that provides the SecurityProxyFactory
implementation.
+ */
+ public String getSecurityProxyFactoryClassName();
+ /** Set the name of the class that provides the SecurityProxyFactory
implementation.
+ */
+ public void setSecurityProxyFactoryClassName(String className)
+ throws ClassNotFoundException;
/** Get the jndi name under which the authentication CachePolicy implenentation
- is found
+ is found
+ */
+ public String getAuthenticationCacheJndiName();
+ /** Set the location of the security credential cache policy. This is first
treated
+ as a ObjectFactory location that is capable of returning CachePolicy instances
+ on a per security domain basis by appending a '/security-domain-name' string
+ to this name when looking up the CachePolicy for a domain. If this fails then
+ the location is treated as a single CachePolicy for all security domains.
+ @param jndiName, the name to the ObjectFactory or CachePolicy binding.
+ */
+ public void setAuthenticationCacheJndiName(String jndiName);
+ /** flush the cache policy for the indicated security domain if the security
manager
+ instance supports a flushCache() method.
+ */
+ /** Get the default timed cache policy timeout.
+ @return the default cache timeout in seconds.
+ */
+ public int getDefaultCacheTimeout();
+ /** Set the default timed cache policy timeout. This has no affect if the
+ AuthenticationCacheJndiName has been changed from the default value.
+ @param timeoutInSecs, the cache timeout in seconds.
+ */
+ public void setDefaultCacheTimeout(int timeoutInSecs);
+ /** Get the default timed cache policy resolution.
+ */
+ public int getDefaultCacheResolution();
+ /** Set the default timed cache policy resolution. This has no affect if the
+ AuthenticationCacheJndiName has been changed from the default value.
+ @param resInSecs, resolution of timeouts in seconds.
+ */
+ public void setDefaultCacheResolution(int resInSecs);
+
+ public void flushAuthenticationCache(String securityDomain);
+ /** Register a SecurityDomain implmentation
*/
- public String getAuthenticationCacheJndiName();
- /** Set the jndi name under which the authentication CachePolicy implenentation
- is found
- */
- public void setAuthenticationCacheJndiName(String jndiName);
- /** flush the cache policy for the indicated security domain if the security
manager
- instance supports a flushCache() method.
- */
- public void flushAuthenticationCache(String securityDomain);
- /** Register a SecurityDomain implmentation
- */
- public void registerSecurityDomain(String securityDomain, SecurityDomain
instance);
+ public void registerSecurityDomain(String securityDomain, SecurityDomain
instance);
}
1.2.2.6 +166 -66
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.2.5
retrieving revision 1.2.2.6
diff -u -r1.2.2.5 -r1.2.2.6
--- JaasSecurityManagerService.java 2001/09/26 06:36:35 1.2.2.5
+++ JaasSecurityManagerService.java 2001/11/09 10:25:55 1.2.2.6
@@ -40,12 +40,13 @@
import org.apache.log4j.Category;
import org.jboss.logging.log4j.JBossCategory;
+import org.jboss.security.AuthenticationManager;
import org.jboss.security.SecurityAssociation;
import org.jboss.security.SecurityProxyFactory;
import org.jboss.security.SecurityDomain;
-import org.jboss.security.SubjectSecurityManager;
import org.jboss.util.CachePolicy;
import org.jboss.util.ServiceMBeanSupport;
+import org.jboss.util.TimedCachePolicy;
/**
* This is a JMX service which manages JAAS based SecurityManagers.
@@ -64,20 +65,28 @@
extends ServiceMBeanSupport
implements JaasSecurityManagerServiceMBean
{
+ private static final String SECURITY_MGR_PATH = "java:/jaas";
+ private static final String DEFAULT_CACHE_POLICY_PATH =
"java:/timedCacheFactory";
/** The log4j interface */
private static Category log;
/** 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 location of the security credential cache policy. This is first treated
+ as a ObjectFactory location that is capable of returning CachePolicy instances
+ on a per security domain basis by appending a '/security-domain-name' string
+ to this name when looking up the CachePolicy for a domain. If this fails then
+ the location is treated as a single CachePolicy for all security domains.
+ */
+ private static String cacheJndiName = DEFAULT_CACHE_POLICY_PATH;
+ private static int defaultCacheTimeout = 30*60;
+ private static int defaultCacheResolution = 60;
/** 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();
+ /** A mapping from security domain name to a SecurityDomainContext object */
+ private static Hashtable securityDomainCtxMap = new Hashtable();
private static NameParser parser;
private static MBeanServer server;
@@ -103,11 +112,13 @@
return securityMgrClassName;
}
public void setSecurityManagerClassName(String className)
- throws ClassNotFoundException
+ throws ClassNotFoundException, ClassCastException
{
securityMgrClassName = className;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
securityMgrClass = loader.loadClass(securityMgrClassName);
+ if( AuthenticationManager.class.isAssignableFrom(securityMgrClass) == false )
+ throw new ClassCastException(securityMgrClass+" does not implement
"+AuthenticationManager.class);
}
public String getSecurityProxyFactoryClassName()
{
@@ -132,26 +143,48 @@
{
this.cacheJndiName = jndiName;
}
+ /** Get the default timed cache policy timeout.
+ @return the default cache timeout in seconds.
+ */
+ public int getDefaultCacheTimeout()
+ {
+ return defaultCacheTimeout;
+ }
+ /** Set the default timed cache policy timeout. This has no affect if the
+ AuthenticationCacheJndiName has been changed from the default value.
+ @param timeoutInSecs, the cache timeout in seconds.
+ */
+ public void setDefaultCacheTimeout(int timeoutInSecs)
+ {
+ this.defaultCacheTimeout = timeoutInSecs;
+ }
+ /** Get the default timed cache policy resolution.
+ */
+ public int getDefaultCacheResolution()
+ {
+ return defaultCacheResolution;
+ }
+ /** Set the default timed cache policy resolution. This has no affect if the
+ AuthenticationCacheJndiName has been changed from the default value.
+ @param resInSecs, resolution of timeouts in seconds.
+ */
+ public void setDefaultCacheResolution(int resInSecs)
+ {
+ this.defaultCacheResolution = resInSecs;
+ }
+
/** 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)
- {
- log.error("flushAuthenticationCache failed", e);
- }
+ SecurityDomainContext securityDomainCtx = (SecurityDomainContext)
securityDomainCtxMap.get(securityDomain);
+ if( securityDomainCtx != null )
+ {
+ CachePolicy cache = securityDomainCtx.getAuthenticationCache();
+ if( cache != null )
+ cache.flush();
+ }
}
public String getName()
@@ -163,31 +196,32 @@
throws MalformedObjectNameException
{
JaasSecurityManagerService.server = server;
- return new ObjectName(OBJECT_NAME);
+ return super.getObjectName(server, 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)
- {
- }
- log.info("startService, cachePolicy="+cachePolicy);
+ /* Create a mapping from the java:/jaas context to a
SecurityDomainObjectFactory
+ so that any lookup against java:/jaas/domain returns an instance of our
+ security manager class.
+ */
+ RefAddr refAddr = new StringRefAddr("nns", "JSM");
+ String factoryName = SecurityDomainObjectFactory.class.getName();
+ Reference ref = new Reference("javax.naming.Context", refAddr, factoryName,
null);
+ ctx.rebind(SECURITY_MGR_PATH, ref);
+ log.info("startService, securityMgrCtxPath="+SECURITY_MGR_PATH);
+
+ refAddr = new StringRefAddr("nns", "JSMCachePolicy");
+ factoryName = DefaultCacheObjectFactory.class.getName();
+ ref = new Reference("javax.naming.Context", refAddr, factoryName, null);
+ ctx.rebind(DEFAULT_CACHE_POLICY_PATH, ref);
+ log.info("startService, cachePolicyCtxPath="+cacheJndiName);
+
// Bind the default SecurityProxyFactory instance under
java:/SecurityProxyFactory
SecurityProxyFactory proxyFactory = (SecurityProxyFactory)
securityProxyFactoryClass.newInstance();
ctx.bind("java:/SecurityProxyFactory", proxyFactory);
@@ -200,7 +234,7 @@
try
{
ic = new InitialContext();
- ic.unbind("java:/jaas");
+ ic.unbind(SECURITY_MGR_PATH);
}
catch(CommunicationException e)
{
@@ -211,16 +245,51 @@
log.error("stopService", e);
}
}
-
+
/** Register a SecurityDomain implmentation
*/
public void registerSecurityDomain(String securityDomain, SecurityDomain
instance)
{
log.info("Added "+securityDomain+", "+instance+" to map");
- jsmMap.put(securityDomain, instance);
+ CachePolicy authCache = getCachePolicy(securityDomain);
+ SecurityDomainContext sdc = new SecurityDomainContext(instance, authCache);
+ securityDomainCtxMap.put(securityDomain, sdc);
}
- // ObjectFactory implementation ----------------------------------
+ /** Lookup the authentication CachePolicy object for a security domain. This
+ method first treats the cacheJndiName as a ObjectFactory location that is
+ capable of returning CachePolicy instances on a per security domain basis
+ by appending a '/security-domain-name' string to the cacheJndiName when
+ looking up the CachePolicy for a domain. If this fails then the cacheJndiName
+ location is treated as a single CachePolicy for all security domains.
+ */
+ private static CachePolicy getCachePolicy(String securityDomain)
+ {
+ CachePolicy authCache = null;
+ String domainCachePath = cacheJndiName + '/' + securityDomain;
+ try
+ {
+ InitialContext iniCtx = new InitialContext();
+ authCache = (CachePolicy) iniCtx.lookup(domainCachePath);
+ }
+ catch(Exception e)
+ {
+ // Failed, treat the cacheJndiName name as a global CachePolicy binding
+ try
+ {
+ InitialContext iniCtx = new InitialContext();
+ authCache = (CachePolicy) iniCtx.lookup(cacheJndiName);
+ }
+ catch(Exception e2)
+ {
+ log.warn("Failed to locate auth CachePolicy at: "+cacheJndiName
+ + " for securityDomain="+securityDomain);
+ }
+ }
+ return authCache;
+ }
+
+ // java:/jaas context ObjectFactory implementation
public static class SecurityDomainObjectFactory implements InvocationHandler,
ObjectFactory
{
@@ -237,18 +306,21 @@
return ctx;
}
- private Object newSecurityMgr(String securityDomain) throws NamingException
+ private SecurityDomainContext newSecurityDomainCtx(String securityDomain)
+ throws NamingException
{
- Object securityMgr = null;
+ SecurityDomainContext sdc = null;
try
- {
+ {
// Create instance of securityMgrClass
Class[] parameterTypes = {String.class};
Constructor ctor = securityMgrClass.getConstructor(parameterTypes);
Object[] args = {securityDomain};
ObjectName name = new ObjectName(server.getDefaultDomain(),
"securityDomain", securityDomain);
- securityMgr = ctor.newInstance(args);
+ AuthenticationManager securityMgr = (AuthenticationManager)
ctor.newInstance(args);
log.info("Created securityMgr="+securityMgr);
+ CachePolicy cachePolicy = getCachePolicy(securityDomain);
+ sdc = new SecurityDomainContext(securityMgr, cachePolicy);
// See if the security mgr supports an externalized cache policy
try
{
@@ -261,24 +333,26 @@
catch(Exception e2)
{ // No cache policy support, this is ok
}
- log.info("Added "+securityDomain+", "+securityMgr+" to map");
- jsmMap.put(securityDomain, securityMgr);
}
catch(Exception e2)
{
log.error("Failed to create sec mgr", e2);
throw new NamingException("Failed to create sec mgr:"+e2.getMessage());
}
- return securityMgr;
+ return sdc;
}
+ /** This is the InvocationHandler callback for the Context interface that
+ was created by out getObjectInstance() method. We handle the
java:/jaas/domain
+ level operations here.
+ */
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";
+ return SECURITY_MGR_PATH + " Context proxy";
if( methodName.equals("list") == true )
- return new DomainEnumeration(jsmMap.keys(), jsmMap);
+ return new DomainEnumeration(securityDomainCtxMap.keys(),
securityDomainCtxMap);
if( methodName.equals("lookup") == false )
throw new OperationNotSupportedException("Only lookup is supported,
op="+method);
@@ -289,22 +363,19 @@
else
name = (Name)args[0];
securityDomain = name.get(0);
- Object binding = jsmMap.get(securityDomain);
- if( binding == null )
+ SecurityDomainContext securityDomainCtx = (SecurityDomainContext)
securityDomainCtxMap.get(securityDomain);
+ if( securityDomainCtx == null )
{
- binding = newSecurityMgr(securityDomain);
- jsmMap.put(securityDomain, binding);
+ securityDomainCtx = newSecurityDomainCtx(securityDomain);
+ securityDomainCtxMap.put(securityDomain, securityDomainCtx);
+ log.info("Added "+securityDomain+", "+securityDomainCtx+" to map");
}
- // Look for requests against the security manager
+ Object binding = securityDomainCtx.getSecurityManager();
+ // Look for requests against the security domain context
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;
- }
+ binding = securityDomainCtx.lookup(request);
}
return binding;
}
@@ -312,11 +383,11 @@
static class DomainEnumeration implements NamingEnumeration
{
Enumeration domains;
- Hashtable jsmMap;
- DomainEnumeration(Enumeration domains, Hashtable jsmMap)
+ Hashtable ctxMap;
+ DomainEnumeration(Enumeration domains, Hashtable ctxMap)
{
this.domains = domains;
- this.jsmMap = jsmMap;
+ this.ctxMap = ctxMap;
}
public void close()
@@ -333,7 +404,7 @@
public Object next()
{
String name = (String) domains.nextElement();
- Object value = jsmMap.get(name);
+ Object value = ctxMap.get(name);
String className = value.getClass().getName();
NameClassPair pair = new NameClassPair(name, className);
return pair;
@@ -341,6 +412,35 @@
public Object nextElement()
{
return domains.nextElement();
+ }
+ }
+
+ /** java:/timedCacheFactory ObjectFactory implementation
+ */
+ public static class DefaultCacheObjectFactory 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;
+ }
+ /** This is the InvocationHandler callback for the Context interface that
+ was created by out getObjectInstance() method. All this does is create
+ a new TimedCache instance.
+ */
+ public Object invoke(Object obj, Method method, Object[] args) throws
Throwable
+ {
+ TimedCachePolicy cachePolicy = new TimedCachePolicy(defaultCacheTimeout,
true, defaultCacheResolution);
+ cachePolicy.init();
+ cachePolicy.start();
+ return cachePolicy;
}
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development