You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/10/06 12:11:13 UTC

[3/7] guacamole-client git commit: GUACAMOLE-524: Deprecate and replace StandardTokens with arbitrary tokens provided to Connectable.connect().

GUACAMOLE-524: Deprecate and replace StandardTokens with arbitrary tokens provided to Connectable.connect().


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/1210d562
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/1210d562
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/1210d562

Branch: refs/heads/master
Commit: 1210d5624c4eb173417cab8358eca4cc3b6c0ebe
Parents: 3089e71
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Oct 4 00:41:07 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Fri Oct 5 12:47:26 2018 -0700

----------------------------------------------------------------------
 .../auth/jdbc/connection/ConnectionService.java |  10 +-
 .../auth/jdbc/connection/ModeledConnection.java |   5 +-
 .../connectiongroup/ConnectionGroupService.java |  11 +-
 .../connectiongroup/ModeledConnectionGroup.java |   6 +-
 .../connectiongroup/RootConnectionGroup.java    |   4 +-
 .../sharing/connection/SharedConnection.java    |   6 +-
 .../SharedRootConnectionGroup.java              |   4 +-
 .../tunnel/AbstractGuacamoleTunnelService.java  |  45 +++---
 .../jdbc/tunnel/GuacamoleTunnelService.java     |  21 ++-
 .../auth/ldap/connection/ConnectionService.java |   9 --
 .../auth/quickconnect/QuickConnectionGroup.java |   4 +-
 .../apache/guacamole/net/auth/Connectable.java  |  17 ++-
 .../net/auth/DelegatingConnection.java          |   6 +-
 .../net/auth/DelegatingConnectionGroup.java     |   5 +-
 .../simple/SimpleAuthenticationProvider.java    |  77 +---------
 .../net/auth/simple/SimpleConnection.java       |  20 ++-
 .../net/auth/simple/SimpleConnectionGroup.java  |   4 +-
 .../apache/guacamole/token/StandardTokens.java  |   5 +
 .../rest/connection/APIConnectionWrapper.java   |   3 +-
 .../APIConnectionGroupWrapper.java              |   3 +-
 .../guacamole/tunnel/StandardTokenMap.java      | 139 +++++++++++++++++++
 .../guacamole/tunnel/TunnelRequestService.java  |  18 ++-
 22 files changed, 268 insertions(+), 154 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java
index 8dcf6f5..e2f3c15 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java
@@ -499,6 +499,10 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
      * @param info
      *     Information associated with the connecting client.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @return
      *     A connected GuacamoleTunnel associated with a newly-established
      *     connection.
@@ -507,12 +511,12 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
      *     If permission to connect to this connection is denied.
      */
     public GuacamoleTunnel connect(ModeledAuthenticatedUser user,
-            ModeledConnection connection, GuacamoleClientInformation info)
-            throws GuacamoleException {
+            ModeledConnection connection, GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
 
         // Connect only if READ permission is granted
         if (hasObjectPermission(user, connection.getIdentifier(), ObjectPermission.Type.READ))
-            return tunnelService.getGuacamoleTunnel(user, connection, info);
+            return tunnelService.getGuacamoleTunnel(user, connection, info, tokens);
 
         // The user does not have permission to connect
         throw new GuacamoleSecurityException("Permission denied.");

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java
index 660212c..b492626 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java
@@ -259,8 +259,9 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException {
-        return connectionService.connect(getCurrentUser(), this, info);
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
+        return connectionService.connect(getCurrentUser(), this, info, tokens);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java
index 01119b9..3e9ec72 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java
@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.connectiongroup;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import java.util.Map;
 import java.util.Set;
 import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
 import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
@@ -243,6 +244,10 @@ public class ConnectionGroupService extends ModeledChildDirectoryObjectService<M
      * @param info
      *     Information associated with the connecting client.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @return
      *     A connected GuacamoleTunnel associated with a newly-established
      *     connection.
@@ -251,12 +256,12 @@ public class ConnectionGroupService extends ModeledChildDirectoryObjectService<M
      *     If permission to connect to this connection is denied.
      */
     public GuacamoleTunnel connect(ModeledAuthenticatedUser user,
-            ModeledConnectionGroup connectionGroup, GuacamoleClientInformation info)
-            throws GuacamoleException {
+            ModeledConnectionGroup connectionGroup, GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
 
         // Connect only if READ permission is granted
         if (hasObjectPermission(user, connectionGroup.getIdentifier(), ObjectPermission.Type.READ))
-            return tunnelService.getGuacamoleTunnel(user, connectionGroup, info);
+            return tunnelService.getGuacamoleTunnel(user, connectionGroup, info, tokens);
 
         // The user does not have permission to connect
         throw new GuacamoleSecurityException("Permission denied.");

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java
index 3aac52d..bcf457a 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java
@@ -135,9 +135,9 @@ public class ModeledConnectionGroup extends ModeledChildDirectoryObject<Connecti
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException {
-        return connectionGroupService.connect(getCurrentUser(), this, info);
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
+        return connectionGroupService.connect(getCurrentUser(), this, info, tokens);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/RootConnectionGroup.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/RootConnectionGroup.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/RootConnectionGroup.java
index d2e5551..08b32fd 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/RootConnectionGroup.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/RootConnectionGroup.java
@@ -122,8 +122,8 @@ public class RootConnectionGroup extends RestrictedObject
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
         throw new GuacamoleSecurityException("Permission denied.");
     }
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java
index 5483d02..cf00831 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java
@@ -131,9 +131,9 @@ public class SharedConnection implements Connection {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException {
-        return tunnelService.getGuacamoleTunnel(user, definition, info);
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
+        return tunnelService.getGuacamoleTunnel(user, definition, info, tokens);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connectiongroup/SharedRootConnectionGroup.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connectiongroup/SharedRootConnectionGroup.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connectiongroup/SharedRootConnectionGroup.java
index 71b997c..33d9ca7 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connectiongroup/SharedRootConnectionGroup.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connectiongroup/SharedRootConnectionGroup.java
@@ -98,8 +98,8 @@ public class SharedRootConnectionGroup implements ConnectionGroup {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
         throw new GuacamoleSecurityException("Permission denied.");
     }
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
index 5f7fc1b..20ac299 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
@@ -52,7 +52,6 @@ import org.apache.guacamole.net.auth.ConnectionGroup;
 import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
 import org.apache.guacamole.protocol.GuacamoleClientInformation;
 import org.apache.guacamole.protocol.GuacamoleConfiguration;
-import org.apache.guacamole.token.StandardTokens;
 import org.apache.guacamole.token.TokenFilter;
 import org.mybatis.guice.transactional.Transactional;
 import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper;
@@ -233,13 +232,6 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
         for (ConnectionParameterModel parameter : parameters)
             config.setParameter(parameter.getName(), parameter.getValue());
 
-        // Build token filter containing credential tokens
-        TokenFilter tokenFilter = new TokenFilter();
-        StandardTokens.addStandardTokens(tokenFilter, user);
-
-        // Filter the configuration
-        tokenFilter.filterValues(config.getParameters());
-
         return config;
         
     }
@@ -279,13 +271,6 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
         for (SharingProfileParameterModel parameter : parameters)
             config.setParameter(parameter.getName(), parameter.getValue());
 
-        // Build token filter containing credential tokens
-        TokenFilter tokenFilter = new TokenFilter();
-        StandardTokens.addStandardTokens(tokenFilter, user);
-
-        // Filter the configuration
-        tokenFilter.filterValues(config.getParameters());
-
         return config;
 
     }
@@ -454,6 +439,10 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
      *     Information describing the Guacamole client connecting to the given
      *     connection.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @param interceptErrors
      *     Whether errors from the upstream remote desktop should be
      *     intercepted and rethrown as GuacamoleUpstreamExceptions.
@@ -467,7 +456,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
      *     while connection configuration information is being retrieved.
      */
     private GuacamoleTunnel assignGuacamoleTunnel(ActiveConnectionRecord activeConnection,
-            GuacamoleClientInformation info, boolean interceptErrors) throws GuacamoleException {
+            GuacamoleClientInformation info, Map<String, String> tokens,
+            boolean interceptErrors) throws GuacamoleException {
 
         // Record new active connection
         Runnable cleanupTask = new ConnectionCleanupTask(activeConnection);
@@ -504,6 +494,13 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
 
             }
 
+            // Build token filter containing credential tokens
+            TokenFilter tokenFilter = new TokenFilter();
+            tokenFilter.setTokens(tokens);
+
+            // Filter the configuration
+            tokenFilter.filterValues(config.getParameters());
+
             // Obtain socket which will automatically run the cleanup task
             ConfiguredGuacamoleSocket socket = new ConfiguredGuacamoleSocket(
                 getUnconfiguredGuacamoleSocket(connection.getGuacamoleProxyConfiguration(),
@@ -651,8 +648,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
     @Override
     @Transactional
     public GuacamoleTunnel getGuacamoleTunnel(final ModeledAuthenticatedUser user,
-            final ModeledConnection connection, GuacamoleClientInformation info)
-            throws GuacamoleException {
+            final ModeledConnection connection, GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
 
         // Acquire access to single connection, ignoring the failover-only flag
         acquire(user, Collections.singletonList(connection), true);
@@ -660,7 +657,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
         // Connect only if the connection was successfully acquired
         ActiveConnectionRecord connectionRecord = activeConnectionRecordProvider.get();
         connectionRecord.init(user, connection);
-        return assignGuacamoleTunnel(connectionRecord, info, false);
+        return assignGuacamoleTunnel(connectionRecord, info, tokens, false);
 
     }
 
@@ -673,7 +670,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
     @Transactional
     public GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
             ModeledConnectionGroup connectionGroup,
-            GuacamoleClientInformation info) throws GuacamoleException {
+            GuacamoleClientInformation info, Map<String, String> tokens)
+            throws GuacamoleException {
 
         // Track failures in upstream (remote desktop) connections
         boolean upstreamHasFailed = false;
@@ -706,7 +704,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
                 // Connect to acquired child
                 ActiveConnectionRecord connectionRecord = activeConnectionRecordProvider.get();
                 connectionRecord.init(user, connectionGroup, connection);
-                GuacamoleTunnel tunnel = assignGuacamoleTunnel(connectionRecord, info, connections.size() > 1);
+                GuacamoleTunnel tunnel = assignGuacamoleTunnel(connectionRecord,
+                        info, tokens, connections.size() > 1);
 
                 // If session affinity is enabled, prefer this connection going forward
                 if (connectionGroup.isSessionAffinityEnabled())
@@ -755,7 +754,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
     @Transactional
     public GuacamoleTunnel getGuacamoleTunnel(RemoteAuthenticatedUser user,
             SharedConnectionDefinition definition,
-            GuacamoleClientInformation info)
+            GuacamoleClientInformation info, Map<String, String> tokens)
             throws GuacamoleException {
 
         // Create a connection record which describes the shared connection
@@ -764,7 +763,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
                 definition.getSharingProfile());
 
         // Connect to shared connection described by the created record
-        GuacamoleTunnel tunnel = assignGuacamoleTunnel(connectionRecord, info, false);
+        GuacamoleTunnel tunnel = assignGuacamoleTunnel(connectionRecord, info, tokens, false);
 
         // Register tunnel, such that it is closed when the
         // SharedConnectionDefinition is invalidated

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
index 34d9293..bad5219 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
@@ -20,6 +20,7 @@
 package org.apache.guacamole.auth.jdbc.tunnel;
 
 import java.util.Collection;
+import java.util.Map;
 import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
 import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
 import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
@@ -73,6 +74,10 @@ public interface GuacamoleTunnelService {
      *     Information describing the Guacamole client connecting to the given
      *     connection.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @return
      *     A new GuacamoleTunnel which is configured and connected to the given
      *     connection.
@@ -82,8 +87,8 @@ public interface GuacamoleTunnelService {
      *     rules.
      */
     GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
-            ModeledConnection connection, GuacamoleClientInformation info)
-            throws GuacamoleException;
+            ModeledConnection connection, GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException;
 
     /**
      * Returns a collection containing connection records representing all
@@ -117,6 +122,10 @@ public interface GuacamoleTunnelService {
      *     Information describing the Guacamole client connecting to the given
      *     connection group.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @return
      *     A new GuacamoleTunnel which is configured and connected to the given
      *     connection group.
@@ -127,7 +136,7 @@ public interface GuacamoleTunnelService {
      */
     GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
             ModeledConnectionGroup connectionGroup,
-            GuacamoleClientInformation info)
+            GuacamoleClientInformation info, Map<String, String> tokens)
             throws GuacamoleException;
 
     /**
@@ -163,6 +172,10 @@ public interface GuacamoleTunnelService {
      *     Information describing the Guacamole client connecting to the given
      *     connection.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @return
      *     A new GuacamoleTunnel which is configured and connected to the given
      *     active connection.
@@ -173,7 +186,7 @@ public interface GuacamoleTunnelService {
      */
     GuacamoleTunnel getGuacamoleTunnel(RemoteAuthenticatedUser user,
             SharedConnectionDefinition definition,
-            GuacamoleClientInformation info)
+            GuacamoleClientInformation info, Map<String, String> tokens)
             throws GuacamoleException;
 
 }

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/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 984e772..18e3b9c 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
@@ -39,8 +39,6 @@ import org.apache.guacamole.net.auth.AuthenticatedUser;
 import org.apache.guacamole.net.auth.Connection;
 import org.apache.guacamole.net.auth.simple.SimpleConnection;
 import org.apache.guacamole.protocol.GuacamoleConfiguration;
-import org.apache.guacamole.token.StandardTokens;
-import org.apache.guacamole.token.TokenFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -122,10 +120,6 @@ public class ConnectionService {
                 confService.getLDAPSearchConstraints()
             );
 
-            // Build token filter containing credential tokens
-            TokenFilter tokenFilter = new TokenFilter();
-            StandardTokens.addStandardTokens(tokenFilter, user);
-
             // Produce connections for each readable configuration
             Map<String, Connection> connections = new HashMap<String, Connection>();
             while (results.hasMore()) {
@@ -180,9 +174,6 @@ public class ConnectionService {
 
                     }
 
-                    // Filter the configuration, substituting all defined tokens
-                    tokenFilter.filterValues(config.getParameters());
-
                     // Store connection using cn for both identifier and name
                     String name = cn.getStringValue();
                     Connection connection = new SimpleConnection(name, name, config);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectionGroup.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectionGroup.java b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectionGroup.java
index cbce379..dbb6934 100644
--- a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectionGroup.java
+++ b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectionGroup.java
@@ -108,8 +108,8 @@ public class QuickConnectionGroup extends AbstractConnectionGroup {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info) 
-            throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
         // This group does not support connections
         throw new GuacamoleSecurityException("Permission denied.");
     }

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connectable.java
----------------------------------------------------------------------
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connectable.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connectable.java
index 7face92..39b12f9 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connectable.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connectable.java
@@ -19,6 +19,7 @@
 
 package org.apache.guacamole.net.auth;
 
+import java.util.Map;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.net.GuacamoleTunnel;
 import org.apache.guacamole.protocol.GuacamoleClientInformation;
@@ -31,11 +32,21 @@ public interface Connectable {
     /**
      * Establishes a connection to guacd using the information associated with
      * this object. The connection will be provided the given client
-     * information.
+     * information. Implementations which support parameter tokens should
+     * apply the given tokens when configuring the connection, such as with a
+     * {@link org.apache.guacamole.token.TokenFilter}.
+     *
+     * @see <a href="http://guacamole.apache.org/doc/gug/configuring-guacamole.html#parameter-tokens">Parameter Tokens</a>
      *
      * @param info
      *     Information associated with the connecting client.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection. If the
+     *     implementation does not support parameter tokens, this Map may be
+     *     ignored.
+     *
      * @return
      *     A fully-established GuacamoleTunnel.
      *
@@ -43,8 +54,8 @@ public interface Connectable {
      *     If an error occurs while connecting to guacd, or if permission to
      *     connect is denied.
      */
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException;
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException;
 
     /**
      * Returns the number of active connections associated with this object.

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java
----------------------------------------------------------------------
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java
index fa1ab78..b80e868 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java
@@ -128,9 +128,9 @@ public class DelegatingConnection implements Connection {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException {
-        return connection.connect(info);
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
+        return connection.connect(info, tokens);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java
----------------------------------------------------------------------
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java
index db647d6..1d958bd 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java
@@ -119,8 +119,9 @@ public class DelegatingConnectionGroup implements ConnectionGroup {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException {
-        return connectionGroup.connect(info);
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
+        return connectionGroup.connect(info, tokens);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java
index 7b1e3e7..6d08d99 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java
@@ -31,8 +31,6 @@ import org.apache.guacamole.net.auth.AuthenticatedUser;
 import org.apache.guacamole.net.auth.Credentials;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.protocol.GuacamoleConfiguration;
-import org.apache.guacamole.token.StandardTokens;
-import org.apache.guacamole.token.TokenFilter;
 
 /**
  * Provides means of retrieving a set of named GuacamoleConfigurations for a
@@ -140,84 +138,13 @@ public abstract class SimpleAuthenticationProvider
 
     }
 
-    /**
-     * Given an arbitrary credentials object, returns a Map containing all
-     * configurations authorized by those credentials, filtering those
-     * configurations using a TokenFilter and the standard credential tokens
-     * (like ${GUAC_USERNAME} and ${GUAC_PASSWORD}). The keys of this Map
-     * are Strings which uniquely identify each configuration.
-     *
-     * @param credentials
-     *     The credentials to use to retrieve authorized configurations.
-     *
-     * @return
-     *     A Map of all configurations authorized by the given credentials, or
-     *     null if the credentials given are not authorized.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving configurations.
-     */
-    private Map<String, GuacamoleConfiguration>
-            getFilteredAuthorizedConfigurations(Credentials credentials)
-            throws GuacamoleException {
-
-        // Get configurations
-        Map<String, GuacamoleConfiguration> configs =
-                getAuthorizedConfigurations(credentials);
-
-        // Return as unauthorized if not authorized to retrieve configs
-        if (configs == null)
-            return null;
-
-        // Build credential TokenFilter
-        TokenFilter tokenFilter = new TokenFilter();
-        StandardTokens.addStandardTokens(tokenFilter, credentials);
-
-        // Filter each configuration
-        for (GuacamoleConfiguration config : configs.values())
-            tokenFilter.filterValues(config.getParameters());
-
-        return configs;
-
-    }
-
-    /**
-     * Given a user who has already been authenticated, returns a Map
-     * containing all configurations for which that user is authorized,
-     * filtering those configurations using a TokenFilter and the standard
-     * credential tokens (like ${GUAC_USERNAME} and ${GUAC_PASSWORD}). The keys
-     * of this Map are Strings which uniquely identify each configuration.
-     *
-     * @param authenticatedUser
-     *     The user whose authorized configurations are to be retrieved.
-     *
-     * @return
-     *     A Map of all configurations authorized for use by the given user, or
-     *     null if the user is not authorized to use any configurations.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving configurations.
-     */
-    private Map<String, GuacamoleConfiguration>
-            getFilteredAuthorizedConfigurations(AuthenticatedUser authenticatedUser)
-            throws GuacamoleException {
-
-        // Pull cached configurations, if any
-        if (authenticatedUser instanceof SimpleAuthenticatedUser && authenticatedUser.getAuthenticationProvider() == this)
-            return ((SimpleAuthenticatedUser) authenticatedUser).getAuthorizedConfigurations();
-
-        // Otherwise, pull using credentials
-        return getFilteredAuthorizedConfigurations(authenticatedUser.getCredentials());
-
-    }
-
     @Override
     public AuthenticatedUser authenticateUser(final Credentials credentials)
             throws GuacamoleException {
 
         // Get configurations
         Map<String, GuacamoleConfiguration> configs =
-                getFilteredAuthorizedConfigurations(credentials);
+                getAuthorizedConfigurations(credentials);
 
         // Return as unauthorized if not authorized to retrieve configs
         if (configs == null)
@@ -233,7 +160,7 @@ public abstract class SimpleAuthenticationProvider
 
         // Get configurations
         Map<String, GuacamoleConfiguration> configs =
-                getFilteredAuthorizedConfigurations(authenticatedUser);
+                getAuthorizedConfigurations(authenticatedUser.getCredentials());
 
         // Return as unauthorized if not authorized to retrieve configs
         if (configs == null)

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java
----------------------------------------------------------------------
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java
index 85783a0..f9da240 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java
@@ -38,9 +38,14 @@ import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration;
 import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
 import org.apache.guacamole.protocol.GuacamoleClientInformation;
 import org.apache.guacamole.protocol.GuacamoleConfiguration;
+import org.apache.guacamole.token.TokenFilter;
 
 /**
- * An extremely basic Connection implementation.
+ * An extremely basic Connection implementation. The underlying connection to
+ * guacd is established using the configuration information provided in
+ * guacamole.properties. Parameter tokens provided to connect() are
+ * automatically applied. Tracking of active connections and connection history
+ * is not provided.
  */
 public class SimpleConnection extends AbstractConnection {
 
@@ -95,8 +100,8 @@ public class SimpleConnection extends AbstractConnection {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info)
-            throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
 
         // Retrieve proxy configuration from environment
         Environment environment = new LocalEnvironment();
@@ -106,6 +111,11 @@ public class SimpleConnection extends AbstractConnection {
         String hostname = proxyConfig.getHostname();
         int port = proxyConfig.getPort();
 
+        // Apply tokens to config parameters
+        GuacamoleConfiguration filteredConfig = new GuacamoleConfiguration(config);
+        TokenFilter tokenFilter = new TokenFilter();
+        tokenFilter.filterValues(config.getParameters());
+
         GuacamoleSocket socket;
 
         // Determine socket type based on required encryption method
@@ -115,7 +125,7 @@ public class SimpleConnection extends AbstractConnection {
             case SSL:
                 socket = new ConfiguredGuacamoleSocket(
                     new SSLGuacamoleSocket(hostname, port),
-                    config, info
+                    filteredConfig, info
                 );
                 break;
 
@@ -123,7 +133,7 @@ public class SimpleConnection extends AbstractConnection {
             case NONE:
                 socket = new ConfiguredGuacamoleSocket(
                     new InetGuacamoleSocket(hostname, port),
-                    config, info
+                    filteredConfig, info
                 );
                 break;
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java
----------------------------------------------------------------------
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java
index 3a7df28..a077eb3 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java
@@ -109,8 +109,8 @@ public class SimpleConnectionGroup extends AbstractConnectionGroup {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info) 
-            throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
         throw new GuacamoleSecurityException("Permission denied.");
     }
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/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 8faca15..22a042e 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
@@ -29,7 +29,12 @@ import org.apache.guacamole.net.auth.Credentials;
 /**
  * Utility class which provides access to standardized token names, as well as
  * facilities for generating those tokens from common objects.
+ *
+ * @deprecated Standard tokens are now supplied by default to the connect()
+ * functions of connections and connection groups. Manually generating the
+ * standard tokens is not necessary.
  */
+@Deprecated
 public class StandardTokens {
 
     /**

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java
index 3a987e5..704db23 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java
@@ -128,7 +128,8 @@ public class APIConnectionWrapper implements Connection {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
         throw new UnsupportedOperationException("Operation not supported.");
     }
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/APIConnectionGroupWrapper.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/APIConnectionGroupWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/APIConnectionGroupWrapper.java
index 625b009..552b787 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/APIConnectionGroupWrapper.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/APIConnectionGroupWrapper.java
@@ -112,7 +112,8 @@ public class APIConnectionGroupWrapper implements ConnectionGroup {
     }
 
     @Override
-    public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException {
+    public GuacamoleTunnel connect(GuacamoleClientInformation info,
+            Map<String, String> tokens) throws GuacamoleException {
         throw new UnsupportedOperationException("Operation not supported.");
     }
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/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
new file mode 100644
index 0000000..1d357d2
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/StandardTokenMap.java
@@ -0,0 +1,139 @@
+/*
+ * 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.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;
+
+/**
+ * Map which is automatically populated with the name/value pairs of all
+ * standardized tokens available for a particular AuthenticatedUser.
+ */
+public class StandardTokenMap extends HashMap<String, String> {
+
+    /**
+     * The name of the token containing the user's username.
+     */
+    public static final String USERNAME_TOKEN = "GUAC_USERNAME";
+
+    /**
+     * The name of the token containing the user's password.
+     */
+    public static final String PASSWORD_TOKEN = "GUAC_PASSWORD";
+
+    /**
+     * The name of the token containing the hostname/address of the machine the
+     * user authenticated from.
+     */
+    public static final String CLIENT_HOSTNAME_TOKEN = "GUAC_CLIENT_HOSTNAME";
+
+    /**
+     * The name of the token containing the IP address of the machine the user
+     * authenticated from.
+     */
+    public static final String CLIENT_ADDRESS_TOKEN = "GUAC_CLIENT_ADDRESS";
+
+    /**
+     * The name of the token containing the current date (server-local time).
+     */
+    public static final String DATE_TOKEN = "GUAC_DATE";
+
+    /**
+     * The name of the token containing the current time (server-local time).
+     */
+    public static final String TIME_TOKEN = "GUAC_TIME";
+
+    /**
+     * The date format that should be used for the date token. This format must
+     * be compatible with Java's SimpleDateFormat.
+     */
+    private static final String DATE_FORMAT = "yyyyMMdd";
+
+    /**
+     * The date format that should be used for the time token. This format must
+     * be compatible with Java's SimpleDateFormat.
+     */
+    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.
+     *
+     * @param authenticatedUser
+     *     The AuthenticatedUser to generate standard tokens for.
+     */
+    public StandardTokenMap(AuthenticatedUser authenticatedUser) {
+
+        // Add date/time tokens (server-local time)
+        Date currentTime = new Date();
+        put(DATE_TOKEN, new SimpleDateFormat(DATE_FORMAT).format(currentTime));
+        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();
+        if (username != null)
+            put(USERNAME_TOKEN, username);
+
+        // Default to the authenticated user's username for the GUAC_USERNAME
+        // token
+        else
+            put(USERNAME_TOKEN, authenticatedUser.getIdentifier());
+
+        // Add password token
+        String password = credentials.getPassword();
+        if (password != null)
+            put(PASSWORD_TOKEN, password);
+
+        // Add client hostname token
+        String hostname = credentials.getRemoteHostname();
+        if (hostname != null)
+            put(CLIENT_HOSTNAME_TOKEN, hostname);
+
+        // Add client address token
+        String address = credentials.getRemoteAddress();
+        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);
+            }
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1210d562/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
index e023a70..1479d82 100644
--- a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
+++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
@@ -22,6 +22,7 @@ package org.apache.guacamole.tunnel;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.util.List;
+import java.util.Map;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.GuacamoleSecurityException;
 import org.apache.guacamole.GuacamoleSession;
@@ -187,6 +188,10 @@ public class TunnelRequestService {
      * @param info
      *     Information describing the connected Guacamole client.
      *
+     * @param tokens
+     *     A Map containing the token names and corresponding values to be
+     *     applied as parameter tokens when establishing the connection.
+     *
      * @return
      *     A new tunnel, connected as required by the request.
      *
@@ -195,7 +200,7 @@ public class TunnelRequestService {
      */
     protected GuacamoleTunnel createConnectedTunnel(UserContext context,
             final TunnelRequest.Type type, String id,
-            GuacamoleClientInformation info)
+            GuacamoleClientInformation info, Map<String, String> tokens)
             throws GuacamoleException {
 
         // Create connected tunnel from identifier
@@ -216,7 +221,7 @@ public class TunnelRequestService {
                 }
 
                 // Connect tunnel
-                tunnel = connection.connect(info);
+                tunnel = connection.connect(info, tokens);
                 logger.info("User \"{}\" connected to connection \"{}\".", context.self().getIdentifier(), id);
                 break;
             }
@@ -235,7 +240,7 @@ public class TunnelRequestService {
                 }
 
                 // Connect tunnel
-                tunnel = group.connect(info);
+                tunnel = group.connect(info, tokens);
                 logger.info("User \"{}\" connected to group \"{}\".", context.self().getIdentifier(), id);
                 break;
             }
@@ -385,16 +390,17 @@ public class TunnelRequestService {
         GuacamoleClientInformation info = getClientInformation(request);
 
         GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
+        AuthenticatedUser authenticatedUser = session.getAuthenticatedUser();
         UserContext userContext = session.getUserContext(authProviderIdentifier);
 
         try {
 
             // Create connected tunnel using provided connection ID and client information
-            GuacamoleTunnel tunnel = createConnectedTunnel(userContext, type, id, info);
+            GuacamoleTunnel tunnel = createConnectedTunnel(userContext, type,
+                    id, info, new StandardTokenMap(authenticatedUser));
 
             // Notify listeners to allow connection to be vetoed
-            fireTunnelConnectEvent(session.getAuthenticatedUser(),
-                    session.getAuthenticatedUser().getCredentials(), tunnel);
+            fireTunnelConnectEvent(authenticatedUser, authenticatedUser.getCredentials(), tunnel);
 
             // Associate tunnel with session
             return createAssociatedTunnel(tunnel, authToken, session, userContext, type, id);