Sorry if I messed up the JBossMQ JAAS stuf; I could no figure out a
generic way to specify what MBean to invoke from a loginmodule.

The on-the-fly-security configuration you are asking for is however
possible to solve in more that one way. I tried the aproach of Scott a
while ago, but did not like it since it does not handle undordered
redeploys. So I ripes some parsing code from XMLLoginConfig and used its
MBean API. Heres the Mbean  I use personally to on-the-fly-configure JCA
RA JAAS Security.

package org.jboss.resource.security;
import java.util.ArrayList;
import java.util.HashMap;
import javax.management.ObjectName;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;

import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import org.jboss.system.ServiceMBeanSupport;
import org.jboss.security.auth.login.XMLLoginConfigMBean;
import org.jboss.security.auth.login.AuthenticationInfo;
import org.jboss.util.jmx.MBeanProxy;
/**
 * Add a security domain dynamically. 
 *
 * <p>Through this MBean you may add new security domains (LoginModules) to JBoss 
dynamically. Just configure the MBean and deploy it and you will have a new 
LoginConfigurations without having to restart the server.Configure it by setting the 
MBean Attribute AuthConfig with the application-policy xml you would normally stuff 
into login-config.xml.</p>
 *
 * <p>Here is an example:</p>
<pre>&lt;server&gt;
  &lt;!--new configuration for new ConnectionManager--&gt;
  &lt;mbean code="org.jboss.resource.security.LoginConfigurator" 
name="jboss.jca:service=AuthenticationInfo,name=User"&gt;
           &lt;depends 
optional-attribute-name="LoginConfig"&gt;jboss.security:service=XMLLoginConfig&lt;/depends&gt;
           &lt;attribute name="AuthConfig"&gt;
  &lt;application-policy name = "user"&gt;
    &lt;authentication&gt;
       &lt;login-module code ="org.jboss.security.auth.spi.LdapLoginModule" flag = 
"required"&gt;
         &lt;module-option name = 
"unauthenticatedIdentity"&gt;nobody&lt;/module-option&gt;
         &lt;module-option name = 
"java.naming.factory.initial"&gt;se.tim.jndi.ChainedCtxFactory&lt;/module-option&gt;
          &lt;module-option name = "principalDNPrefix"&gt;uid=&lt;/module-option&gt;
          &lt;module-option name = 
"principalDNSuffix"&gt;,ou=People,dc=tim,dc=se&lt;/module-option&gt;
          &lt;module-option name = 
"uidAttributeID"&gt;uniquemember&lt;/module-option&gt;
          &lt;module-option name = "roleAttributeID"&gt;cn&lt;/module-option&gt;
          &lt;module-option name = "matchOnUserDN"&gt;true&lt;/module-option&gt;
          &lt;module-option name = "rolesCtxDN"&gt;ou=Groups&lt;/module-option&gt;
          &lt;module-option name = 
"java.naming.provider.url"&gt;ldap://pra.tim.se/dc=tim,dc=se&lt;/module-option&gt;
          &lt;module-option name = 
"java.naming.security.authentication"&gt;simple&lt;/module-option&gt;
          &lt;module-option name = " 
java.naming.security.principal"&gt;cn=Manager,dc=tim,dc=se&lt;/module-option&gt;
          &lt;module-option name = 
"java.naming.security.credentials"&gt;PWD&lt;/module-option&gt;
          &lt;module-option name = 
"se.tim.jndi.chained.classes"&gt;se.tim.jndi.dsml.DSMLInterceptor&lt;/module-option&gt;
          &lt;module-option name = 
"se.tim.jndi.factory.initial"&gt;com.sun.jndi.ldap.LdapCtxFactory&lt;/module-option&gt;
          &lt;module-option name = 
"se.tim.jndi.dsml.pm"&gt;se.tim.jndi.dsml.FilePM&lt;/module-option&gt;
      &lt;/login-module&gt;
    &lt;/authentication&gt;
  &lt;/application-policy&gt;
           &lt;/attribute&gt;
  &lt;/mbean&gt;
&lt;/server&gt;
</pre>
 *
 * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Antman</a>
 * @version $Revision: 1.1 $
 * @jmx:mbean name="jboss.jca:service=LoginConfigurator" 
extends="org.jboss.system.ServiceMBean"
 */

public class LoginConfigurator
   extends ServiceMBeanSupport 
   implements LoginConfiguratorMBean{
   ObjectName loginConfig;
   Element authConfig;
   
   /**
    * @jmx:managed-attribute 
    */
   public ObjectName getLoginConfig() {
      return  loginConfig;
   }

   /**
    * @jmx:managed-attribute
    */
   public void setLoginConfig(ObjectName loginConfig) {
      this.loginConfig = loginConfig;
   }
   /**
    * @jmx:managed-attribute
    */
   public void setAuthConfig(Element authConfig) {
      this.authConfig = authConfig;
   }
   /**
    * @jmx:managed-attribute
    */
   public Element getAuthConfig() {
      return authConfig;
   }
   
   
   public void startService() throws Exception
   {
      // Check sanity
      if ( loginConfig == null) {
         throw new Exception("No LoginConfig MBean configured!");
      } // end of if ()
      if ( authConfig == null) {
         throw new Exception("No authentication config set");
      } // end of if ()
      log.info("Config " + authConfig.getNodeName());
      if ( !"application-policy".equals(authConfig.getNodeName()) ) {
          throw new Exception("Autehntication config is not an application policy");
      } // end of if ()

      // DO IT
      AuthenticationInfo info = parseAuthentication(authConfig);

      
      XMLLoginConfigMBean confMBean = (XMLLoginConfigMBean)
         MBeanProxy.create(XMLLoginConfigMBean.class,
                           loginConfig,
                           server);
      confMBean.addAppConfig( authConfig.getAttribute("name"), info.
                          getAppConfigurationEntry()
                          );
   }
   
   public void stopService() {
      XMLLoginConfigMBean confMBean = (XMLLoginConfigMBean)
         MBeanProxy.create(XMLLoginConfigMBean.class,
                           loginConfig,
                           server);
      confMBean.removeAppConfig( authConfig.getAttribute("name"));
   }

   /* Stolen from XMLLoginConfig. Thanks stark */
    /** Parse the application-policy/authentication element
    @param policy, the application-policy/authentication element
    */
   private AuthenticationInfo parseAuthentication(Element policy) throws Exception
   {
      // Parse the permissions
      NodeList authentication = policy.getElementsByTagName("authentication");
      if( authentication.getLength() == 0 )
      {
         return null;
      }

      Element auth = (Element) authentication.item(0);
      NodeList modules = auth.getElementsByTagName("login-module");
      ArrayList tmp = new ArrayList();
      for(int n = 0; n < modules.getLength(); n ++)
      {
         Element module = (Element) modules.item(n);
         parseModule(module, tmp);
      }
      AppConfigurationEntry[] entries = new AppConfigurationEntry[tmp.size()];
      tmp.toArray(entries);
      AuthenticationInfo info = new AuthenticationInfo();
      info.setAppConfigurationEntry(entries);
      return info;
   }
   private void parseModule(Element module, ArrayList entries) throws Exception
   {
      LoginModuleControlFlag controlFlag = LoginModuleControlFlag.REQUIRED;
      String className = module.getAttribute("code");
      String flag = module.getAttribute("flag");
      if( flag != null )
      {
         if( LoginModuleControlFlag.REQUIRED.toString().indexOf(flag) > 0 )
            controlFlag = LoginModuleControlFlag.REQUIRED;
         else if( LoginModuleControlFlag.REQUISITE.toString().indexOf(flag) > 0 )
            controlFlag = LoginModuleControlFlag.REQUISITE;
         else if( LoginModuleControlFlag.SUFFICIENT.toString().indexOf(flag) > 0 )
            controlFlag = LoginModuleControlFlag.SUFFICIENT;
         else if( LoginModuleControlFlag.OPTIONAL.toString().indexOf(flag) > 0 )
            controlFlag = LoginModuleControlFlag.OPTIONAL;
      }
      NodeList opts = module.getElementsByTagName("module-option");
      HashMap options = new HashMap();
      for(int n = 0; n < opts.getLength(); n ++)
      {
         Element opt = (Element) opts.item(n);
         String name = opt.getAttribute("name");
         String value = getContent(opt, "");
         options.put(name, value);
      }
      AppConfigurationEntry entry = new AppConfigurationEntry(className, controlFlag, 
options);
      entries.add(entry);
   }
   
   private static String getContent(Element element, String defaultContent)
   {
      NodeList children = element.getChildNodes();
      String content = defaultContent;
      if( children.getLength() > 0 )
      {
         content = "";
         for(int n = 0; n < children.getLength(); n ++)
         {
            if( children.item(n).getNodeType() == Node.TEXT_NODE ||
            children.item(n).getNodeType() == Node.CDATA_SECTION_NODE )
               content += children.item(n).getNodeValue();
            else
               content += children.item(n).getFirstChild();
         }
         return content.trim();
      }
      return content;
   }
}// LoginConfigurator

//Peter


On 15 Dec, Scott M Stark wrote:
> 
> ----- Original Message ----- 
> From: "Anatoly Akkerman" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Sunday, December 15, 2002 10:57 AM
> Subject: Re: [JBoss-dev] deployment scripts + extending Configuration of JBossSX on 
>the fly
> 
> 
> 
>> I've taken a look at the SecurityConfig. All it does is create an 
>> XMLLoginConfig MBean and then push it to the top of the stack of 
>> Configurations. So, basically it does its own custom scripting. It 
>> solves the problem but isn't it an overkill to create an MBean whose 
>> function is only to instantiate another MBean and register it with the 
>> third? This is pure metaprogramming.
>> 
> This is no different than deploying a new DataSource with a deployment and
> as such I don't see it as "pure metaprogramming", whatever that is.
> 
>> I still have a security question, though:
>> If I understand correctly, the entire Configuration gets replaced by the 
>> one that currently sits on the stack? Can I just add a particular piece, 
>> say, only application-policy for 'jbossmq-instanceid1234' while all 
>> other policies remain in place? Can I later remove any named application 
>> policy w/o affecting the rest? Stack seems to be a very limited data 
>> structure, I cannot add "jbossmq-id1", "jbossmq-id2" and then remove 
>> them in the _same_ (not stack-based) order.
>> 
>> Is there any technical limitation for doing what I need? Am I misreading 
>> something? Please, correct me if I am wrong.
>> 
> Yes, the stack as used right now is too global. There needs to be a stack
> per security domain. Pushing a config into a non-existent domain is equivalent
> to adding a config for the doamin. Pushing a config into an existing domain
> either overrides or augments the configuration. This change will be made
> when I move the dynamic config service out of the testsuite.
> 
>> I've taken a look at the ServiceBindingManager. It is somewhat similar 
>> to what I need but not exactly. In fact, it could have been a lot 
>> simpler (w/o requiring one to write a special delegate class that is 
>> responsible for changing configuration) by using the scripting facility 
>> itself. Here is how it could be done when *-service.xml is interpreted 
>> as a script:
>> 
>> Deployer loads a configuration for a service (similar to ServiceConfig) 
>> which can be simply a property sheet.
>> It initializes variables in the JellyContext with values from the 
>> ServiceConfig
>> Let's say the ServiceConfig for this bean has the following properties, 
>> so we simply set variables in JellyContext with the appropriate names:
>> FooService.Name = myDomain:service=Foo-1
>> FooService.ref1 = otherDomain:service=someName
>> FooService.jndiName = java:/Foo-1
>> FooService.propX = someValue
>> 
>> 
>> Deployer loads the foo-service.xml and executes it (it sets the taglib 
>> to the deployTagLib).
>> foo-service.xml should have references to appropriate variables, like:
>> 
>> <mbean name="${FooService.Name}" class="so.and.soClass">
>>      <depends optional-attribute-name="ref1">${FooService.ref1}</depends>
>>      <attribute name="JndiName">${FooService.jndiName}</attribute>
>>      <attribute name="propX">${FooService.propX}</attribute>
>> </mbean>
>> 
>> <mbean> tag creates the MBean with the given name and class (expression 
>> ${FooService.Name} is evaluated in the JellyContext and value of 
>> "myDomain:service=Foo-1" gets filled in.
>> 
>> the <mbean> evaluates its body (which means that <depend> and 
>> <attribute> tags get executed.
>> 
>> <depends> tag ensures that the dependency is present
>> <attribute> tag locates closes surrounding <mbean>, gets its mbean and 
>> sets the attributed to the appropriate value.
>> 
>> 
>> Now, if you wanted to reset certain attributes on an already existing 
>> mbean, you would run _the same_ foo-service.xml but using a 
>> reconfigureTagLib which binds the <mbean> tag to tag implementation that 
>> looks up the mbean instead of creating it.
>> 
>> Ain't it simpler?
> 
> Its not obviously simpler, and I don't see how this would be able to handle the
> transform of an attribute which itself is an xml fragment requiring the equivalent of
> XSLT to make the change. This also does not allow one to modify existing
> configurations. You have to first change the base configuration to be written
> with the scripting language.
> 
> Let's see a prototype to weigh the advantages and disadvantages. All we need to
> do is add the ability to externalize the bootstrap deployment services and we
> can switch between alternate view of deployment processing.
> 
> 
> 
> -------------------------------------------------------
> This sf.net email is sponsored by:
> With Great Power, Comes Great Responsibility 
> Learn to use your power at OSDN's High Performance Computing Channel
> http://hpc.devchannel.org/
> _______________________________________________
> Jboss-development mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/jboss-development

-- 
------------------------------------------------------------
Peter Antman    Chief Technology Officer, Development
Technology in Media, Box 34105 100 26 Stockholm
WWW: http://www.tim.se  WWW: http://www.backsource.org
Email: [EMAIL PROTECTED]        
Phone: +46-(0)8-506 381 11 Mobile: +46-(0)704 20 58 11
------------------------------------------------------------



-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to