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