This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 38ca9a7f23 Add support code for custom user attributes
38ca9a7f23 is described below

commit 38ca9a7f238a12f6c363fe313549dd6f422080ff
Author: remm <r...@apache.org>
AuthorDate: Fri Mar 17 11:07:54 2023 +0100

    Add support code for custom user attributes
    
    Based on code from 473 by Carsten Klein.
---
 java/org/apache/catalina/realm/RealmBase.java | 97 ++++++++++++++++++++++++++-
 webapps/docs/changelog.xml                    |  4 ++
 2 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/realm/RealmBase.java 
b/java/org/apache/catalina/realm/RealmBase.java
index c7bc3f9097..8e647f9d8a 100644
--- a/java/org/apache/catalina/realm/RealmBase.java
+++ b/java/org/apache/catalina/realm/RealmBase.java
@@ -26,6 +26,7 @@ import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 
@@ -72,6 +73,21 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
 
     private static final Log log = LogFactory.getLog(RealmBase.class);
 
+    /**
+     * The character used for delimiting user attribute names.
+     * <p>
+     * Applies to some of the Realm implementations only.
+     */
+    protected static final String USER_ATTRIBUTES_DELIMITER = ",";
+
+    /**
+     * The character used as wildcard in user attribute lists. Using it means
+     * <i>query all available user attributes</i>.
+     * <p>
+     * Applies to some of the Realm implementations only.
+     */
+    protected static final String USER_ATTRIBUTES_WILDCARD = "*";
+
     private static final List<Class<? extends DigestCredentialHandlerBase>> 
credentialHandlerClasses = new ArrayList<>();
 
     static {
@@ -143,6 +159,22 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
     private int transportGuaranteeRedirectStatus = 
HttpServletResponse.SC_FOUND;
 
 
+    /**
+     * The comma separated names of user attributes to additionally query from 
the
+     * realm. These will be provided to the user through the created
+     * Principal's <i>attributes</i> map. Support for this feature is optional.
+     */
+    protected String userAttributes = null;
+
+
+    /**
+     * The list of user attributes to additionally query from the
+     * realm. These will be provided to the user through the created
+     * Principal's <i>attributes</i> map. Support for this feature is optional.
+     */
+    protected List<String> userAttributesList = null;
+
+
     // ------------------------------------------------------------- Properties
 
     /**
@@ -264,6 +296,33 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
     }
 
 
+    /**
+     * @return the comma separated names of user attributes to additionally 
query from realm
+     */
+    public String getUserAttributes() {
+        return userAttributes;
+    }
+
+    /**
+     * Set the comma separated names of user attributes to additionally query 
from
+     * the realm. These will be provided to the user through the created
+     * Principal's <i>attributes</i> map. In this map, each field value is 
bound to
+     * the field's name, that is, the name of the field serves as the key of 
the
+     * mapping.
+     * <p>
+     * If set to the wildcard character, or, if the wildcard character is part 
of
+     * the comma separated list, all available attributes - except the
+     * <i>password</i> attribute (as specified by <code>userCredCol</code>) - 
are
+     * queried. The wildcard character is defined by constant
+     * {@link RealmBase#USER_ATTRIBUTES_WILDCARD}. It defaults to the asterisk 
(*)
+     * character.
+     *
+     * @param userAttributes the comma separated names of user attributes
+     */
+    public void setUserAttributes(String userAttributes) {
+        this.userAttributes = userAttributes;
+    }
+
     // --------------------------------------------------------- Public Methods
 
     @Override
@@ -853,6 +912,40 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
     }
 
 
+    /**
+     * Parse the specified delimiter separated attribute names and return a 
list of
+     * that names or <code>null</code>, if no attributes have been specified.
+     * <p>
+     * If a wildcard character is found, return a list consisting of a single
+     * wildcard character only.
+     *
+     * @param userAttributes comma separated names of attributes to parse
+     * @return a list containing the parsed attribute names or 
<code>null</code>, if
+     *         no attributes have been specified
+     */
+    protected List<String> parseUserAttributes(String userAttributes) {
+        if (userAttributes == null) {
+            return null;
+        }
+        List<String> attrs = new ArrayList<>();
+        for (String name : userAttributes.split(USER_ATTRIBUTES_DELIMITER)) {
+            name = name.trim();
+            if (name.length() == 0) {
+                continue;
+            }
+            if (name.equals(USER_ATTRIBUTES_WILDCARD)) {
+                return Collections.singletonList(USER_ATTRIBUTES_WILDCARD);
+            }
+            if (attrs.contains(name)) {
+                // skip duplicates
+                continue;
+            }
+            attrs.add(name);
+        }
+        return attrs.size() > 0 ? attrs : null;
+    }
+
+
     /**
      * Check if the specified Principal has the specified security role, 
within the context of this Realm. This method
      * or {@link #hasRoleInternal(Principal, String)} can be overridden by 
Realm implementations, but the default is
@@ -987,7 +1080,9 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
         if (credentialHandler == null) {
             credentialHandler = new MessageDigestCredentialHandler();
         }
-
+        if (userAttributes != null) {
+            userAttributesList = parseUserAttributes(userAttributes);
+        }
         setState(LifecycleState.STARTING);
     }
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index f77b97fd78..98b6e35879 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -142,6 +142,10 @@
         <code>DigestAuthenticator</code> with a default of
         <code>SHA-256,MD5</code>. (markt)
       </add>
+      <update>
+        Add support code for custom user attributes in <code>RealmBase</code>.
+        Based on code from <pr>473</pr> by Carsten Klein. (remm)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to