GUACAMOLE-524: Remove Attributes interface from AuthenticatedUser. Rely instead on tokens injected via decoration of connections.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/98bd3ead Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/98bd3ead Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/98bd3ead Branch: refs/heads/master Commit: 98bd3ead2179febdafcae7935811da88a05beda1 Parents: 0d7cff5 Author: Michael Jumper <mjum...@apache.org> Authored: Thu Oct 4 23:37:16 2018 -0700 Committer: Michael Jumper <mjum...@apache.org> Committed: Fri Oct 5 12:47:26 2018 -0700 ---------------------------------------------------------------------- .../jdbc/user/ModeledAuthenticatedUser.java | 1 - .../auth/jdbc/user/RemoteAuthenticatedUser.java | 11 ----- .../ldap/AuthenticationProviderService.java | 45 ++++++++++++-------- .../auth/ldap/ConfigurationService.java | 3 +- .../auth/ldap/LDAPAuthenticationProvider.java | 17 ++++++++ .../auth/ldap/connection/ConnectionService.java | 9 ++++ .../auth/ldap/user/LDAPAuthenticatedUser.java | 38 ++++++++++------- .../net/auth/AbstractAuthenticatedUser.java | 11 ----- .../guacamole/net/auth/AuthenticatedUser.java | 2 +- .../apache/guacamole/token/StandardTokens.java | 43 ++----------------- .../guacamole/tunnel/StandardTokenMap.java | 17 -------- 11 files changed, 82 insertions(+), 115 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledAuthenticatedUser.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledAuthenticatedUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledAuthenticatedUser.java index 539cec0..828b05e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledAuthenticatedUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledAuthenticatedUser.java @@ -79,7 +79,6 @@ public class ModeledAuthenticatedUser extends RemoteAuthenticatedUser { super(authenticatedUser.getAuthenticationProvider(), authenticatedUser.getCredentials(), authenticatedUser.getEffectiveUserGroups()); this.modelAuthenticationProvider = modelAuthenticationProvider; this.user = user; - super.setAttributes(authenticatedUser.getAttributes()); } /** http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java index f994655..a936e4e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java @@ -19,7 +19,6 @@ package org.apache.guacamole.auth.jdbc.user; -import java.util.Map; import java.util.Collections; import java.util.Set; import org.apache.guacamole.net.auth.AuthenticatedUser; @@ -52,16 +51,6 @@ public abstract class RemoteAuthenticatedUser implements AuthenticatedUser { */ private final Set<String> effectiveGroups; - @Override - public Map<String, String> getAttributes() { - return Collections.<String, String>emptyMap(); - } - - @Override - public void setAttributes(Map<String, String> attributes) { - // No attributes supported - } - /** * Creates a new RemoteAuthenticatedUser, deriving the associated remote * host from the given credentials. http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java index c820189..aa4382e 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java @@ -54,6 +54,12 @@ public class AuthenticationProviderService { private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); /** + * The prefix string to add to each parameter token generated from an LDAP + * attribute name. + */ + private static final String LDAP_ATTRIBUTE_TOKEN_PREFIX = "LDAP_ATTR_"; + + /** * Service for creating and managing connections to LDAP servers. */ @Inject @@ -233,7 +239,7 @@ public class AuthenticationProviderService { try { // Return AuthenticatedUser if bind succeeds LDAPAuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); - authenticatedUser.init(credentials, getLDAPAttributes(ldapConnection, credentials.getUsername())); + authenticatedUser.init(credentials, getAttributeTokens(ldapConnection, credentials.getUsername())); return authenticatedUser; @@ -246,43 +252,44 @@ public class AuthenticationProviderService { } /** - * Returns all custom LDAP attributes on the user currently bound under - * the given LDAP connection. The custom attributes are specified in - * guacamole.properties. If no attributes are specified or none are + * Returns parameter tokens generated from LDAP attributes on the user + * currently bound under the given LDAP connection. The attributes to be + * converted into parameter tokens must be explicitly listed in + * guacamole.properties. If no attributes are specified or none are * found on the LDAP user object, an empty map is returned. * * @param ldapConnection - * LDAP connection to find the custom LDAP attributes. + * LDAP connection to use to read the attributes of the user. * * @param username - * The username of the user whose attributes are queried. + * The username of the user whose attributes are to be queried. * * @return - * All attributes on the user currently bound under the - * given LDAP connection, as a map of attribute name to - * corresponding attribute value, or an empty map if no - * attributes are specified or none are found on the user - * object. + * A map of parameter tokens generated from attributes on the user + * currently bound under the given LDAP connection, as a map of token + * name to corresponding value, or an empty map if no attributes are + * specified or none are found on the user object. * * @throws GuacamoleException * If an error occurs retrieving the user DN or the attributes. */ - private Map<String, String> getLDAPAttributes(LDAPConnection ldapConnection, + private Map<String, String> getAttributeTokens(LDAPConnection ldapConnection, String username) throws GuacamoleException { // Get attributes from configuration information List<String> attrList = confService.getAttributes(); // If there are no attributes there is no reason to search LDAP - if (attrList == null || attrList.isEmpty()) + if (attrList.isEmpty()) return Collections.<String, String>emptyMap(); // Build LDAP query parameters String[] attrArray = attrList.toArray(new String[attrList.size()]); String userDN = getUserBindDN(username); - Map<String, String> attrMap = new HashMap<String, String>(); + Map<String, String> tokens = new HashMap<String, String>(); try { + // Get LDAP attributes by querying LDAP LDAPEntry userEntry = ldapConnection.read(userDN, attrArray); if (userEntry == null) @@ -292,17 +299,19 @@ public class AuthenticationProviderService { if (attrSet == null) return Collections.<String, String>emptyMap(); - // Add each attribute into Map + // Convert each retrieved attribute into a corresponding token for (Object attrObj : attrSet) { LDAPAttribute attr = (LDAPAttribute)attrObj; - attrMap.put(attr.getName(), attr.getStringValue()); + tokens.put(LDAP_ATTRIBUTE_TOKEN_PREFIX + attr.getName(), attr.getStringValue()); } + } catch (LDAPException e) { - throw new GuacamoleServerException("Error while querying for User Attributes.", e); + throw new GuacamoleServerException("Could not query LDAP user attributes.", e); } - return attrMap; + return tokens; + } /** http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java index b52ad50..4347d45 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java @@ -355,7 +355,8 @@ public class ConfigurationService { */ public List<String> getAttributes() throws GuacamoleException { return environment.getProperty( - LDAPGuacamoleProperties.LDAP_USER_ATTRIBUTES + LDAPGuacamoleProperties.LDAP_USER_ATTRIBUTES, + Collections.<String>emptyList() ); } http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java index 31aa4e2..48e275c 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java @@ -23,9 +23,11 @@ package org.apache.guacamole.auth.ldap; import com.google.inject.Guice; import com.google.inject.Injector; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.ldap.user.LDAPAuthenticatedUser; import org.apache.guacamole.net.auth.AbstractAuthenticationProvider; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; +import org.apache.guacamole.net.auth.TokenInjectingUserContext; import org.apache.guacamole.net.auth.UserContext; /** @@ -85,4 +87,19 @@ public class LDAPAuthenticationProvider extends AbstractAuthenticationProvider { } + @Override + public UserContext decorate(UserContext context, + AuthenticatedUser authenticatedUser, Credentials credentials) + throws GuacamoleException { + + // Only decorate if the user authenticated against LDAP + if (!(authenticatedUser instanceof LDAPAuthenticatedUser)) + return context; + + // Apply LDAP-specific tokens to all connections / connection groups + return new TokenInjectingUserContext(context, + ((LDAPAuthenticatedUser) authenticatedUser).getTokens()); + + } + } http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java index 18e3b9c..b69a13a 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java @@ -35,8 +35,10 @@ import org.apache.guacamole.auth.ldap.ConfigurationService; import org.apache.guacamole.auth.ldap.EscapingService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; +import org.apache.guacamole.auth.ldap.user.LDAPAuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Connection; +import org.apache.guacamole.net.auth.TokenInjectingConnection; import org.apache.guacamole.net.auth.simple.SimpleConnection; import org.apache.guacamole.protocol.GuacamoleConfiguration; import org.slf4j.Logger; @@ -178,6 +180,13 @@ public class ConnectionService { String name = cn.getStringValue(); Connection connection = new SimpleConnection(name, name, config); connection.setParentIdentifier(LDAPAuthenticationProvider.ROOT_CONNECTION_GROUP); + + // Inject LDAP-specific tokens only if LDAP handled user + // authentication + if (user instanceof LDAPAuthenticatedUser) + connection = new TokenInjectingConnection(connection, + ((LDAPAuthenticatedUser) user).getTokens()); + connections.put(name, connection); } http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java index 8969e73..36f6695 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java @@ -20,6 +20,7 @@ package org.apache.guacamole.auth.ldap.user; import com.google.inject.Inject; +import java.util.Collections; import java.util.Map; import org.apache.guacamole.net.auth.AbstractAuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticationProvider; @@ -44,35 +45,40 @@ public class LDAPAuthenticatedUser extends AbstractAuthenticatedUser { private Credentials credentials; /** - * Arbitrary attributes associated with this AuthenticatedUser object. + * Name/value pairs to be applied as parameter tokens when connections + * are established using this AuthenticatedUser. */ - private Map<String, String> attributes; + private Map<String, String> tokens; /** * Initializes this AuthenticatedUser using the given credentials and - * arbitrary attributes. + * connection parameter tokens. * * @param credentials * The credentials provided when this user was authenticated. * - * @param attributes - * The map of arbitrary attribute name/value pairs to associate with - * this AuthenticatedUser. + * @param tokens + * A Map of all name/value pairs that should be applied as parameter + * tokens when connections are established using the AuthenticatedUser. */ - public void init(Credentials credentials, Map<String, String> attributes) { + public void init(Credentials credentials, Map<String, String> tokens) { this.credentials = credentials; - this.attributes = attributes; + this.tokens = Collections.unmodifiableMap(tokens); setIdentifier(credentials.getUsername()); } - @Override - public Map<String, String> getAttributes() { - return attributes; - } - - @Override - public void setAttributes(Map<String, String> attributes) { - // All attributes are read-only + /** + * Returns a Map of all name/value pairs that should be applied as + * parameter tokens when connections are established using this + * AuthenticatedUser. + * + * @return + * A Map of all name/value pairs that should be applied as parameter + * tokens when connections are established using this + * AuthenticatedUser. + */ + public Map<String, String> getTokens() { + return tokens; } @Override http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java ---------------------------------------------------------------------- diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java index 828ad89..36c4571 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java @@ -20,7 +20,6 @@ package org.apache.guacamole.net.auth; import java.util.Collections; -import java.util.Map; import java.util.Set; /** @@ -42,14 +41,4 @@ public abstract class AbstractAuthenticatedUser extends AbstractIdentifiable // Nothing to invalidate } - @Override - public Map<String, String> getAttributes() { - return Collections.<String, String>emptyMap(); - } - - @Override - public void setAttributes(Map<String, String> attributes) { - //do nothing - } - } http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java ---------------------------------------------------------------------- diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java index 14f2597..a799937 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java @@ -25,7 +25,7 @@ import java.util.Set; * A user of the Guacamole web application who has been authenticated by an * AuthenticationProvider. */ -public interface AuthenticatedUser extends Identifiable, Attributes { +public interface AuthenticatedUser extends Identifiable { /** * The identifier reserved for representing a user that has authenticated http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java ---------------------------------------------------------------------- diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java b/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java index 22a042e..3118cf2 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java @@ -21,8 +21,6 @@ package org.apache.guacamole.token; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.Map; -import java.util.Set; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; @@ -82,11 +80,6 @@ public class StandardTokens { private static final String TIME_FORMAT = "HHmmss"; /** - * The prefix of the arbitrary attribute tokens. - */ - public static final String ATTR_TOKEN_PREFIX = "GUAC_ATTR_"; - - /** * This utility class should not be instantiated. */ private StandardTokens() {} @@ -155,11 +148,10 @@ public class StandardTokens { * Adds tokens which are standardized by guacamole-ext to the given * TokenFilter using the values from the given AuthenticatedUser object, * including any associated credentials. These standardized tokens include - * the current username (GUAC_USERNAME), password (GUAC_PASSWORD), the - * server date and time (GUAC_DATE and GUAC_TIME respectively), and custom - * user attributes. If either the username or password are not set within - * the given user or their provided credentials, the corresponding token(s) - * will remain unset. + * the current username (GUAC_USERNAME), password (GUAC_PASSWORD), and the + * server date and time (GUAC_DATE and GUAC_TIME respectively). If either + * the username or password are not set within the given user or their + * provided credentials, the corresponding token(s) will remain unset. * * @param filter * The TokenFilter to add standard tokens to. @@ -177,33 +169,6 @@ public class StandardTokens { // Add tokens specific to credentials addStandardTokens(filter, user.getCredentials()); - // Add custom attribute tokens - addAttributeTokens(filter, user.getAttributes()); - } - - /** - * Add attribute tokens to StandardTokens. These are arbitrary - * key/value pairs that may be configured by the various authentication - * extensions. - * - * @param filter - * The TokenFilter to add attribute tokens to. - * - * @param attributes - * The map of key/value pairs to add tokens for. - */ - public static void addAttributeTokens(TokenFilter filter, - Map<String, String> attributes) { - - if (attributes != null) { - for (Map.Entry entry : attributes.entrySet()) { - String key = entry.getKey().toString(); - String tokenName = ATTR_TOKEN_PREFIX + key.toUpperCase(); - String tokenValue = entry.getValue().toString(); - filter.setToken(tokenName, tokenValue); - } - } - } } http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/98bd3ead/guacamole/src/main/java/org/apache/guacamole/tunnel/StandardTokenMap.java ---------------------------------------------------------------------- diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/StandardTokenMap.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/StandardTokenMap.java index 1d357d2..3392861 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/StandardTokenMap.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/StandardTokenMap.java @@ -22,7 +22,6 @@ package org.apache.guacamole.tunnel; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; -import java.util.Map; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; @@ -77,11 +76,6 @@ public class StandardTokenMap extends HashMap<String, String> { private static final String TIME_FORMAT = "HHmmss"; /** - * The prefix of the arbitrary attribute tokens. - */ - public static final String ATTR_TOKEN_PREFIX = "GUAC_ATTR_"; - - /** * Creates a new StandardTokenMap which is pre-populated with the * name/value pairs of all standardized tokens available for the given * AuthenticatedUser. @@ -97,7 +91,6 @@ public class StandardTokenMap extends HashMap<String, String> { put(TIME_TOKEN, new SimpleDateFormat(TIME_FORMAT).format(currentTime)); Credentials credentials = authenticatedUser.getCredentials(); - Map<String, String> attributes = authenticatedUser.getAttributes(); // Add username token String username = credentials.getUsername(); @@ -124,16 +117,6 @@ public class StandardTokenMap extends HashMap<String, String> { if (address != null) put(CLIENT_ADDRESS_TOKEN, address); - // Add tokens for all attributes on the AuthenticatedUser - if (attributes != null) { - for (Map.Entry entry : attributes.entrySet()) { - String key = entry.getKey().toString(); - String tokenName = ATTR_TOKEN_PREFIX + key.toUpperCase(); - String tokenValue = entry.getValue().toString(); - put(tokenName, tokenValue); - } - } - } }