|
26 | 26 | import java.security.Principal;
|
27 | 27 | import java.security.cert.X509Certificate;
|
28 | 28 | import java.util.ArrayList;
|
| 29 | +import java.util.Collections; |
29 | 30 | import java.util.List;
|
30 | 31 | import java.util.Locale;
|
31 | 32 |
|
@@ -72,6 +73,21 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm {
|
72 | 73 |
|
73 | 74 | private static final Log log = LogFactory.getLog(RealmBase.class);
|
74 | 75 |
|
| 76 | + /** |
| 77 | + * The character used for delimiting user attribute names. |
| 78 | + * <p> |
| 79 | + * Applies to some of the Realm implementations only. |
| 80 | + */ |
| 81 | + protected static final String USER_ATTRIBUTES_DELIMITER = ","; |
| 82 | + |
| 83 | + /** |
| 84 | + * The character used as wildcard in user attribute lists. Using it means |
| 85 | + * <i>query all available user attributes</i>. |
| 86 | + * <p> |
| 87 | + * Applies to some of the Realm implementations only. |
| 88 | + */ |
| 89 | + protected static final String USER_ATTRIBUTES_WILDCARD = "*"; |
| 90 | + |
75 | 91 | private static final List<Class<? extends DigestCredentialHandlerBase>> credentialHandlerClasses = new ArrayList<>();
|
76 | 92 |
|
77 | 93 | static {
|
@@ -143,6 +159,22 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm {
|
143 | 159 | private int transportGuaranteeRedirectStatus = HttpServletResponse.SC_FOUND;
|
144 | 160 |
|
145 | 161 |
|
| 162 | + /** |
| 163 | + * The comma separated names of user attributes to additionally query from the |
| 164 | + * realm. These will be provided to the user through the created |
| 165 | + * Principal's <i>attributes</i> map. Support for this feature is optional. |
| 166 | + */ |
| 167 | + protected String userAttributes = null; |
| 168 | + |
| 169 | + |
| 170 | + /** |
| 171 | + * The list of user attributes to additionally query from the |
| 172 | + * realm. These will be provided to the user through the created |
| 173 | + * Principal's <i>attributes</i> map. Support for this feature is optional. |
| 174 | + */ |
| 175 | + protected List<String> userAttributesList = null; |
| 176 | + |
| 177 | + |
146 | 178 | // ------------------------------------------------------------- Properties
|
147 | 179 |
|
148 | 180 | /**
|
@@ -264,6 +296,33 @@ public void setStripRealmForGss(boolean stripRealmForGss) {
|
264 | 296 | }
|
265 | 297 |
|
266 | 298 |
|
| 299 | + /** |
| 300 | + * @return the comma separated names of user attributes to additionally query from realm |
| 301 | + */ |
| 302 | + public String getUserAttributes() { |
| 303 | + return userAttributes; |
| 304 | + } |
| 305 | + |
| 306 | + /** |
| 307 | + * Set the comma separated names of user attributes to additionally query from |
| 308 | + * the realm. These will be provided to the user through the created |
| 309 | + * Principal's <i>attributes</i> map. In this map, each field value is bound to |
| 310 | + * the field's name, that is, the name of the field serves as the key of the |
| 311 | + * mapping. |
| 312 | + * <p> |
| 313 | + * If set to the wildcard character, or, if the wildcard character is part of |
| 314 | + * the comma separated list, all available attributes - except the |
| 315 | + * <i>password</i> attribute (as specified by <code>userCredCol</code>) - are |
| 316 | + * queried. The wildcard character is defined by constant |
| 317 | + * {@link RealmBase#USER_ATTRIBUTES_WILDCARD}. It defaults to the asterisk (*) |
| 318 | + * character. |
| 319 | + * |
| 320 | + * @param userAttributes the comma separated names of user attributes |
| 321 | + */ |
| 322 | + public void setUserAttributes(String userAttributes) { |
| 323 | + this.userAttributes = userAttributes; |
| 324 | + } |
| 325 | + |
267 | 326 | // --------------------------------------------------------- Public Methods
|
268 | 327 |
|
269 | 328 | @Override
|
@@ -845,6 +904,40 @@ public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
|
845 | 904 | }
|
846 | 905 |
|
847 | 906 |
|
| 907 | + /** |
| 908 | + * Parse the specified delimiter separated attribute names and return a list of |
| 909 | + * that names or <code>null</code>, if no attributes have been specified. |
| 910 | + * <p> |
| 911 | + * If a wildcard character is found, return a list consisting of a single |
| 912 | + * wildcard character only. |
| 913 | + * |
| 914 | + * @param userAttributes comma separated names of attributes to parse |
| 915 | + * @return a list containing the parsed attribute names or <code>null</code>, if |
| 916 | + * no attributes have been specified |
| 917 | + */ |
| 918 | + protected List<String> parseUserAttributes(String userAttributes) { |
| 919 | + if (userAttributes == null) { |
| 920 | + return null; |
| 921 | + } |
| 922 | + List<String> attrs = new ArrayList<>(); |
| 923 | + for (String name : userAttributes.split(USER_ATTRIBUTES_DELIMITER)) { |
| 924 | + name = name.trim(); |
| 925 | + if (name.length() == 0) { |
| 926 | + continue; |
| 927 | + } |
| 928 | + if (name.equals(USER_ATTRIBUTES_WILDCARD)) { |
| 929 | + return Collections.singletonList(USER_ATTRIBUTES_WILDCARD); |
| 930 | + } |
| 931 | + if (attrs.contains(name)) { |
| 932 | + // skip duplicates |
| 933 | + continue; |
| 934 | + } |
| 935 | + attrs.add(name); |
| 936 | + } |
| 937 | + return attrs.size() > 0 ? attrs : null; |
| 938 | + } |
| 939 | + |
| 940 | + |
848 | 941 | /**
|
849 | 942 | * Check if the specified Principal has the specified security role, within the context of this Realm. This method
|
850 | 943 | * or {@link #hasRoleInternal(Principal, String)} can be overridden by Realm implementations, but the default is
|
@@ -979,7 +1072,9 @@ protected void startInternal() throws LifecycleException {
|
979 | 1072 | if (credentialHandler == null) {
|
980 | 1073 | credentialHandler = new MessageDigestCredentialHandler();
|
981 | 1074 | }
|
982 |
| - |
| 1075 | + if (userAttributes != null) { |
| 1076 | + userAttributesList = parseUserAttributes(userAttributes); |
| 1077 | + } |
983 | 1078 | setState(LifecycleState.STARTING);
|
984 | 1079 | }
|
985 | 1080 |
|
|
0 commit comments