User: stark   
  Date: 01/03/06 01:02:47

  Modified:    src/docs howtojaas.xml
  Log:
  Updated the JAAS howto for the latest JBossSX changes
  
  Revision  Changes    Path
  1.2       +755 -484  manual/src/docs/howtojaas.xml
  
  Index: howtojaas.xml
  ===================================================================
  RCS file: /products/cvs/ejboss/manual/src/docs/howtojaas.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- howtojaas.xml     2001/02/11 00:55:33     1.1
  +++ howtojaas.xml     2001/03/06 09:02:46     1.2
  @@ -1,4 +1,5 @@
   <section><title>JAAS Based Security in JBoss</title>
  +<subtitle>Custom Security in JBoss Using the JBossSX Framework</subtitle>
   <para>
   Author:
   <author><firstname>Scott</firstname><surname>Stark</surname></author>
  @@ -6,65 +7,58 @@
   </para>
   
   <para>
  -<note><para>These instructions require a cvs snapshot that is latter than Jan 10 
2001. The "JBoss-PRE2.1 with jetty 3.0.2" binary package
  -not work with these instructions as the configuration mechanism has changed since 
the package was created. </para></note>
  +<note><para>The JBossSX framework is a new addition to JBoss that requires a
  +cvs snapshot that is latter than March 4 2001, or the JBoss-2.1 final binary.
  +</para></note>
   </para>
   
  +<section id="Introduction"><title>Introduction</title>
  +<!-- Begin Introduction -->
   <para>
  -For a previous tutorial by Edward Kenworthy, see Security Walkthrough/How 
To/Tutorial, first cut. The AppCallbackHandler implementation of
  -CallbackHandler in this document was derived from that tutorial. </para>
  -
  -<section><title>Introduction</title>
  -
  -<para>
  -This document describes the JBoss server's security architecture in some detail. It 
should be sufficient to allow you to configure a simple security setup
  -for testing. It should also give you a good start to being able to inegrate your 
own custom security implementation into JBoss. </para>
  +This document describes the setting up secured access to JBoss hosted EJBs
  +for both the standard declarative J2EE security model as well as custom
  +JAAS Subject based security. It should be sufficient to allow you to configure
  +a simple security setup for testing and also give you a good start to being
  +able to inegrate your own custom security implementation into JBoss. For
  +a more detailed description of the JBossSX framework see the JBossSX
  +chapter.
  +</para>
   
       
        <itemizedlist>
        <listitem><para><link linkend="jaas1">Security Model 
Overview</link></para></listitem>
        <listitem><para><link linkend="jaas2">How to Associate Security With the 
Container SecurityInterceptor</link></para></listitem> 
        <listitem><para><link linkend="jaas3">Using 
JaasSecurityManager</link></para></listitem> 
  -     <listitem><para><link linkend="jaas4">The Stateless Session 
Bean</link></para></listitem>  
  +     <listitem><para><link linkend="jaas4">The Session 
Beans</link></para></listitem>  
        <listitem><para><link linkend="jaas5">Deploying a Bean with 
Security</link></para></listitem>   
        </itemizedlist>
   
  +<!-- End Introduction -->
   </section>
   
   <section id="jaas1"><title>Security Model Overview</title>
   
   <para>
  -The security model in JBoss is based on the server container architecture's 
pluggable method interceptors and the fact that the container factory always
  -inserts security interceptor(org.jboss.ejb.plugins.SecurityInterceptor). For a view 
of see Entity Container Diagram for additional details. </para>
  -
  -<para>
  -Integration of custom security requires implementing the two interfaces that the 
SecurityInterceptor class uses to externalize its security checks. They
  -are:</para>
  -
  -
  -<programlisting>
  -package org.jboss.security;
  -public interface EJBSecurityManager
  -{
  -        public boolean isValid(java.security.Principal principal, Object 
credential);
  -}
  -
  -and: 
  -
  -package org.jboss.security;
  -public interface RealmMapping
  -{
  -    public java.security.Principal getPrincipal(java.security.Principal principal);
  -    public boolean doesUserHaveRole(java.security.Principal principal, Set 
roleNames);
  -}
  -</programlisting>
  +The security model in JBoss is based on the server container architecture's
  +pluggable method interceptors and the fact that the container factory always
  +inserts security interceptor(org.jboss.ejb.plugins.SecurityInterceptor).
  +The SecurityInterceptor delegates the tasks of principal authentication
  +and and principal role mapping to two different security interfaces;
  +org.jboss.security.EJBSecurityManager and org.jboss.security.RealmMapping.
  +JBoss includes a number of sample implementations of both interfaces which
  +can be found in the org.jboss.security.plugins.samples package.
  +</para>
   
   <para>
  -JBoss includes a number of sample implementations of both interfaces. These can be 
found in the org.jboss.security.plugins.samples package. There is
  -also a JMX service bean that can be used to setup a JAAS based implementation of 
both interfaces. The JMX bean is
  -org.jboss.security.JaasSecurityManagerService and the security manager 
implementation is org.jboss.security.JaasSecurityManager. This document
  -will focus on setting up the JaasSecurityManager via the JaasSecurityManagerService 
for a trivial stateless session bean. Once you can perform the
  -steps documented to secure the example bean, you should be able to introduce your 
own production ready security using this example as a template. 
  +The default security implementation that comes pre-configured is JMX service
  +bean and a JAAS based implementation of both interfaces. The JMX bean is
  +org.jboss.security.plugins.JaasSecurityManagerService and the security
  +interfaces implementation is org.jboss.security.plugins.JaasSecurityManager.
  +This document will focus on setting up the JaasSecurityManager via the
  +JaasSecurityManagerService for a trivial stateless session bean. Once you can
  +perform the steps documented to secure the example bean, you should be able
  +to introduce your own production ready security using this example as a
  +template.
   </para>
   
   </section>
  @@ -72,246 +66,406 @@
   <section id="jaas2"><title>How to Associate Security With the Container 
SecurityInterceptor</title>
   
   <para>
  -Ok, so you know that every EJB container in JBoss includes a SecurityInterceptor 
that delegates its security checks to an EJBSecurityManger and
  -RealmMapping implementation. Question: How do you choose which implementations a 
given container uses? Answer: You specify this information via
  -the jboss deployment descriptor. </para>
  -
  -<para>
  -The JBoss Deployment Descriptor(jboss.xml and standardjboss.xml)</para>
  -
  -<para>
  -The JBoss deployment descriptor is the JBoss application specific deployment 
configuration file. It describes optional behavior that is outside of the EJB
  -spec ejb-jar.xml deployment descriptor. The standardjboss.xml version of the file 
is located in ${jboss_home}/conf/conf_name where ${jboss_home}
  -is the directory into which you have installed the JBoss distribution and conf_name 
is the specific runtime configuration that you specify to the run.sh or
  -run.bat script when starting the server. The default value for conf_name is of 
course "default". The standardjboss.xml specifies the global configuration
  -default values. You can also specific ejb-jar or j2ee-ear specific jboss.xml 
descriptors that override specific configuration properties as appropriate for
  -your application. There are a quite a few configurable properties that can be set 
in the file, but all are optional. For all of the possible configuration
  -elements and their details see the jboss.dtd. We are only concerned with the two 
security specific elements: </para>
  -      
  +Ok, so you know that every EJB container in JBoss includes a SecurityInterceptor
  +that delegates its security checks to a security manager implementation.
  +How do you choose which implementations a given container uses?
  +You specify this information via the jboss deployment descriptor.
  +</para>
  +
  +<section><title>
  +The JBoss Deployment Descriptor(jboss.xml and standardjboss.xml)
  +</title>
  +
  +<para>
  +The JBoss deployment descriptor is the JBoss application specific deployment
  +configuration file. It describes implementation behavior that is outside of the
  +EJB spec ejb-jar.xml deployment descriptor. The standardjboss.xml version of the
  +file is located in ${jboss_home}/conf/conf_name where ${jboss_home} is the
  +directory into which you have installed the JBoss distribution and conf_name is
  +the specific runtime configuration that you specify to the run.sh or
  +run.bat script when starting the server. The default value for conf_name is
  +"default". The standardjboss.xml specifies the global configuration default
  +values. You can also specific ejb-jar or j2ee-ear specific jboss.xml descriptors
  +that override specific or all configuration properties as appropriate for
  +your application. There are a quite a few configurable properties that can be
  +set in the file, but all are optional. For all of the possible configuration
  +elements and their details see the jboss.dtd. We are only concerned with the
  +three security specific elements: </para>
  + 
        <itemizedlist> 
  +     <listitem><para>security-domain</para></listitem>
        <listitem><para>role-mapping-manager</para></listitem>
        <listitem><para>authentication-module</para></listitem> 
        </itemizedlist> 
  -
   
  +<section><title>security-domain</title>
   <para>
  -role-mapping-manager
  +The security-domain element specifies the an implementation of both the
  +org.jboss.security.RealmMapping and org.jboss.security.EJBSecurityManager
  +interfaces to use for all J2EE deployment units in the ear or ejb-jar.
  +The value is specified as the JNDI name where the object is located.
  +Hence, the security-domain is like a JMS TopicConnectionFactory in
  +that it is accessed via a JNDI name whose setup is a managed process.
   </para>
  -
  -<para>
  -The role-mapping-manager element specifies the implementation of the 
org.jboss.security.RealmMapping interface that is to be used by the container
  -SecurityInterceptor. The value is specified as the JNDI name to where the object is 
located. Hence, the role-mapping-manager is like a JMS
  -TopicConnectionFactory in that it is accessed via a JNDI name. As far as the 
container configuration is concerned, an implementation of
  -org.jboss.security.RealmMapping exists in the JBoss server JNDI namespace and 
role-mapping-manager element provides the location. We'll se how
  -you get a RealmMapping instance into the JNDI namespace shortly. </para>
  +</section>
   
  +<section><title>role-mapping-manager</title>
   <para>
  -authentication-module
  +The role-mapping-manager element specifies the implementation of the
  +org.jboss.security.RealmMapping interface that is to be used by the container
  +SecurityInterceptor. The value is specified as the JNDI name where the object is
  +located.  As far as the container configuration is concerned, an implementation
  +of org.jboss.security.RealmMapping exists in the JBoss server JNDI namespace
  +and role-mapping-manager element provides the location.
   </para>
  +</section>
   
  +<section><title>authentication-module</title>
   <para>
  -The authentication-module element specifies the implementation of the 
org.jboss.security.EJBSecurityManager interface that is to be used by the
  -container SecurityInterceptor. The value is specified as the JNDI name to where the 
object is located, just like the role-mapping-manager. </para>
  +The authentication-module element specifies the implementation of the
  +org.jboss.security.EJBSecurityManager interface that is to be used by the
  +container SecurityInterceptor. The value is specified as the JNDI name to where
  +the object is located, just like the role-mapping-manager.
  +</para>
  +</section>
   
  +<section><title>Sample jboss.xml</title>
   <para>
  -Sample jboss.xml
  -
  -The jboss.xml descriptor will we use is: 
  +The sample jboss.xml descriptor we will use is: 
   </para>
   
  -<programlisting><![CDATA[
  +<figure id="jboss.xml"><title>jboss.xml</title>
  +<programlisting>
  +<![CDATA[
   <?xml version="1.0"?>
   <jboss>
  -        <container-configurations>
  -                <container-configuration>
  -                        <container-name>Standard Stateless 
SessionBean</container-name>
  -                        
<role-mapping-manager>java:/jaas/other</role-mapping-manager>
  -                        
<authentication-module>java:/jaas/other</authentication-module>
  -                </container-configuration>
  -        </container-configurations>
  -
  -        <enterprise-beans>
  -                <session>
  -                        <ejb-name>StatelessSession</ejb-name>
  -                        <configuration-name>Standard Stateless 
SessionBean</configuration-name>
  -                </session>
  -        </enterprise-beans>
  +    <!-- All bean containers use this security manager by default -->
  +    <security-domain>java:/jaas/other</security-domain> ]]><co id="jboss.sample.sd" 
/>
  +<![CDATA[
  +    <container-configurations>
  +        <!-- Override the role mapping function from that of the
  +        security-domain setting for stateless session beans -->
  +        <container-configuration>
  +            <!-- Use the standardjboss.xml container-name so we only have
  +            to specify the elements we want to override -->
  +            <container-name>Standard Stateless SessionBean</container-name>
  +            
<role-mapping-manager>java:/jaas/session-roles</role-mapping-manager>]]><co 
id="jboss.sample.rmm" />
  +<![CDATA[
  +        </container-configuration>
  +    </container-configurations>
  +
   </jboss>
   ]]></programlisting>
  -
  +<calloutlist>
  +<callout arearefs="jboss.sample.sd">
   <para>
  -This says that we are augmenting the definition of the "Standard Stateless 
SessionBean" container to include role-mapping-manager and
  -authentication-module security elements, the values of which are the JNDI name 
"java:/jaas/other". We will see the reason for choosing this particular
  -name over the next couple of sections. The "Standard Stateless SessionBean" name is 
coming from the standardjboss.xml default configuration file. </para>
  +Establishes a global security manager via the
  +<function>security-domain</function> element. 
  +</para>
  +</callout>
   
  +<callout arearefs="jboss.sample.rmm">
   <para>
  -Setting Up the RealmMapping and EJBSecurityManager in JNDI</para>
  +Overrides the global security manager role mapping function for
  +stateless session beans.
  +</para>
  +</callout>
  +</calloutlist>
  +</figure>
   
   <para>
  -So the container configuration security elements specify the JNDI names where the 
desired RealmMapping and EJBSecurityManager implementations
  -are to be obtained from for a given container. Now the question is how to bind 
implementations into the JBoss server JNDI namespace. The answer is to
  -create a JMX mbean that creates and binds the desired implementations at server 
startup. The JaasSecurityManagerService is an mbean that has been
  -written that we will use to perform the required setup. </para>
  +Here we are assigning a global security manager for all beans to the
  +the object located at java:/jaas/other and we are setting a different
  +role mapping manager for the <quote>Standard Stateless SessionBean</quote>
  +container. This means that any stateless session beans bundled in the
  +ear or jar will use the RealmMapper located at java:/jaas/session-roles rather
  +the the security-domain element setting.
  +We will see the reason for choosing JNDI names of the form java:/jaas/XXX
  +over the next couple of sections.
  +</para>
  +</section>
  +<!-- End The JBoss Deployment Descriptor -->
  +</section>
   
  +<section><title>Setting Up the Security Manager Implementation in JNDI</title>
  +
   <para>
  -To configure the JaasSecurityManagerService, open the 
${jboss_home}/conf/default/jboss.jcml file and look for an entry like: </para>
  +So we have setup the container configuration security elements to specify the
  +JNDI names where the desired RealmMapping and EJBSecurityManager implementations
  +are to be obtained from. Now the question is how to bind implementations into the
  +JBoss server JNDI namespace. The answer is to create a JMX mbean that creates and
  +binds the desired implementations at server startup. The
  +JaasSecurityManagerService is an mbean that has been written that we will use to
  +perform the required setup.
  +</para>
   
  +<para>
  +To configure the JaasSecurityManagerService, open the
  +${jboss_home}/conf/default/jboss.jcml file and look for an entry like:
  +</para>
   
   <programlisting><![CDATA[
  -<!-- JAAS security manager and realm mapping -->
  -<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
  -        name="DefaultDomain:service=JaasSecurityManager" />
  +  <!-- JAAS security manager and realm mapping -->
  +  <mbean code="org.jboss.security.plugins.JaasSecurityManagerService" 
name="Security:name=JaasSecurityManager">
  +    <attribute 
name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
  +    <attribute 
name="SecurityProxyFactoryClassName">org.jboss.security.SubjectSecurityProxyFactory</attribute>
  +  </mbean>
   ]]></programlisting>
   
   <para>
  -If it is commented out or does not exist, uncomment or add the entry. The service 
creates a reference to a JNDI Context at java:/jaas that lazily binds
  -instances of JaasSecurityManager under java:/jaas as requested. If you don't know 
JNDI well or this just makes no sense, don't worry about. All we
  -care about is that with the JaasSecurityManagerService setup, any lookup on the 
JBoss server JNDI InitialContext using a name of the form
  -java:/jaas/xyz results in an object of type 
org.jboss.security.plugins.JaasSecurityManager that has the name xyz. Translated to 
code, this means: </para>
  +If it is commented out or does not exist, uncomment or add the entry. The
  +JaasSecurityManagerService service creates a reference to a JNDI Context at
  +java:/jaas that lazily binds instances of 
org.jboss.security.plugins.JaasSecurityManager
  +under java:/jaas as they are requested via JNDI. The details of how this happens are
  +not important(if they are to you, look at the code). All we care about is that with 
the
  +JaasSecurityManagerService setup, any lookup on the JBoss server JNDI InitialContext
  +using a name of the form java:/jaas/xyz results in an object of type
  +org.jboss.security.plugins.JaasSecurityManager that has the name xyz. Translated to 
code,
  +this means:
  +</para>
   
   <programlisting>
   InitialContext ctx = new InitialContext();
  -JaasSecurityManager jsm1 = (JaasSecurityManager) 
ctx.lookup("java:/jaas/xyz");</programlisting>
  +JaasSecurityManager jsm1 = (JaasSecurityManager) ctx.lookup("java:/jaas/xyz");
  +String securityDomain = jsm1.getSecurityDomain();
  +// securityDomain == "xyz"
  +</programlisting>
   
   <para>
  -where jsm1 is an instance of JaasSecurityManager that was created using the name 
"xyz". We are going to use this feature to bind a single instance of
  -JaasSecurityManager for use as both the RealmMapping and EJBSecurityManager 
implementations(because JaasSecurityManager implements both
  -interfaces). We'll see this when we get to the session bean example. Now we need to 
know how we can actually authenticate users and specify the
  -roles/identies they posses with a JaasSecurityManager. 
  +where <varname>jsm1</varname> is an instance of JaasSecurityManager that was created
  +using the name "xyz".
  +We are using this feature to bind a single instance of JaasSecurityManager for
  +use as both the RealmMapping and EJBSecurityManager implementations in the 
preceeding
  +jboss.xml descriptor. We can do this because JaasSecurityManager implements both
  +interfaces. Now we need to know how we can actually authenticate users and specify 
the
  +roles/identies they possess with a JaasSecurityManager.
   </para>
  +</section>
   
  +<!-- End jaas2 -->
   </section>
   
   <section id="jaas3"><title>Using JaasSecurityManager</title>
   
   <para>
  -As you would expect, the JaasSecurityManager uses the JAAS (Java Authentication and 
Authorization Service) to implement both the user
  -authentication and role mapping function of the RealmMapping and EJBSecurityManager 
interfaces. It does this by creating a JAAS Subject using the
  -javax.security.auth.login.LoginContext mechanism. The JAAS Subject creation 
involves:</para>
  +As you would expect, the JaasSecurityManager uses JAAS(Java Authentication and
  +Authorization Service) to implement both the user authentication and role mapping
  +function of the RealmMapping and EJBSecurityManager interfaces. It does this by 
creating
  +a JAAS Subject using the javax.security.auth.login.LoginContext mechanism. When
  +the JaasSecurityManager needs to authenticate a user, it does a JAAS
  +login using the following programmatic steps:
  +</para>
   
   <programlisting>
  -Principal principal = ... passed in by SecurityInterceptor;
  -char[] password = ... passed in by SecurityInterceptor;
  -String name = ... the xyz component of java:/jaas/xyz used in the 
authentication-module and role-mapping-manager
  -LoginContext lc = new LoginContext(name, new CallbackHandler(){...});
  -lc.login(); // This validates principal, password
  +Principal principal = ... passed in by SecurityInterceptor;<co id="jaas.principal" 
/>
  +Object credential = ... passed in by SecurityInterceptor;<co id="jaas.credential" />
  +/* Access the security domain to which the security manager is bound. This is
  +the xyz component of java:/jaas/xyz name used when defining the security-domain
  +or role-mapping-manager config elements. */
  +String name = getSecurityDomain();
  +CallbackHandler handler = new 
org.jboss.security.plugins.SecurityAssociationHandler();
  +handler.setSecurityInfo(principal, credential);
  +LoginContext lc = new LoginContext(name, handler);
  +// Validate principal, credential using the LoginModules configured for 'name'
  +lc.login();
   Subject subject = lc.getSubject();
  -Set roles = subject.getPrincipals();
  +Set subjectGroups = subject.getPrincipals(Group.class);
  +// Get the Group whose name is 'Roles'
  +Group roles = getGroup(subjectGroups, "Roles");
   </programlisting>
  -
  +<calloutlist>
  +<callout arearefs="jaas.principal">
   <para>
  -If you know JAAS, you'll see that the name that was used in the creation of the 
JaasSecurityManager correlates with the LoginContext Configuration
  -index. The JAAS LoginContext object looks to a configuration file that is made up 
of named sections that describe the LoginModules that need to be
  -executed in order to perform authentication. This abstraction allows the 
authentication api to be independent of a particular implementation. The
  -authentication of users and the assignment of user roles comes down to implementing 
a javax.security.auth.spi.LoginModule and creating login
  -configuration entry that correlates with the JaasSecurityManager name. There exist 
a number of sample LoginModule implementation in the
  -org.jboss.security.plugins.samples package. We are going to use the 
JaasServerLoginModule to demonstrate the how to configure a LoginModule to
  -work with the JaasSecurityManager. If you need different authentication and role 
mapping you can choose another LoginModule or implement you own
  -and then configure it using the same steps we will use. </para>
  +A Principal is an identity object. Often it represents the username string,
  +but it can be an X509 cert, an http cookie, etc. This is ultimately passed to
  +the LoginModule chain and so the interpretation of what the Principal is
  +depends on the configured LoginModules for the security domain.
  +</para>
  +</callout>
   
  +<callout arearefs="jaas.credential">
   <para>
  -Using JaasServerLoginModule
  +The credential is the value the principal is attempting to use to
  +verify his identity. It could be a password string or one-way has
  +of the password, a session key or token, etc.
  +This is ultimately passed to the LoginModule chain
  +and so the interpretation of what the credential is depends on the
  +configured LoginModules for the security domain.
   </para>
  +</callout>
  +</calloutlist>
   
   <para>
  -The JaasServerLoginModule class is a simple file based implemention that uses two 
files(users.properties and roles.properities) to perform
  -authentication and role mapping respectively. </para>
  +If your familiar JAAS, you'll see that the name that was used in the creation of
  +the JaasSecurityManager correlates with the LoginContext Configuration
  +name. The JAAS LoginContext object looks to a configuration object that is made up
  +of named sections that describe the LoginModules that need to be
  +executed in order to perform authentication. This abstraction allows the
  +authentication api to be independent of a particular implementation. The
  +authentication of users and the assignment of user roles comes down to
  +implementing a javax.security.auth.spi.LoginModule and creating login
  +configuration entry that correlates with the JaasSecurityManager name.
  +There exist a number of sample LoginModule implementation in the
  +org.jboss.security.plugins.samples package. We are going to use the
  +JaasServerLoginModule to demonstrate the how to configure a LoginModule to
  +work with the JaasSecurityManager. For your particular application you would
  +likely need different authentication and role mapping. You can choose another
  +LoginModule that integrates with your security environment, or implement you own
  +and then configure it using the same steps we will use.
  +</para>
   
  +<section><title>Using JaasServerLoginModule</title>
   <para>
  -users.properties</para>
  +The JaasServerLoginModule class is a simple properties file based implemention
  +that uses two files(users.properties and roles.properities) to perform
  +authentication and role mapping respectively.
  +</para>
   
  +<section><title>users.properties</title>
   <para>
  -The users.properties file is a java properties formatted file that specifies the 
username to password mapping. Its format is 
  +The users.properties file is a java properties formatted file that specifies the
  +username to password mapping. Its format is:
   
  +<programlisting>
   username1=password1
   username2=password2
   ...
  +</programlisting>
   
   with one entry per line. 
  -</para>
  -
  -<para>
  -roles.properties
   </para>
  +</section>
   
  +<section><title>roles.properties</title>
   <para>
  -The roles.properties file is a java properties formatted file that specifies the 
username to role(s) mapping. Its format is 
  +The roles.properties file is a java properties formatted file that specifies
  +the username to role(s) mapping. Its format is:
   
  +<programlisting>
   username1=role1[,role2,...]
   username2=role1
   ...
  -
  -with one entry per line. If a user has multiple roles they are specified using a 
comma separated list. </para>
  -
  +</programlisting>
   
  -<para>
  -The LoginModule Configuration File
  +with one entry per line. If a user has multiple roles they are specified using a
  +comma separated list.
   </para>
  +</section>
   
  +<section><title>The LoginModule Configuration File</title>
   <para>
  -The JAAS LoginModule Configuration file is ${jboss_home)/conf/default/auth.conf. 
The syntax is: </para>
  +By default JAAS uses a LoginModule configuration file to describe which
  +LoginModule instances need to be executed during a login. The default
  +config for the JBoss server is ${jboss_home)/conf/default/auth.conf.
  +The syntax is:
   
  -<programlisting>
  +<synopsis>
   name {
  -        login_module_class_name (required|optional|...) [options];
  +        login_module_class_name (required|optional|...)
  +        [options]
  +        ;
   };
  +</synopsis>
   
  -See the JAAS documentation for the complete syntax description. There should be an 
entry like the following: // The default server login module 
  +See the JAAS documentation for the complete syntax description. In the JBoss server
  +auth.conf file there should be an entry like 'other' in the figure below.
  +Also shown is a 'session-roles' entry that we have added that specfies two
  +login modules.
  +</para>
   
  +<figure id="auth.conf"><title>The JBoss Server JAAS Login Config File</title>
  +<programlisting>
  +// The default server login module
   other {
  -    // A realistic server login module, which can be used when the number 
  -    // of users is relatively small. It uses two properties files:
  -    //   users.properties, which holds users (key) and their password (value).
  -    //   roles.properties, which holds users (key) and a comma-separated list of 
their roles (value).
  +    // A realistic server login module...
       org.jboss.security.plugins.samples.JaasServerLoginModule required;
   };
  -</programlisting>
  -
   
  -<para>
  -This indicates that the JaasServerLoginModule we want to use is setup for the 
"other" configuration. This happens to the the configuration that JAAS
  -uses when it can't find a match and it will work fine for us. </para>
  +// Augment the JaasServerLoginModule roles with a CallerPrincipal mapping
  +// using the RolesLoginModule
  +session-roles {
  +    org.jboss.security.plugins.samples.JaasServerLoginModule required
  +        password-stacking="useFirstPass"
  +    ;
  +    org.jboss.security.plugins.samples.RolesLoginModule required
  +    ;
  +};
  +</programlisting>
  +</figure>
   
   <para>
  -We have touched on all of the JBoss security related elements we need to configure. 
Let's now put together a simple session bean that we will secure to
  -demonstrate how to use what we have gone over to deploy a secure bean. </para>
  -
  +This indicates that the JaasServerLoginModule we want to use is setup for
  +the configuration named 'other'. This name also matches name of the
  +security domain portion of the JNDI name java:/jaas/other, which is what
  +we want. Recall that we specified an different security domain for
  +the role-mapping-manager element for the stateless session bean container
  +configuration. We used java:/jaas/session-roles. When a user accesses a
  +stateless session bean, they will be authenticated by the login modules
  +configured for the 'session-roles' domain. Referring to Figure 1 shows
  +that both the JaasServerLoginModule and RolesLoginModule login modules
  +will be executed for perform the authentication in this domain.
  +
  +
  +<note>The configuration named 'other' is used JAAS whenever it can't find
  +an entry matching the name passed to the LoginContext constructor. So
  +if we had used a JNDI name like java:/jaas/global as the security-domain
  +configuration element, we would still be using the 'other' login configuration
  +entry unless there also happened to be a 'global' entry.
  +</note>
  +</para>
   </section>
  -
  -<section id="jaas4"><title>The Stateless Session Bean</title>
  +</section>
   
   <para>
  -Here are the home, remote and bean classes for the simple stateless session bean we 
are going to secure, along with a simple client that creates an
  -instance of the session bean:</para> 
  +We have now touched on all of the JBoss security related elements we need to
  +configure to secure the deployment of EJBs.
  +Let's now put together two simple session beans that we will secure to
  +demonstrate how to use what we have gone over.
  +</para>
  +</section>
   
  +<section id="jaas4"><title>The Session Beans</title>
   <para>
  -StatelessSession.java</para>
  +The following figures give the code listings for the the home, remote
  +and bean classes for the simple stateless and stateful session beans we
  +are going to secure, along with a simple client that accesses instances
  +of the session beans. 
  +</para> 
   
  +<figure id="Session.java"><title>The Session Beans Remote Interface</title>
   <programlisting>
   import javax.ejb.*;
   import java.rmi.*;
   
  -public interface StatelessSession extends EJBObject
  +public interface Session extends EJBObject
   {
       public String echo(String arg) throws RemoteException;
   }
  -
  -StatelessSessionHome.java
  +</programlisting>
  +</figure>
   
  +<figure id="SessionHome.java"><title>The Session Beans Home Interface</title>
  +<programlisting>
   import javax.ejb.*;
   import java.rmi.*;
   
  -public interface StatelessSessionHome extends EJBHome
  +public interface SessionHome extends EJBHome
   {
  -    public StatelessSession create() throws RemoteException, CreateException;
  +    public Session create() throws RemoteException, CreateException;
   }
  -
  -StatelessSessionBean.java
  +</programlisting>
  +</figure>
   
  +<figure id="StatelessSessionBean.java"><title>The Stateless Session Bean</title>
  +<programlisting>
   import java.rmi.RemoteException;
   import java.security.Principal;
   import javax.ejb.*;
   
  +/**
  +@ejbHome: SessionHome
  +@ejbRemote: Session
  +*/
   public class StatelessSessionBean implements SessionBean
   {
       private SessionContext sessionContext;
  @@ -350,51 +504,118 @@
       }
   
   }
  -
   </programlisting>
  +</figure>
   
  -<para>ejb-jar.xml</para>
  +<figure id="StatefulSessionBean.java"><title>The Stateful Session Bean</title>
  +<programlisting>
  +import java.rmi.RemoteException;
  +import java.security.Principal;
  +import javax.ejb.*;
   
  -<programlisting><![CDATA[
  +/**
  +@ejbHome: SessionHome
  +@ejbRemote: Session
  +*/
  +public class StatefulSessionBean implements SessionBean
  +{
  +    private SessionContext sessionContext;
  +
  +    public void ejbCreate() throws RemoteException, CreateException
  +    {
  +        System.out.println("StatefulSessionBean.ejbCreate() called");
  +    }
  +
  +    public void ejbActivate() throws RemoteException
  +    {
  +        System.out.println("StatelessSessionBean.ejbActivate() called");
  +    }
  +
  +    public void ejbPassivate() throws RemoteException
  +    {
  +        System.out.println("StatefulSessionBean.ejbPassivate() called");
  +    }
  +
  +    public void ejbRemove() throws RemoteException
  +    {
  +        System.out.println("StatefulSessionBean.ejbRemove() called");
  +    }
  +
  +    public void setSessionContext(SessionContext context) throws RemoteException
  +    {
  +        sessionContext = context;
  +    }
  +
  +    public String echo(String arg)
  +    {
  +        System.out.println("StatefulSessionBean.echo, arg="+arg);
  +        Principal p = sessionContext.getCallerPrincipal();
  +        System.out.println("StatefulSessionBean.echo, callerPrincipal="+p);
  +        return arg;
  +    }
  +}
  +</programlisting>
  +</figure>
  +
  +<figure id="ejb-jar.xml"><title>The ejb-jar Deployment Descriptor</title>
  +<programlisting>
  +<![CDATA[
   <?xml version="1.0"?>
   <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 
1.1//EN"
       "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">
   
   <ejb-jar>
  -        <display-name>SecurityTests</display-name>
  -        <enterprise-beans>
  -                <session>
  -                        <description>A trival echo bean</description>
  -                        <ejb-name>StatelessSession</ejb-name>
  -                        <home>StatelessSessionHome</home>
  -                        <remote>StatelessSession</remote>
  -                        <ejb-class>StatelessSessionBean</ejb-class>
  -                        <session-type>Stateless</session-type>
  -                        <transaction-type>Container</transaction-type>
  -                </session>
  +    <display-name>SecurityTests</display-name>
  +    <enterprise-beans>
  +        <session>
  +            <description>A trival stateless session echo bean</description>
  +            <ejb-name>StatelessSession</ejb-name>
  +            <home>SessionHome</home>
  +            <remote>Session</remote>
  +            <ejb-class>StatelessSessionBean</ejb-class>
  +            <session-type>Stateless</session-type>
  +            <transaction-type>Container</transaction-type>
  +        </session>
  +
  +        <session>
  +            <description>A trival stateful session echo bean</description>
  +            <ejb-name>StatefulSession</ejb-name>
  +            <home>SessionHome</home>
  +            <remote>Session</remote>
  +            <ejb-class>StatelessSessionBean</ejb-class>
  +            <session-type>Stateful</session-type>
  +            <transaction-type>Container</transaction-type>
  +        </session>
       </enterprise-beans>
   
  -        <assembly-descriptor>
  -                <security-role>
  -                        <role-name>Echo</role-name>
  -                </security-role>
  -
  -                <method-permission>
  -                        <role-name>Echo</role-name>
  -                        <method>
  -                                <ejb-name>StatelessSession</ejb-name>
  -                                <method-name>*</method-name>
  -                        </method>
  -                </method-permission>
  +    <assembly-descriptor>
  +        <security-role>
  +            <role-name>Echo</role-name>
  +        </security-role>
  +
  +        <method-permission>
  +            <role-name>Echo</role-name>
  +            <method>
  +                <ejb-name>StatelessSession</ejb-name>
  +                <method-name>*</method-name>
  +            </method>
  +        </method-permission>
  +
  +        <method-permission>
  +            <role-name>Echo</role-name>
  +            <method>
  +                <ejb-name>StatefulSession</ejb-name>
  +                <method-name>*</method-name>
  +            </method>
  +        </method-permission>
       </assembly-descriptor>
   </ejb-jar>
   ]]></programlisting>
  -
  -<para>StatelessSessionClient.java</para>
  -
  -
  -<programlisting><![CDATA[
  +</figure>
   
  +<figure id="SessionClient.java"><title>The Client</title>
  +<programlisting>
  +<![CDATA[
   import java.io.IOException;
   import javax.naming.InitialContext;
   import javax.rmi.PortableRemoteObject;
  @@ -405,9 +626,9 @@
   where ${jboss_home} is the location of your JBoss distribution.
   
   @author [EMAIL PROTECTED]
  -@version $Revision: 1.1 $
  +@version $Revision: 1.2 $
   */
  -public class StatelessSessionClient
  +public class SessionClient
   {
       static class AppCallbackHandler implements CallbackHandler
       {
  @@ -465,12 +686,20 @@
   
           try
           {
  -            InitialContext jndiContext = new InitialContext();
  -            StatelessSessionHome home = (StatelessSessionHome) 
jndiContext.lookup("StatelessSession");
  +            InitialContext iniContext = new InitialContext();
  +            SessionHome home = (SessionHome) iniContext.lookup("StatelessSession");
               System.out.println("Found StatelessSessionHome");
  -            StatelessSession bean = home.create();
  +            Session bean = home.create();
               System.out.println("Created StatelessSession");
               System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
  +            bean.remove();
  +
  +            home = (SessionHome) iniContext.lookup("StatefulSession");
  +            System.out.println("Found StatefulSessionHome");
  +            bean = home.create();
  +            System.out.println("Created StatefulSession");
  +            System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
  +            bean.remove();
           }
           catch(Exception e)
           {
  @@ -479,264 +708,294 @@
       }
   }
   ]]></programlisting>
  +</figure>
   
  -
   <para>
  -The session bean is trivial. The client is also trivial except for the use of a 
JAAS LoginContext and CallbackHandler implementation. This is how a client
  -establishes the username and password that is sent to jboss. Now, finally let's put 
everything together and deploy the session bean. </para>
  +The session beans are trivial and both the stateless and stateful bean use the
  +same home and remote interfaces. The client is also trivial except for the use
  +of a JAAS LoginContext and CallbackHandler implementation. This is how a client
  +establishes the username and password that is sent to jboss.
  +Now, finally let's put everything together and deploy the session bean.
  +</para>
   
   </section>
   
   <section id="jaas5"><title>Deploying a Bean with Security</title>
  -
   <para>
  -We will perform the following steps to deploy and test the secured session bean: 
</para>
  -
  -   <orderedlist>
  -   <listitem><para>Compile the session bean and client </para></listitem>
  -   <listitem><para>Create the session bean ejb-jar with the ejb-jar.xml and 
jboss.xml security elements </para></listitem>
  -   <listitem><para>Edit the users.properties and roles.properties </para></listitem>
  -   <listitem><para>Deploy the session bean jar, users.properties and 
roles.properties </para></listitem> 
  -   <listitem><para>Edit the JBoss server jboss.jcml and auth.conf files 
</para></listitem> 
  -   <listitem><para>Start the JBoss server </para></listitem>
  -   <listitem><para>Setup client env and test access to the session bean 
</para></listitem>
  -   </orderedlist>
  -
  -<para>
  -Compile the session bean and client
  +This section details the procedure for building, deploying and testing
  +the secured ejb-jar.
  +The steps I'll go through are on a windows 2000 box using the cygwin port
  +of the GNU tools, so most things will look like unix with the exception of
  +the ';' path separator used in the java classpath.
   </para>
  -
  -<para>
  -The examples I'll go through are on a windows 2000 box using the cygwin port of the 
GNU tools. So most things will look like unix with the exception of
  -the ';' path separator used in the java classpath. </para>
  -
  -<para>
  -First save all of the files presented in this document. You should have the 
following 6 files: </para>
  -
  -<literallayout>
  -<command>
  -bash 1066>ls
  -StatelessSession.java        StatelessSessionHome.java
  -StatelessSessionBean.java    ejb-jar.xml
  -StatelessSessionClient.java  jboss.xml
  -</command></literallayout>
  -
  -<para>
  -Next, setup the classpath as follows by substituting the value for jboss_home 
appropriate for your system. </para>
  -
  -<literallayout><command>
  -bash 1068>export CLASSPATH="${jboss_home}/client/jaas.jar"
  -bash 1069>CLASSPATH="${CLASSPATH};${jboss_home}/client/ejb.jar"
  -bash 1070>CLASSPATH="${CLASSPATH};${jboss_home}/client/jnp-client.jar"
  -bash 1071>CLASSPATH="${CLASSPATH};${jboss_home}/client/jboss-client.jar"
  -bash 1072>CLASSPATH="${CLASSPATH};."
  -bash 1073>echo $CLASSPATH
  
-D:/usr/local/src/cvsroot/jBoss/jboss/dist/client/jaas.jar;D:/usr/local/src/cvsroot/jBoss/jboss/dist/client/ejb.jar;\
  
-D:/usr/local/src/cvsroot/jBoss/jboss/dist/client/jnp-client.jar;D:/usr/local/src/cvsroot/jBoss/jboss/dist/client/jboss-client.jar;.
  -</command></literallayout>
  -
  -<para>
  -Next, compile all of the source. </para>
  -
  -<literallayout><command>
  -bash 1077>javac -g *.java
  -bash 1078>ls
  -StatelessSession.class
  -StatelessSession.java
  -StatelessSessionBean.class
  -StatelessSessionBean.java
  -StatelessSessionClient$AppCallbackHandler.class
  -StatelessSessionClient.class
  -StatelessSessionClient.java
  -StatelessSessionHome.class
  -StatelessSessionHome.java
  -ejb-jar.xml
  -jboss.xml
  -</command></literallayout>
  -
  -<para>
  -Create the session bean ejb-jar with the ejb-jar.xml and jboss.xml security 
elements</para>
  -
  -<para>
  -Next, create the session bean jar as follows: </para>
  -
  -<literallayout><command>
  -bash 1087>jar -cf $jboss_home/deploy/ssbean.jar StatelessSession.class 
  -StatelessSessionBean.class StatelessSessionHome.class META-INF
  -bash 1087>jar -tf $jboss_home/deploy/ssbean.jar
  -META-INF/
  -META-INF/MANIFEST.MF
  -StatelessSession.class
  -StatelessSessionBean.class
  -StatelessSessionHome.class
  -META-INF/ejb-jar.xml
  -META-INF/jboss.xml
  -</command></literallayout>
  -
  -<para>
  -Edit the users.properties and roles.properties</para>
  -
  -<para>
  -Create a users.properties and roles.properties with the following data in each 
file: </para>
  -
  -<literallayout>
  -<command>
  -bash 1090>cat users.properties
  -scott=echoman
  -stark=javaman
  -bash 1091>cat roles.properties
  -scott=Echo
  -stark=Java,Coder
  -bash 1092>
  -
  -</command></literallayout>
  -
  -<para>
  -Deploy the session bean jar, users.properties and roles.properties </para>
   
  -<para>
  -We already deployed the session bean jar by jaring the files to the 
$jboss_home/deploy directory. To deploy the users.properties and roles.properties
  -simply copy them to to the $jboss_home/conf/default directory. </para>
  -
  -<para>
  -Edit the JBoss server jboss.jcml and auth.conf files</para>
  +<procedure><title>Deployment Steps</title>
  +<step>
  +<para>Compile the session bean and client
  +</para>
  +    <substeps>
  +    <step>
  +    <para>Save all of the files presented in the figures of this document:
  +    <itemizedlist>
  +        <listitem><para><link linkend="jboss.xml">jboss.xml</link></para></listitem>
  +        <listitem><para><link linkend="auth.conf">auth.conf</link></para></listitem>
  +        <listitem><para><link 
linkend="Session.java">Session.java</link></para></listitem>
  +        <listitem><para><link 
linkend="SessionHome.java">SessionHome.java</link></para></listitem>
  +        <listitem><para><link 
linkend="StatelessSessionBean.java">StatelessSessionBean.java</link></para></listitem>
  +        <listitem><para><link 
linkend="StatefulSessionBean.java">StatefulSessionBean.java</link></para></listitem>
  +        <listitem><para><link 
linkend="ejb-jar.xml">ejb-jar.xml</link></para></listitem>
  +        <listitem><para><link 
linkend="SessionClient.java">SessionClient.java</link></para></listitem>
  +    </itemizedlist>
  +    This will give you the following 8 files:
  +    </para>
  +
  +    <literallayout>
  +    <command>
  +    howto-jaas 1053>ls
  +    Session.java        StatefulSessionBean.java   ejb-jar.xml
  +    SessionClient.java  StatelessSessionBean.java  jboss.xml
  +    SessionHome.java    auth.conf
  +    </command></literallayout>
  +    </step>
  +
  +    <step>
  +    <para>Create a users.properties and roles.properties with the following
  +    data in each file: </para>
  +
  +    <literallayout>
  +    <command>
  +    bash 1090>cat users.properties
  +    scott=echoman
  +    stark=javaman
  +    bash 1091>cat roles.properties
  +    scott=Echo
  +    stark=Java,Coder
  +    scott.CallerPrincipal=caller_scott
  +    stark.CallerPrincipal=caller_stark
  +    bash 1092>
  +
  +    </command></literallayout>
  +    </step>
  +
  +    <step>
  +    <para>
  +    Next, setup the classpath as follows by substituting the value for jboss_home
  +    appropriate for your system. For example, I'm using jboss_home is a
  +    fresh build from cvs and jboss_home=/tmp/cvs/jboss/dist.
  +    </para>
  +
  +    <literallayout><command>
  +    howto-jaas 1055>export jboss_home=/tmp/cvs/jboss/dist
  +    howto-jaas 1056>export CLASSPATH="${jboss_home}/client/jaas.jar"
  +    howto-jaas 1057>CLASSPATH="${CLASSPATH};${jboss_home}/client/ejb.jar"
  +    howto-jaas 1058>CLASSPATH="${CLASSPATH};${jboss_home}/client/jnp-client.jar"
  +    howto-jaas 1059>CLASSPATH="${CLASSPATH};${jboss_home}/client/jboss-client.jar"
  +    howto-jaas 1060>CLASSPATH="${CLASSPATH};${jboss_home}/client/jbosssx-client.jar"
  +    howto-jaas 1061>CLASSPATH="${CLASSPATH};."
  +    howto-jaas 1062>echo $CLASSPATH
  +    
/tmp/cvs/jboss/dist/client/jaas.jar;/tmp/cvs/jboss/dist/client/ejb.jar;/tmp/cvs/jboss/dist/client/jnp-client.jar;/tmp/cvs/jboss/dist/client/jboss-client.jar;/tmp/cvs/jboss/dist/client/jbosssx-client.jar;.
  +    </command></literallayout>
  +    </step>
  +
  +    <step>
  +    <para>Next, compile all of the source. </para>
  +
  +    <literallayout><command>
  +    howto-jaas 1087>javac -g *.java
  +    howto-jaas 1088>ls
  +    Session.class                           StatefulSessionBean.java
  +    Session.java                            StatelessSessionBean.class
  +    SessionClient$AppCallbackHandler.class  StatelessSessionBean.java
  +    SessionClient.class                     auth.conf
  +    SessionClient.java                      ejb-jar.xml
  +    SessionHome.class                       jboss.xml
  +    SessionHome.java                        roles.properties
  +    StatefulSessionBean.class               users.properties
  +    </command></literallayout>
  +    </step>
  +    </substeps>
  +</step>
  +
  +<step>
  +<para>Create the session bean ejb-jar with the ejb-jar.xml and jboss.xml security
  +elements</para>
  +
  +<para>Next, create the session bean jar as follows:</para>
  +    <substeps>
  +    <step>
  +    <literallayout><command>
  +    howto-jaas 1089>mkdir META-INF
  +    howto-jaas 1090>mv *.xml META-INF
  +    howto-jaas 1091>jar -cf $jboss_home/deploy/ssbean.jar Session.class 
SessionHome.class StatefulSessionBean.class StatelessSessionBean.class 
roles.properties users.properties META-INF
  +    howto-jaas 1092>jar -tf $jboss_home/deploy/ssbean.jar
  +    META-INF/
  +    META-INF/MANIFEST.MF
  +    Session.class
  +    SessionHome.class
  +    StatefulSessionBean.class
  +    StatelessSessionBean.class
  +    roles.properties
  +    users.properties
  +    META-INF/ejb-jar.xml
  +    META-INF/jboss.xml
  +    </command></literallayout>
  +    </step>
  +
  +    </substeps>
  +</step>
  +
  +<step>
  +<para>Deploy the session bean jar. We already deployed the session bean jar by
  +jaring the files to the $jboss_home/deploy directory. The deploy directory is
  +where the JBoss server's autodeploy process looks for ejb jars.
  +</para>
  +</step>
   
  -<para>
  -These files needs to be setup as described earlier. The jboss.jcml file needs to 
have the JaasSecurityManagerService mbean element:</para>
  +<step>
  +<para>Edit the JBoss server jboss.jcml and auth.conf files.
  +These files need to be setup as described earlier.</para>
  +    <substeps>
  +    <step>
  +    <para>The $jboss_home/conf/default/jboss.jcml file needs to have the
  +    JaasSecurityManagerService mbean element setup as follows:</para>
   
   <programlisting><![CDATA[
  -...
   <!-- JAAS security manager and realm mapping -->
  -  <mbean code="org.jboss.security.plugins.JaasSecurityManagerService" 
name="DefaultDomain:service=JaasSecurityManager" />
  -
  -and the auth.conf needs to have the JaasServerLoginModule entry in the other 
section: 
  -
  -...
  -// The default server login module
  -other {
  -    // A realistic server login module, which can be used when the number 
  -    // of users is relatively small. It uses two properties files:
  -    //   users.properties, which holds users (key) and their password (value).
  -    //   roles.properties, which holds users (key) and a comma-separated list of 
their roles (value).
  -    org.jboss.security.plugins.samples.JaasServerLoginModule required;
  -
  -    // For database based authentication comment the line above,
  -    // uncomment the line below and adjust the parameters in quotes
  -    // Database server login module provides security manager only, no role mapping
  -    // org.jboss.security.plugins.DatabaseServerLoginModule required 
db="jdbc/DbJndiName" 
  -    table="UserTable" name="UserNameColumn" password="UserPswColumn";
  -};
  +<mbean code="org.jboss.security.plugins.JaasSecurityManagerService" 
name="Secuty:name=JaasSecurityManager">
  +  <attribute 
name="SecurityManagerClassName">org.jboss.security.plugins.JaasSerityManager</attribute>
  +</mbean>
   ]]></programlisting>
  -
  +    </step>
   
  -
  -<para>
  -Start the JBoss server</para>
  -
  -<para>
  -Go to the $jboss_home/bin and start the run.sh or run.bat script as appropriate for 
you system. You will see a good deal of ouput on your console. Mine
  -looks like, and I have emphasized the session bean deployment output. </para>
  +    <step>
  +    <para>Copy the auth.conf that you created from Figure <xref linkend="auth.conf" 
/> to
  +    $jboss_home/conf/default and overwrite the existing file.</para>
  +    <literallayout><computeroutput><![CDATA[
  +    howto-jaas 1103>cp auth.conf $jboss_home/conf/default
  +    cp: overwrite '/tmp/cvs/jboss/dist/conf/default/auth.conf'? y
  +    ]]></computeroutput></literallayout>
  +    </step>
  +    </substeps>
  +</step>
  +
  +<step>
  +<para>Start the JBoss server.
  +Go to the $jboss_home/bin directory and use the run.sh or run.bat script as
  +appropriate for you system to start the JBoss server. You will see a good
  +deal of ouput on your console. Below is some console output and I have
  +emphasized the session bean deployment output.
  +</para>
   
  -<literallayout><computeroutput>
  -811>run.bat
  +<literallayout><computeroutput><![CDATA[
  +bin 608>run.bat
   Using configuration "default"
   [Info] Java version: 1.3.0_01,Sun Microsystems Inc.
   [Info] Java VM: Java HotSpot(TM) Client VM 1.3.0_01,Sun Microsystems Inc.
   [Info] System: Windows 2000 5.0,x86
   [Shutdown] Shutdown hook added
   [Service Control] Registered with server
  -[Jetty] Setting unpackWars=false
  -[Jetty] Set successfully
  -[Jetty] Adding configuration: URL=file:/usr/local/src/cvsroot/jBoss/jboss/
  -dist/conf/default/jetty.xml
  -[Jetty] Added successfully
  -[Service Control] Initializing 18 MBeans
  -[Webserver] Initializing
  -[Webserver] Initialized
  -[Naming] Initializing
  -[Naming] Initialized
  +[Service Control] Initializing 24 MBeans
   ...
  -[J2EE Deployer Default] Starting
  -[J2EE Deployer Default] Cleaning up deployment directory
  -[J2EE Deployer Default] Started
  +]]><emphasis>
   [Auto deploy] Starting
  -[Auto deploy] Watching D:\usr\local\src\cvsroot\jBoss\jboss\dist\deploy
  -
  -[Auto deploy] Auto deploy of 
file:/D:/usr/local/src/cvsroot/jBoss/jboss/dist/deploy/ssbean.jar
  -[J2EE Deployer Default] Deploy J2EE application: 
file:/D:/usr/local/src/cvsroot/jBoss/
  -jboss/dist/deploy/ssbean.jar
  +[Auto deploy] Watching D:\tmp\cvs\jboss\dist\deploy
  +[Auto deploy] Auto deploy of file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar
  +[J2EE Deployer Default] Deploy J2EE application: 
file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar
   [J2EE Deployer Default] Create application ssbean.jar
   [J2EE Deployer Default] install module ssbean.jar
  -[J2EE Deployer Default] Starting module ssbean.jar
  -[Container factory] Deploying:file:/D:/usr/local/src/cvsroot/
  -jBoss/jboss/dist/tmp/deploy/Default/ssbean.jar/ejb1001.jar
  -
  -[Verifier] Verifying 
file:/D:/usr/local/src/cvsroot/jBoss/jboss/dist/tmp/deploy/Default/ssbean.jar/ejb1001.jar
  +[Container factory] 
Deploying:file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar
  +[Verifier] Verifying 
file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar/ejb1001.jar
   [Container factory] Deploying StatelessSession
  -[Container factory] Deployed application: file:/D:/usr/local/src/cvsroot/
  -jBoss/jboss/dist/tmp/deploy/Default/ssbean.jar/ejb1001.jar
  -[J2EE Deployer Default] J2EE application: file:/D:/usr/local/src/cvsroot/
  -jBoss/jboss/dist/deploy/ssbean.jar is deployed.
  -
  -[Auto deploy] Started
  -[JMX RMI Adaptor] Starting
  -[JMX RMI Adaptor] Started
  -[JMX RMI Connector] Starting
  -[JMX RMI Connector] Started
  -[Service Control] Started 18 services
  -[Default] JBoss PRE-2.1 Started
  -</computeroutput></literallayout>
  -
  -
  -<para>
  -Setup client env and test access to the session bean</para>
  -
  -<para>
  -At this point the session bean is deployed and it should only be accessible by 
users with a role of 'Echo', and we have one user with a username 'scott'
  -and a password 'echoman' that has this role. We have another user with a username 
'stark' and a password 'javaman' that should not be able to
  -acccess the session bean because he does not have the required role. Let's test 
this. </para>
  -
  -<para>
  -We need one final bit of information in order for the client to find the JBoss 
server JNDI name service. Since we are using a no arg InitialContext in the
  -client, we need a jndi.properties file in our classpath(or we need to specify all 
required properities on the command line). For JBoss, the jndi.properties
  -file should look like the following for the server running on the localhost with 
the default name service port: </para>
  -
  -<literallayout><computeroutput>
  -bash 1108>cat jndi.properties
  -# JNDI initial context properties for jboss app server
  -java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
  -java.naming.provider.url=localhost
  -java.naming.factory.url.pkgs=org.jboss.naming
  -</computeroutput>
  -</literallayout>
  -
  -
  -<para>
  -Create this file in the same directory as your StatelessSessionClient.java file 
since this directory is on the classpath we setup earlier. Now, run the client
  -as user scott and specify the location of the JBoss client side JAAS login 
configuration file as follows: </para>
  -
  -<literallayout><computeroutput>
  -bash 1109>java 
-Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf 
StatelessSessionClient scott echoman
  -Created LoginContext
  -Found StatelessSessionHome
  -Created StatelessSession
  -Bean.echo('Hello') -> Hello
  -
  ---- Server console:
  -[StatelessSession] StatelessSessionBean.ejbCreate() called
  -[StatelessSession] StatelessSessionBean.echo, arg=Hello
  -[StatelessSession] StatelessSessionBean.echo, callerPrincipal=scott
  +[Container factory] lookup securityManager name: java:/jaas/other
  +[Container factory] JAAS.Created 
securityMgr=org.jboss.security.plugins.JaasSecurityManager@5f1832
  +[Container factory] JAAS.setCachePolicy, c=null
  +[Container factory] JAAS.Added other, 
org.jboss.security.plugins.JaasSecurityManager@5f1832 to map
  +[Container factory] JAAS.Created 
securityMgr=org.jboss.security.plugins.JaasSecurityManager@2d8659
  +[Container factory] JAAS.setCachePolicy, c=null
  +[Container factory] JAAS.Added session-roles, 
org.jboss.security.plugins.JaasSecurityManager@2d8659 to map
  +[Container factory] Deploying StatefulSession
  +[Container factory] lookup securityManager name: java:/jaas/other
  +[Bean Cache] Cache policy scheduler started
  +[Container factory] Deployed application: 
file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar
  +[J2EE Deployer Default] J2EE application: 
file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar is deployed.
  +</emphasis>
  +...
  +[Service Control] Started 24 services
  +[Default] JBoss PRE-2.1 Started in 0m:10s
   </computeroutput></literallayout>
  +</step>
   
  +<step>
  +<para>Setup client env and test access to the session bean</para>
   <para>
  -Ok, so that succeed as desired. Now we need to make sure that unauthorized users 
are actually denied access. This time run as user stark:</para> 
  -
  -<literallayout><computeroutput>
  -bash 1111>java 
-Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf 
StatelessSessionClient stark javaman
  -Created LoginContext
  -Found StatelessSessionHome
  -java.rmi.ServerException: RemoteException occurred in server thread; nested 
exception is:
  +    At this point the session bean is deployed and it should only be accessible by
  +    users with a role of 'Echo', and we have one user with a username 'scott'
  +    and a password 'echoman' that has this role. We have another user with a
  +    username 'stark' and a password 'javaman' that should not be able to
  +    acccess the session bean because he does not have the required role. We
  +    need to setup the client env and run the client to test this.
  +</para>
  +<substeps>
  +    <step>
  +    <para>
  +    We need one final bit of information in order for the client to find the JBoss 
server
  +    JNDI name service. Since we are using a no arg InitialContext in the
  +    client, we need a jndi.properties file in our classpath(or we need to specify 
all
  +    required properities on the command line). For JBoss, the jndi.properties
  +    file should look like the following for the server running on the localhost with
  +    the default name service port: </para>
  +
  +    <literallayout><computeroutput>
  +    bash 1108>cat jndi.properties
  +    # JNDI initial context properties for jboss app server
  +    java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
  +    java.naming.provider.url=localhost
  +    java.naming.factory.url.pkgs=org.jboss.naming
  +    </computeroutput></literallayout>
  +
  +    <para>
  +    Create this file in the same directory as your SessionClient.java file since
  +    this directory is on the classpath we setup earlier.</para>
  +    </step>
  +
  +    <step><para>Now, run the client as user scott and specify the location of
  +    the JBoss client side JAAS login configuration file as follows: </para>
  +    <literallayout><computeroutput><![CDATA[
  +    --- Client:
  +    howto-jaas 1133>java 
-Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient 
scott echoman
  +    Created LoginContext
  +    Found StatelessSessionHome
  +    Created StatelessSession
  +    Bean.echo('Hello') -> Hello
  +    Found StatefulSessionHome
  +    Created StatefulSession
  +    Bean.echo('Hello') -> Hello
  +
  +    --- Server console:
  +    [JAASSecurity] User 'scott' authenticated.
  +    [JAASSecurity] User 'scott' authenticated.
  +    [StatelessSession] StatelessSessionBean.ejbCreate() called
  +    [StatelessSession] StatelessSessionBean.echo, arg=Hello
  +    [StatelessSession] StatelessSessionBean.echo, callerPrincipal=caller_scott
  +    [StatefulSession] StatelessSessionBean.ejbCreate() called
  +    [StatefulSession] StatelessSessionBean.echo, arg=Hello
  +    [StatefulSession] StatelessSessionBean.echo, callerPrincipal=scott
  +    [StatefulSession] StatelessSessionBean.ejbRemove() called
  +    ]]></computeroutput></literallayout>
  +    </step>
  +
  +    <step>
  +    <para>Ok, so that succeed as desired. Now we need to make sure that unauthorized
  +    users are actually denied access. This time run as user stark:</para> 
  +
  +    <literallayout><computeroutput>
  +    --- Client:
  +    howto-jaas 1135>java 
-Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient 
stark javaman
  +    Created LoginContext
  +    Found StatelessSessionHome
  +    java.rmi.ServerException: RemoteException occurred in server thread; nested 
exception is:
           java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
  +
           java.lang.SecurityException: Illegal access exception
   java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
           java.lang.SecurityException: Illegal access exception
  @@ -745,69 +1004,81 @@
           at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)
           at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)
           at 
org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)
  -        at 
org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:221)
  +        at 
org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:248)
           at $Proxy0.create(Unknown Source)
  -        at StatelessSessionClient.main(StatelessSessionClient.java:74)
  -
  ---- Server console: No new output
  -</computeroutput></literallayout>
  -
  +        at SessionClient.main(SessionClient.java:74)
   
  -<para>
  -Alright, seems secure. Let's try user scott with an invalid password: </para>
  -
  -<literallayout>
  -<computeroutput>
  -bash 1113>java 
-Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf 
StatelessSessionClient scott badpass
  -Created LoginContext
  -Found StatelessSessionHome
  -java.rmi.ServerException: RemoteException occurred in server thread; nested 
exception is:
  +    --- Server console:
  +    [JAASSecurity] User 'stark' authenticated.
  +    [JAASSecurity] User 'stark' authenticated.
  +    [StatelessSession] Illegal access, principal=stark
  +    </computeroutput></literallayout>
  +    </step>
  +
  +    <step>
  +    <para>Alright, seems secure. Let's try user scott with an invalid password: 
</para>
  +
  +    <literallayout><computeroutput><![CDATA[
  +    --- Client:
  +    howto-jaas 1137>java 
-Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient 
scott badpass
  +    Created LoginContext
  +    Found StatelessSessionHome
  +    java.rmi.ServerException: RemoteException occurred in server thread; nested 
exception is:
           java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
  +
           java.lang.SecurityException: Authentication exception
  -java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
  +    java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
           java.lang.SecurityException: Authentication exception
  -java.lang.SecurityException: Authentication exception
  +    java.lang.SecurityException: Authentication exception
           at 
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)
           at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)
           at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)
           at 
org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)
  -        at 
org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:221)
  +        at 
org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:248)
           at $Proxy0.create(Unknown Source)
  -        at StatelessSessionClient.main(StatelessSessionClient.java:74)
  -
  ---- Server console:
  -[JAASSecurity] Bad password.
  -[StatelessSession] javax.security.auth.login.FailedLoginException: Password 
Incorrect/Password Required
  -[StatelessSession]      at 
org.jboss.security.plugins.AbstractServerLoginModule.login(AbstractServerLoginModule.java:110)
  -[StatelessSession]      at 
org.jboss.security.plugins.samples.JaasServerLoginModule.login(JaasServerLoginModule.java:94)
  -[StatelessSession]      at java.lang.reflect.Method.invoke(Native Method)
  -[StatelessSession]      at 
javax.security.auth.login.LoginContext.invoke(LoginContext.java:595)
  -[StatelessSession]      at 
javax.security.auth.login.LoginContext.access$000(LoginContext.java:125)
  -[StatelessSession]      at 
javax.security.auth.login.LoginContext$3.run(LoginContext.java:531)
  -[StatelessSession]      at java.security.AccessController.doPrivileged(Native 
Method)
  -[StatelessSession]      at 
javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:528)
  -[StatelessSession]      at 
javax.security.auth.login.LoginContext.login(LoginContext.java:449)
  -[StatelessSession]      at 
org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:168)
  -[StatelessSession]      at 
org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:101)
  -[StatelessSession]      at 
org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:101)
  -[StatelessSession]      at 
org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:124)
  -[StatelessSession]      at 
org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:106)
  -[StatelessSession]      at 
org.jboss.ejb.StatelessSessionContainer.invokeHome(StatelessSessionContainer.java:253)
  -[StatelessSession]      at 
org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invokeHome(JRMPContainerInvoker.java:347)
  -[StatelessSession]      at java.lang.reflect.Method.invoke(Native Method)
  -[StatelessSession]      at 
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
  -[StatelessSession]      at sun.rmi.transport.Transport$1.run(Transport.java:142)
  -[StatelessSession]      at java.security.AccessController.doPrivileged(Native 
Method)
  -[StatelessSession]      at 
sun.rmi.transport.Transport.serviceCall(Transport.java:139)
  -[StatelessSession]      at 
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
  -[StatelessSession]      at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
  -[StatelessSession]      at java.lang.Thread.run(Thread.java:484)
  -</computeroutput>
  -</literallayout>
  +        at SessionClient.main(SessionClient.java:74)
   
  -<para>
  -Mission accomplished. 
  +    --- Server console:
  +    [JAASSecurity] Bad password.
  +    [StatelessSession] javax.security.auth.login.FailedLoginException: Password 
Incorrect/Password Required
  +    [StatelessSession]      at 
org.jboss.security.plugins.AbstractServerLoginModule.login(AbstractServerLoginModule.java:141)
  +    [StatelessSession]      at 
org.jboss.security.plugins.samples.JaasServerLoginModule.login(JaasServerLoginModule.java:94)
  +    [StatelessSession]      at java.lang.reflect.Method.invoke(Native Method)
  +    [StatelessSession]      at 
javax.security.auth.login.LoginContext.invoke(LoginContext.java:595)
  +    [StatelessSession]      at 
javax.security.auth.login.LoginContext.access$000(LoginContext.java:125)
  +    [StatelessSession]      at 
javax.security.auth.login.LoginContext$3.run(LoginContext.java:531)
  +    [StatelessSession]      at java.security.AccessController.doPrivileged(Native 
Method)
  +    [StatelessSession]      at 
javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:528)
  +    [StatelessSession]      at 
javax.security.auth.login.LoginContext.login(LoginContext.java:449)
  +    [StatelessSession]      at 
org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:291)
  +    [StatelessSession]      at 
org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:260)
  +    [StatelessSession]      at 
org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:149)
  +    [StatelessSession]      at 
org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:196)
  +    [StatelessSession]      at 
org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:131)
  +    [StatelessSession]      at 
org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:106)
  +    [StatelessSession]      at 
org.jboss.ejb.StatelessSessionContainer.invokeHome(StatelessSessionContainer.java:253)
  +    [StatelessSession]      at 
org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invokeHome(JRMPContainerInvoker.java:358)
  +    [StatelessSession]      at java.lang.reflect.Method.invoke(Native Method)
  +    [StatelessSession]      at 
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
  +    [StatelessSession]      at sun.rmi.transport.Transport$1.run(Transport.java:142)
  +    [StatelessSession]      at java.security.AccessController.doPrivileged(Native 
Method)
  +    [StatelessSession]      at 
sun.rmi.transport.Transport.serviceCall(Transport.java:139)
  +    [StatelessSession]      at 
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
  +    [StatelessSession]      at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
  +    [StatelessSession]      at java.lang.Thread.run(Thread.java:484)
  +    [StatelessSession] Authentication exception, principal=scott
  +    ]]></computeroutput></literallayout>
  +    </step>
  +    </substeps>
  +</step>
  +</procedure>
  +</section>
   
  +<section><title>Wrap Up</title>
  +<para>This has been an introduction to the steps required to enable security
  +for EJB containers. Support for more advanced customization of security is
  +documented in the JBossSX chapter.
   </para>
  +</section>
  +
   </section>
  -</section>
  \ No newline at end of file
  
  
  

Reply via email to