diff --git a/java/org/apache/catalina/realm/UserDatabaseRealm.java b/java/org/apache/catalina/realm/UserDatabaseRealm.java index f30c24a01d63..f6889269da08 100644 --- a/java/org/apache/catalina/realm/UserDatabaseRealm.java +++ b/java/org/apache/catalina/realm/UserDatabaseRealm.java @@ -18,8 +18,9 @@ import java.security.Principal; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; -import java.util.List; +import java.util.Set; import javax.naming.Context; @@ -28,7 +29,6 @@ import org.apache.catalina.Role; import org.apache.catalina.User; import org.apache.catalina.UserDatabase; -import org.apache.catalina.Wrapper; import org.apache.naming.ContextBindings; import org.apache.tomcat.util.ExceptionUtils; @@ -112,69 +112,6 @@ public void setLocalJndiResource(boolean localJndiResource) { } - // --------------------------------------------------------- Public Methods - - /** - * Return true if the specified Principal has the specified - * security role, within the context of this Realm; otherwise return - * false. This implementation returns true if the - * User has the role, or if any Group that the - * User is a member of has the role. - * - * @param principal Principal for whom the role is to be checked - * @param role Security role to be checked - */ - @Override - public boolean hasRole(Wrapper wrapper, Principal principal, String role) { - - UserDatabase database = getUserDatabase(); - if (database == null) { - return false; - } - - // Check for a role alias defined in a element - if (wrapper != null) { - String realRole = wrapper.findSecurityReference(role); - if (realRole != null) { - role = realRole; - } - } - if (principal instanceof GenericPrincipal) { - GenericPrincipal gp = (GenericPrincipal) principal; - if (gp.getUserPrincipal() instanceof UserDatabasePrincipal) { - principal = database.findUser(gp.getName()); - } - } - if (!(principal instanceof User)) { - // Play nice with SSO and mixed Realms - // No need to pass the wrapper here because role mapping has been - // performed already a few lines above - return super.hasRole(null, principal, role); - } - if ("*".equals(role)) { - return true; - } else if (role == null) { - return false; - } - User user = (User) principal; - Role dbrole = database.findRole(role); - if (dbrole == null) { - return false; - } - if (user.isInRole(dbrole)) { - return true; - } - Iterator groups = user.getGroups(); - while (groups.hasNext()) { - Group group = groups.next(); - if (group.isInRole(dbrole)) { - return true; - } - } - return false; - } - - // ------------------------------------------------------ Protected Methods @Override @@ -221,7 +158,7 @@ protected Principal getPrincipal(String username) { return null; } - List roles = new ArrayList<>(); + Set roles = new HashSet<>(); Iterator uroles = user.getRoles(); while (uroles.hasNext()) { Role role = uroles.next(); @@ -235,9 +172,8 @@ protected Principal getPrincipal(String username) { Role role = uroles.next(); roles.add(role.getName()); } - } - return new GenericPrincipal(username, roles, - new UserDatabasePrincipal(username)); + } + return new GenericPrincipal(username, new ArrayList(roles)); } @@ -306,16 +242,4 @@ protected void stopInternal() throws LifecycleException { // Release reference to our user database database = null; } - - - private static class UserDatabasePrincipal implements Principal { - private final String name; - private UserDatabasePrincipal(String name) { - this.name = name; - } - @Override - public String getName() { - return name; - } - } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 8e39a2a4792d..38821b1fb196 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -160,6 +160,17 @@ AprLifecycleListener does not show dev version suffix for libtcnative and libapr. (michaelo) + + Remove class UserDatabasePrincipal and the hasRole + override from class UserDatabaseRealm in order to make the + Realm work with cached roles only during a user's login (according to the + documentation). + + + Ignore duplicates when collecting the effective roles list from Roles and + Groups in UserDatabaseRealm.getPrincipal(String) by using a + HashSet instead of an ArrayList. +