Author: markt
Date: Wed Sep  3 15:18:39 2008
New Revision: 691805

URL: http://svn.apache.org/viewvc?rev=691805&view=rev
Log:
Add a new combined Realm that can be used to try authenticating against 
multiple realms.

Added:
    tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java   (with 
props)
    tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java   (with 
props)
Modified:
    tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/startup/ContextRuleSet.java
    tomcat/trunk/java/org/apache/catalina/startup/EngineRuleSet.java
    tomcat/trunk/java/org/apache/catalina/startup/HostRuleSet.java
    tomcat/trunk/webapps/docs/config/realm.xml
    tomcat/trunk/webapps/docs/realm-howto.xml

Added: tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java?rev=691805&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java (added)
+++ tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java Wed Sep  3 
15:18:39 2008
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.realm;
+
+import java.security.Principal;
+
+import java.security.cert.X509Certificate;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.Realm;
+import org.apache.catalina.util.StringManager;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * Realm implementation that contains one or more realms. Authentication is
+ * attempted for each realm in the order they were configured. If any realm
+ * authenticates the user then the authentication succeeds.
+ */
+public class CombinedRealm extends RealmBase {
+
+    private static Log log = LogFactory.getLog(RealmBase.class);
+
+    /**
+     * The string manager for this package.
+     */
+    protected static StringManager sm =
+        StringManager.getManager(Constants.Package);
+    
+    /**
+     * The list of Realms contained by this Realm.
+     */
+       protected List<Realm> realms = new LinkedList<Realm>();
+
+
+       /**
+        * Add a realm to the list of realms that will be used to authenticate
+        * users.
+        */
+       public void addRealm(Realm theRealm) {
+           realms.add(theRealm);
+           
+           if (log.isDebugEnabled()) {
+               sm.getString("combinedRealm.addRealm", theRealm.getInfo(), 
+                       Integer.toString(realms.size()));
+           }
+       }
+
+
+    /**
+     * Return the Principal associated with the specified username and
+     * credentials, if there is one; otherwise return <code>null</code>.
+     *
+     * @param username Username of the Principal to look up
+     * @param credentials Password or other credentials to use in
+     *  authenticating this username
+     */
+    public Principal authenticate(String username, byte[] credentials) {
+        Principal authenticatedUser = null;
+        
+        for (Realm realm : realms) {
+            if (log.isDebugEnabled()) {
+                log.debug(sm.getString("combinedRealm.authStart", username, 
realm.getInfo()));
+            }
+            
+            authenticatedUser = realm.authenticate(username, credentials);
+            
+            if (authenticatedUser == null) {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authFail", username, 
realm.getInfo()));
+                }
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authSucess", 
username, realm.getInfo()));
+                }
+                break;
+            }
+        }
+        return authenticatedUser;
+    }
+
+
+    /**
+     * Return the Principal associated with the specified username, which
+     * matches the digest calculated using the given parameters using the
+     * method described in RFC 2069; otherwise return <code>null</code>.
+     *
+     * @param username Username of the Principal to look up
+     * @param clientDigest Digest which has been submitted by the client
+     * @param nOnce Unique (or supposedly unique) token which has been used
+     * for this request
+     * @param realm Realm name
+     * @param md5a2 Second MD5 digest used to calculate the digest :
+     * MD5(Method + ":" + uri)
+     */
+    public Principal authenticate(String username, String clientDigest,
+            String once, String nc, String cnonce, String qop,
+            String realmName, String md5a2) {
+        Principal authenticatedUser = null;
+        
+        for (Realm realm : realms) {
+            if (log.isDebugEnabled()) {
+                log.debug(sm.getString("combinedRealm.authStart", username, 
realm.getInfo()));
+            }
+
+            authenticatedUser = realm.authenticate(username, clientDigest, 
once,
+                    nc, cnonce, qop, realmName, md5a2);
+
+            if (authenticatedUser == null) {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authFail", username, 
realm.getInfo()));
+                }
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authSucess", 
username, realm.getInfo()));
+                }
+                break;
+            }
+        }
+        return authenticatedUser;
+    }
+
+
+    /**
+     * Return the Principal associated with the specified username and
+     * credentials, if there is one; otherwise return <code>null</code>.
+     *
+     * @param username Username of the Principal to look up
+     * @param credentials Password or other credentials to use in
+     *  authenticating this username
+     */
+    public Principal authenticate(String username, String credentials) {
+        Principal authenticatedUser = null;
+        
+        for (Realm realm : realms) {
+            if (log.isDebugEnabled()) {
+                log.debug(sm.getString("combinedRealm.authStart", username, 
realm.getInfo()));
+            }
+
+            authenticatedUser = realm.authenticate(username, credentials);
+
+            if (authenticatedUser == null) {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authFail", username, 
realm.getInfo()));
+                }
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authSucess", 
username, realm.getInfo()));
+                }
+                break;
+            }
+        }
+        return authenticatedUser;
+    }
+
+
+    /**
+     * Set the Container with which this Realm has been associated.
+     *
+     * @param container The associated Container
+     */
+    public void setContainer(Container container) {
+        // Set the container for sub-realms. Mainly so logging works.
+        for(Realm realm : realms) {
+            realm.setContainer(container);
+        }
+        super.setContainer(container);
+    }
+
+
+    /**
+     * Prepare for the beginning of active use of the public methods of this
+     * component.  This method should be called before any of the public
+     * methods of this component are utilized.  It should also send a
+     * LifecycleEvent of type START_EVENT to any registered listeners.
+     *
+     * @exception LifecycleException if this component detects a fatal error
+     *  that prevents this component from being used
+     */
+    public void start() throws LifecycleException {
+        // Start 'sub-realms' then this one
+        for (Realm realm : realms) {
+            if (realm instanceof Lifecycle) {
+                ((Lifecycle) realm).start();
+            }
+        }
+        super.start();
+    }
+
+
+    /**
+     * Gracefully terminate the active use of the public methods of this
+     * component.  This method should be the last one called on a given
+     * instance of this component.  It should also send a LifecycleEvent
+     * of type STOP_EVENT to any registered listeners.
+     *
+     * @exception LifecycleException if this component detects a fatal error
+     *  that needs to be reported
+     */
+     public void stop() throws LifecycleException {
+        // Stop this realm, then the sub-realms (reverse order to start)
+        super.stop();
+        for (Realm realm : realms) {
+            if (realm instanceof Lifecycle) {
+                ((Lifecycle) realm).stop();
+            }
+        }        
+    }
+
+
+    /**
+     * Return the Principal associated with the specified chain of X509
+     * client certificates.  If there is none, return <code>null</code>.
+     *
+     * @param certs Array of client certificates, with the first one in
+     *  the array being the certificate of the client itself.
+     */
+    public Principal authenticate(X509Certificate[] certs) {
+        Principal authenticatedUser = null;
+        String username = null;
+        if (certs != null && certs.length >0) {
+            username = certs[0].getSubjectDN().getName();
+        }
+        
+        for (Realm realm : realms) {
+            if (log.isDebugEnabled()) {
+                log.debug(sm.getString("combinedRealm.authStart", username, 
realm.getInfo()));
+            }
+
+            authenticatedUser = realm.authenticate(certs);
+
+            if (authenticatedUser == null) {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authFail", username, 
realm.getInfo()));
+                }
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("combinedRealm.authSucess", 
username, realm.getInfo()));
+                }
+                break;
+            }
+        }
+        return authenticatedUser;
+    }
+
+    @Override
+    protected String getName() {
+        // This method should never be called
+        // Stack trace will show where this was called from
+        UnsupportedOperationException uoe =
+            new UnsupportedOperationException(
+                    sm.getString("combinedRealm.getName"));
+        log.error(sm.getString("combinedRealm.unexpectedMethod"), uoe);
+        throw uoe;
+    }
+
+    @Override
+    protected String getPassword(String username) {
+        // This method should never be called
+        // Stack trace will show where this was called from
+        UnsupportedOperationException uoe =
+            new UnsupportedOperationException(
+                    sm.getString("combinedRealm.getPassword"));
+        log.error(sm.getString("combinedRealm.unexpectedMethod"), uoe);
+        throw uoe;
+    }
+
+    @Override
+    protected Principal getPrincipal(String username) {
+        // This method should never be called
+        // Stack trace will show where this was called from
+        UnsupportedOperationException uoe =
+            new UnsupportedOperationException(
+                    sm.getString("combinedRealm.getPrincipal"));
+        log.error(sm.getString("combinedRealm.unexpectedMethod"), uoe);
+        throw uoe;
+    }
+
+}

Propchange: tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author Id

Modified: tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties?rev=691805&r1=691804&r2=691805&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties Wed Sep 
 3 15:18:39 2008
@@ -85,3 +85,11 @@
 dataSourceRealm.getPassword.exception=Exception retrieving password for "{0}"
 dataSourceRealm.getRoles.exception=Exception retrieving roles for "{0}"
 dataSourceRealm.open=Exception opening database connection
+combinedRealm.unexpectedMethod=An unexpected call was made to a method on the 
combined realm
+combinedRealm.getName=The getName() method should never be called
+combinedRealm.getPassword=The getPassword() method should never be called
+combinedRealm.getPrincipal=The getPrincipal() method should never be called
+combinedRealm.authStart=Attempting to authenticate user "{0}" with realm "{1}"
+combinedRealm.authFailed=Failed to authenticate user "{0}" with realm "{1}"
+combinedRealm.authSucess=Authenticated user "{0}" with realm "{1}"
+combinedRealm.addRealm=Add "{0}" realm, making a total of "{1}" realms
\ No newline at end of file

Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextRuleSet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextRuleSet.java?rev=691805&r1=691804&r2=691805&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextRuleSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextRuleSet.java Wed Sep  
3 15:18:39 2008
@@ -170,13 +170,7 @@
                             "addApplicationParameter",
                             "org.apache.catalina.deploy.ApplicationParameter");
 
-        digester.addObjectCreate(prefix + "Context/Realm",
-                                 null, // MUST be specified in the element
-                                 "className");
-        digester.addSetProperties(prefix + "Context/Realm");
-        digester.addSetNext(prefix + "Context/Realm",
-                            "setRealm",
-                            "org.apache.catalina.Realm");
+        digester.addRuleSet(new RealmRuleSet(prefix + "Context/"));
 
         digester.addObjectCreate(prefix + "Context/Resources",
                                  "org.apache.naming.resources.FileDirContext",

Modified: tomcat/trunk/java/org/apache/catalina/startup/EngineRuleSet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/EngineRuleSet.java?rev=691805&r1=691804&r2=691805&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/EngineRuleSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/EngineRuleSet.java Wed Sep  3 
15:18:39 2008
@@ -121,13 +121,7 @@
                             "org.apache.catalina.LifecycleListener");
 
 
-        digester.addObjectCreate(prefix + "Engine/Realm",
-                                 null, // MUST be specified in the element
-                                 "className");
-        digester.addSetProperties(prefix + "Engine/Realm");
-        digester.addSetNext(prefix + "Engine/Realm",
-                            "setRealm",
-                            "org.apache.catalina.Realm");
+        digester.addRuleSet(new RealmRuleSet(prefix + "Engine/"));
 
         digester.addObjectCreate(prefix + "Engine/Valve",
                                  null, // MUST be specified in the element

Modified: tomcat/trunk/java/org/apache/catalina/startup/HostRuleSet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/HostRuleSet.java?rev=691805&r1=691804&r2=691805&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/HostRuleSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/HostRuleSet.java Wed Sep  3 
15:18:39 2008
@@ -124,13 +124,7 @@
                             "addLifecycleListener",
                             "org.apache.catalina.LifecycleListener");
 
-        digester.addObjectCreate(prefix + "Host/Realm",
-                                 null, // MUST be specified in the element
-                                 "className");
-        digester.addSetProperties(prefix + "Host/Realm");
-        digester.addSetNext(prefix + "Host/Realm",
-                            "setRealm",
-                            "org.apache.catalina.Realm");
+        digester.addRuleSet(new RealmRuleSet(prefix + "Host/"));
 
         digester.addObjectCreate(prefix + "Host/Valve",
                                  null, // MUST be specified in the element

Added: tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java?rev=691805&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java (added)
+++ tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java Wed Sep  3 
15:18:39 2008
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina.startup;
+
+
+import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.digester.RuleSetBase;
+
+
+/**
+ * <p><strong>RuleSet</strong> for processing the contents of a Realm 
definition
+ * element.  This <code>RuleSet</code> supports Realms such as the
+ * <code>CombinedRealm</code> that used nested Realms.</p>
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class RealmRuleSet extends RuleSetBase {
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * The matching pattern prefix to use for recognizing our elements.
+     */
+    protected String prefix = null;
+
+
+    // ------------------------------------------------------------ Constructor
+
+
+    /**
+     * Construct an instance of this <code>RuleSet</code> with the default
+     * matching pattern prefix.
+     */
+    public RealmRuleSet() {
+
+        this("");
+
+    }
+
+
+    /**
+     * Construct an instance of this <code>RuleSet</code> with the specified
+     * matching pattern prefix.
+     *
+     * @param prefix Prefix for matching pattern rules (including the
+     *  trailing slash character)
+     */
+    public RealmRuleSet(String prefix) {
+
+        super();
+        this.namespaceURI = null;
+        this.prefix = prefix;
+
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Add the set of Rule instances defined in this RuleSet to the
+     * specified <code>Digester</code> instance, associating them with
+     * our namespace URI (if any).  This method should only be called
+     * by a Digester instance.</p>
+     *
+     * @param digester Digester instance to which the new Rule instances
+     *  should be added.
+     */
+    public void addRuleInstances(Digester digester) {
+
+        digester.addObjectCreate(prefix + "Realm",
+                                 null, // MUST be specified in the element,
+                                 "className");
+        digester.addSetProperties(prefix + "Realm");
+        digester.addSetNext(prefix + "Realm",
+                            "setRealm",
+                            "org.apache.catalina.Realm");
+
+        digester.addObjectCreate(prefix + "Realm/Realm",
+                                 null, // MUST be specified in the element
+                                 "className");
+        digester.addSetProperties(prefix + "Realm/Realm");
+        digester.addSetNext(prefix + "Realm/Realm",
+                            "addRealm",
+                            "org.apache.catalina.Realm");
+
+    }
+
+
+}

Propchange: tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/java/org/apache/catalina/startup/RealmRuleSet.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author Id

Modified: tomcat/trunk/webapps/docs/config/realm.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/realm.xml?rev=691805&r1=691804&r2=691805&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/realm.xml (original)
+++ tomcat/trunk/webapps/docs/config/realm.xml Wed Sep  3 15:18:39 2008
@@ -565,6 +565,30 @@
     Guide</a> for more information on setting up container managed security
     using the JAAS Realm component.</p>
 
+    <h3>Combined Realm (org.apache.catalina.realm.CombinedRealm)</h3>
+
+    <p><strong>CombinedRealm</strong> is an implementation of the Tomcat 6
+    <code>Realm</code> interface that authenticates users through one or more
+    sub-Realms.</p>
+
+    <p>Using CombinedRealm gives the developer the ability to combine multiple
+    Realms of the same or different types. This can be used to authenticate
+    against different sources, provide fall back in case one Realm fails or for
+    any other purpose that requires multiple Realms.</p>
+
+    <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
+    <code>Realm</code> element that defines the CombinedRealm. Authentication
+    will be attempted against each <code>Realm</code> in the order they are
+    listed. Authentication against any Realm will be sufficient to authenticate
+    the user.</p>
+
+    <p>The Combined Realm implementation does not support any additional
+    attributes.</p>
+
+    <p>See the <a href="../realm-howto.html">Container-Managed Security
+    Guide</a> for more information on setting up container managed security
+    using the Combined Realm component.</p>
+
   </subsection>
 
 
@@ -573,7 +597,14 @@
 
 <section name="Nested Components">
 
-  <p>No components may be nested inside a <strong>Realm</strong> element.</p>
+  <h3>Combined Realm Implementation</h3>
+
+  <p>If you are using the <em>Combined Realm Implementation</em>
+  <strong>&lt;Realm&gt;</strong> elements may be nested inside it.</p>
+
+  <h3>Other Realm Implementations</h3>
+  
+  <p>No other Realm implementation supports nested components.</p>
 
 </section>
 

Modified: tomcat/trunk/webapps/docs/realm-howto.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/realm-howto.xml?rev=691805&r1=691804&r2=691805&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/realm-howto.xml (original)
+++ tomcat/trunk/webapps/docs/realm-howto.xml Wed Sep  3 15:18:39 2008
@@ -1440,6 +1440,61 @@
 </subsection>
 
 
+<subsection name="CombinedRealm">
+
+    <h3>Introduction</h3>
+
+    <p><strong>CombinedRealm</strong> is an implementation of the Tomcat 6
+    <code>Realm</code> interface that authenticates users through one or more
+    sub-Realms.</p>
+
+    <p>Using CombinedRealm gives the developer the ability to combine multiple
+    Realms of the same or different types. This can be used to authenticate
+    against different sources, provide fall back in case one Realm fails or for
+    any other purpose that requires multiple Realms.</p>
+
+    <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
+    <code>Realm</code> element that defines the CombinedRealm. Authentication
+    will be attempted against each <code>Realm</code> in the order they are
+    listed. Authentication against any Realm will be sufficient to authenticate
+    the user.</p>
+
+    <h3>Realm Element Attributes</h3>
+    <p>To configure CombinedRealm, you create a <code>&lt;Realm&gt;</code>
+    element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
+    file within your <code>&lt;Engine&gt;</code> or <code>&lt;Host&gt;</code>.
+    You can also nest inside a <code>&lt;Context&gt;</code> node in a
+    <code>context.xml</code> file. The following attributes are supported by
+    this implementation:</p>
+
+<attributes>
+
+  <attribute name="className" required="true">
+    <p>The fully qualified Java class name of this Realm implementation.
+    You <strong>MUST</strong> specify the value
+    "<code>org.apache.catalina.realm.CombinedRealm</code>" here.</p>
+  </attribute>
+
+</attributes>
+
+<h3>Example</h3>
+
+<p>Here is an example of how your server.xml snippet should look to use a
+UserDatabase Realm and a DataSource Realm.</p>
+
+<source>
+&lt;Realm className="org.apache.catalina.realm.CombinedRealm" &gt;
+   &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+             resourceName="UserDatabase"/&gt;
+   &lt;Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
+             dataSourceName="jdbc/authority"
+             userTable="users" userNameCol="user_name" userCredCol="user_pass"
+             userRoleTable="user_roles" roleNameCol="role_name"/&gt;
+&lt;Realm/&gt;
+</source>
+
+</subsection>
+
 </section>
 
 </body>



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to