mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 21:51:23 +00:00
GUACAMOLE-524: Merge use decoration API to inject tokens from LDAP attributes.
This commit is contained in:
@@ -499,6 +499,10 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
|
|||||||
* @param info
|
* @param info
|
||||||
* Information associated with the connecting client.
|
* 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
|
* @return
|
||||||
* A connected GuacamoleTunnel associated with a newly-established
|
* A connected GuacamoleTunnel associated with a newly-established
|
||||||
* connection.
|
* connection.
|
||||||
@@ -507,12 +511,12 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
|
|||||||
* If permission to connect to this connection is denied.
|
* If permission to connect to this connection is denied.
|
||||||
*/
|
*/
|
||||||
public GuacamoleTunnel connect(ModeledAuthenticatedUser user,
|
public GuacamoleTunnel connect(ModeledAuthenticatedUser user,
|
||||||
ModeledConnection connection, GuacamoleClientInformation info)
|
ModeledConnection connection, GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
|
||||||
// Connect only if READ permission is granted
|
// Connect only if READ permission is granted
|
||||||
if (hasObjectPermission(user, connection.getIdentifier(), ObjectPermission.Type.READ))
|
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
|
// The user does not have permission to connect
|
||||||
throw new GuacamoleSecurityException("Permission denied.");
|
throw new GuacamoleSecurityException("Permission denied.");
|
||||||
|
@@ -259,8 +259,9 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException {
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
return connectionService.connect(getCurrentUser(), this, info);
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
return connectionService.connect(getCurrentUser(), this, info, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.connectiongroup;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
|
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
|
||||||
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
|
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
|
||||||
@@ -243,6 +244,10 @@ public class ConnectionGroupService extends ModeledChildDirectoryObjectService<M
|
|||||||
* @param info
|
* @param info
|
||||||
* Information associated with the connecting client.
|
* 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
|
* @return
|
||||||
* A connected GuacamoleTunnel associated with a newly-established
|
* A connected GuacamoleTunnel associated with a newly-established
|
||||||
* connection.
|
* connection.
|
||||||
@@ -251,12 +256,12 @@ public class ConnectionGroupService extends ModeledChildDirectoryObjectService<M
|
|||||||
* If permission to connect to this connection is denied.
|
* If permission to connect to this connection is denied.
|
||||||
*/
|
*/
|
||||||
public GuacamoleTunnel connect(ModeledAuthenticatedUser user,
|
public GuacamoleTunnel connect(ModeledAuthenticatedUser user,
|
||||||
ModeledConnectionGroup connectionGroup, GuacamoleClientInformation info)
|
ModeledConnectionGroup connectionGroup, GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
|
||||||
// Connect only if READ permission is granted
|
// Connect only if READ permission is granted
|
||||||
if (hasObjectPermission(user, connectionGroup.getIdentifier(), ObjectPermission.Type.READ))
|
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
|
// The user does not have permission to connect
|
||||||
throw new GuacamoleSecurityException("Permission denied.");
|
throw new GuacamoleSecurityException("Permission denied.");
|
||||||
|
@@ -135,9 +135,9 @@ public class ModeledConnectionGroup extends ModeledChildDirectoryObject<Connecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
return connectionGroupService.connect(getCurrentUser(), this, info);
|
return connectionGroupService.connect(getCurrentUser(), this, info, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -122,8 +122,8 @@ public class RootConnectionGroup extends RestrictedObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
throw new GuacamoleSecurityException("Permission denied.");
|
throw new GuacamoleSecurityException("Permission denied.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -131,9 +131,9 @@ public class SharedConnection implements Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
return tunnelService.getGuacamoleTunnel(user, definition, info);
|
return tunnelService.getGuacamoleTunnel(user, definition, info, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -98,8 +98,8 @@ public class SharedRootConnectionGroup implements ConnectionGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
throw new GuacamoleSecurityException("Permission denied.");
|
throw new GuacamoleSecurityException("Permission denied.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,7 +52,6 @@ import org.apache.guacamole.net.auth.ConnectionGroup;
|
|||||||
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
|
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||||
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
||||||
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||||
import org.apache.guacamole.token.StandardTokens;
|
|
||||||
import org.apache.guacamole.token.TokenFilter;
|
import org.apache.guacamole.token.TokenFilter;
|
||||||
import org.mybatis.guice.transactional.Transactional;
|
import org.mybatis.guice.transactional.Transactional;
|
||||||
import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper;
|
import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper;
|
||||||
@@ -233,13 +232,6 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
for (ConnectionParameterModel parameter : parameters)
|
for (ConnectionParameterModel parameter : parameters)
|
||||||
config.setParameter(parameter.getName(), parameter.getValue());
|
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;
|
return config;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -279,13 +271,6 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
for (SharingProfileParameterModel parameter : parameters)
|
for (SharingProfileParameterModel parameter : parameters)
|
||||||
config.setParameter(parameter.getName(), parameter.getValue());
|
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;
|
return config;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -454,6 +439,10 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
* Information describing the Guacamole client connecting to the given
|
* Information describing the Guacamole client connecting to the given
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
|
* @param tokens
|
||||||
|
* A Map containing the token names and corresponding values to be
|
||||||
|
* applied as parameter tokens when establishing the connection.
|
||||||
|
*
|
||||||
* @param interceptErrors
|
* @param interceptErrors
|
||||||
* Whether errors from the upstream remote desktop should be
|
* Whether errors from the upstream remote desktop should be
|
||||||
* intercepted and rethrown as GuacamoleUpstreamExceptions.
|
* intercepted and rethrown as GuacamoleUpstreamExceptions.
|
||||||
@@ -467,7 +456,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
* while connection configuration information is being retrieved.
|
* while connection configuration information is being retrieved.
|
||||||
*/
|
*/
|
||||||
private GuacamoleTunnel assignGuacamoleTunnel(ActiveConnectionRecord activeConnection,
|
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
|
// Record new active connection
|
||||||
Runnable cleanupTask = new ConnectionCleanupTask(activeConnection);
|
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
|
// Obtain socket which will automatically run the cleanup task
|
||||||
ConfiguredGuacamoleSocket socket = new ConfiguredGuacamoleSocket(
|
ConfiguredGuacamoleSocket socket = new ConfiguredGuacamoleSocket(
|
||||||
getUnconfiguredGuacamoleSocket(connection.getGuacamoleProxyConfiguration(),
|
getUnconfiguredGuacamoleSocket(connection.getGuacamoleProxyConfiguration(),
|
||||||
@@ -651,8 +648,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public GuacamoleTunnel getGuacamoleTunnel(final ModeledAuthenticatedUser user,
|
public GuacamoleTunnel getGuacamoleTunnel(final ModeledAuthenticatedUser user,
|
||||||
final ModeledConnection connection, GuacamoleClientInformation info)
|
final ModeledConnection connection, GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
|
||||||
// Acquire access to single connection, ignoring the failover-only flag
|
// Acquire access to single connection, ignoring the failover-only flag
|
||||||
acquire(user, Collections.singletonList(connection), true);
|
acquire(user, Collections.singletonList(connection), true);
|
||||||
@@ -660,7 +657,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
// Connect only if the connection was successfully acquired
|
// Connect only if the connection was successfully acquired
|
||||||
ActiveConnectionRecord connectionRecord = activeConnectionRecordProvider.get();
|
ActiveConnectionRecord connectionRecord = activeConnectionRecordProvider.get();
|
||||||
connectionRecord.init(user, connection);
|
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
|
@Transactional
|
||||||
public GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
|
public GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
|
||||||
ModeledConnectionGroup connectionGroup,
|
ModeledConnectionGroup connectionGroup,
|
||||||
GuacamoleClientInformation info) throws GuacamoleException {
|
GuacamoleClientInformation info, Map<String, String> tokens)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Track failures in upstream (remote desktop) connections
|
// Track failures in upstream (remote desktop) connections
|
||||||
boolean upstreamHasFailed = false;
|
boolean upstreamHasFailed = false;
|
||||||
@@ -706,7 +704,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
// Connect to acquired child
|
// Connect to acquired child
|
||||||
ActiveConnectionRecord connectionRecord = activeConnectionRecordProvider.get();
|
ActiveConnectionRecord connectionRecord = activeConnectionRecordProvider.get();
|
||||||
connectionRecord.init(user, connectionGroup, connection);
|
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 session affinity is enabled, prefer this connection going forward
|
||||||
if (connectionGroup.isSessionAffinityEnabled())
|
if (connectionGroup.isSessionAffinityEnabled())
|
||||||
@@ -755,7 +754,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
@Transactional
|
@Transactional
|
||||||
public GuacamoleTunnel getGuacamoleTunnel(RemoteAuthenticatedUser user,
|
public GuacamoleTunnel getGuacamoleTunnel(RemoteAuthenticatedUser user,
|
||||||
SharedConnectionDefinition definition,
|
SharedConnectionDefinition definition,
|
||||||
GuacamoleClientInformation info)
|
GuacamoleClientInformation info, Map<String, String> tokens)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Create a connection record which describes the shared connection
|
// Create a connection record which describes the shared connection
|
||||||
@@ -764,7 +763,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
|
|||||||
definition.getSharingProfile());
|
definition.getSharingProfile());
|
||||||
|
|
||||||
// Connect to shared connection described by the created record
|
// 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
|
// Register tunnel, such that it is closed when the
|
||||||
// SharedConnectionDefinition is invalidated
|
// SharedConnectionDefinition is invalidated
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
package org.apache.guacamole.auth.jdbc.tunnel;
|
package org.apache.guacamole.auth.jdbc.tunnel;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
|
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
|
||||||
import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
|
import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
|
||||||
import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
|
import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
|
||||||
@@ -73,6 +74,10 @@ public interface GuacamoleTunnelService {
|
|||||||
* Information describing the Guacamole client connecting to the given
|
* Information describing the Guacamole client connecting to the given
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
|
* @param tokens
|
||||||
|
* A Map containing the token names and corresponding values to be
|
||||||
|
* applied as parameter tokens when establishing the connection.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* A new GuacamoleTunnel which is configured and connected to the given
|
* A new GuacamoleTunnel which is configured and connected to the given
|
||||||
* connection.
|
* connection.
|
||||||
@@ -82,8 +87,8 @@ public interface GuacamoleTunnelService {
|
|||||||
* rules.
|
* rules.
|
||||||
*/
|
*/
|
||||||
GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
|
GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
|
||||||
ModeledConnection connection, GuacamoleClientInformation info)
|
ModeledConnection connection, GuacamoleClientInformation info,
|
||||||
throws GuacamoleException;
|
Map<String, String> tokens) throws GuacamoleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a collection containing connection records representing all
|
* Returns a collection containing connection records representing all
|
||||||
@@ -117,6 +122,10 @@ public interface GuacamoleTunnelService {
|
|||||||
* Information describing the Guacamole client connecting to the given
|
* Information describing the Guacamole client connecting to the given
|
||||||
* connection group.
|
* connection group.
|
||||||
*
|
*
|
||||||
|
* @param tokens
|
||||||
|
* A Map containing the token names and corresponding values to be
|
||||||
|
* applied as parameter tokens when establishing the connection.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* A new GuacamoleTunnel which is configured and connected to the given
|
* A new GuacamoleTunnel which is configured and connected to the given
|
||||||
* connection group.
|
* connection group.
|
||||||
@@ -127,7 +136,7 @@ public interface GuacamoleTunnelService {
|
|||||||
*/
|
*/
|
||||||
GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
|
GuacamoleTunnel getGuacamoleTunnel(ModeledAuthenticatedUser user,
|
||||||
ModeledConnectionGroup connectionGroup,
|
ModeledConnectionGroup connectionGroup,
|
||||||
GuacamoleClientInformation info)
|
GuacamoleClientInformation info, Map<String, String> tokens)
|
||||||
throws GuacamoleException;
|
throws GuacamoleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,6 +172,10 @@ public interface GuacamoleTunnelService {
|
|||||||
* Information describing the Guacamole client connecting to the given
|
* Information describing the Guacamole client connecting to the given
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
|
* @param tokens
|
||||||
|
* A Map containing the token names and corresponding values to be
|
||||||
|
* applied as parameter tokens when establishing the connection.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* A new GuacamoleTunnel which is configured and connected to the given
|
* A new GuacamoleTunnel which is configured and connected to the given
|
||||||
* active connection.
|
* active connection.
|
||||||
@@ -173,7 +186,7 @@ public interface GuacamoleTunnelService {
|
|||||||
*/
|
*/
|
||||||
GuacamoleTunnel getGuacamoleTunnel(RemoteAuthenticatedUser user,
|
GuacamoleTunnel getGuacamoleTunnel(RemoteAuthenticatedUser user,
|
||||||
SharedConnectionDefinition definition,
|
SharedConnectionDefinition definition,
|
||||||
GuacamoleClientInformation info)
|
GuacamoleClientInformation info, Map<String, String> tokens)
|
||||||
throws GuacamoleException;
|
throws GuacamoleException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -79,7 +79,6 @@ public class ModeledAuthenticatedUser extends RemoteAuthenticatedUser {
|
|||||||
super(authenticatedUser.getAuthenticationProvider(), authenticatedUser.getCredentials(), authenticatedUser.getEffectiveUserGroups());
|
super(authenticatedUser.getAuthenticationProvider(), authenticatedUser.getCredentials(), authenticatedUser.getEffectiveUserGroups());
|
||||||
this.modelAuthenticationProvider = modelAuthenticationProvider;
|
this.modelAuthenticationProvider = modelAuthenticationProvider;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
super.setAttributes(authenticatedUser.getAttributes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.auth.jdbc.user;
|
package org.apache.guacamole.auth.jdbc.user;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||||
@@ -52,16 +51,6 @@ public abstract class RemoteAuthenticatedUser implements AuthenticatedUser {
|
|||||||
*/
|
*/
|
||||||
private final Set<String> effectiveGroups;
|
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
|
* Creates a new RemoteAuthenticatedUser, deriving the associated remote
|
||||||
* host from the given credentials.
|
* host from the given credentials.
|
||||||
|
@@ -153,6 +153,14 @@
|
|||||||
<version>3.0</version>
|
<version>3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JUnit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -30,11 +30,12 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.guacamole.auth.ldap.user.AuthenticatedUser;
|
import org.apache.guacamole.auth.ldap.user.LDAPAuthenticatedUser;
|
||||||
import org.apache.guacamole.auth.ldap.user.UserContext;
|
import org.apache.guacamole.auth.ldap.user.LDAPUserContext;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.GuacamoleServerException;
|
import org.apache.guacamole.GuacamoleServerException;
|
||||||
import org.apache.guacamole.auth.ldap.user.UserService;
|
import org.apache.guacamole.auth.ldap.user.UserService;
|
||||||
|
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.Credentials;
|
import org.apache.guacamole.net.auth.Credentials;
|
||||||
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
|
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
|
||||||
import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
|
import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
|
||||||
@@ -74,13 +75,13 @@ public class AuthenticationProviderService {
|
|||||||
* Provider for AuthenticatedUser objects.
|
* Provider for AuthenticatedUser objects.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private Provider<AuthenticatedUser> authenticatedUserProvider;
|
private Provider<LDAPAuthenticatedUser> authenticatedUserProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provider for UserContext objects.
|
* Provider for UserContext objects.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private Provider<UserContext> userContextProvider;
|
private Provider<LDAPUserContext> userContextProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the DN which corresponds to the user having the given
|
* Determines the DN which corresponds to the user having the given
|
||||||
@@ -211,7 +212,7 @@ public class AuthenticationProviderService {
|
|||||||
* If an error occurs while authenticating the user, or if access is
|
* If an error occurs while authenticating the user, or if access is
|
||||||
* denied.
|
* denied.
|
||||||
*/
|
*/
|
||||||
public AuthenticatedUser authenticateUser(Credentials credentials)
|
public LDAPAuthenticatedUser authenticateUser(Credentials credentials)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Attempt bind
|
// Attempt bind
|
||||||
@@ -231,8 +232,8 @@ public class AuthenticationProviderService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Return AuthenticatedUser if bind succeeds
|
// Return AuthenticatedUser if bind succeeds
|
||||||
AuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
|
LDAPAuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
|
||||||
authenticatedUser.init(credentials, getLDAPAttributes(ldapConnection, credentials.getUsername()));
|
authenticatedUser.init(credentials, getAttributeTokens(ldapConnection, credentials.getUsername()));
|
||||||
|
|
||||||
return authenticatedUser;
|
return authenticatedUser;
|
||||||
|
|
||||||
@@ -245,43 +246,44 @@ public class AuthenticationProviderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all custom LDAP attributes on the user currently bound under
|
* Returns parameter tokens generated from LDAP attributes on the user
|
||||||
* the given LDAP connection. The custom attributes are specified in
|
* currently bound under the given LDAP connection. The attributes to be
|
||||||
* guacamole.properties. If no attributes are specified or none are
|
* 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.
|
* found on the LDAP user object, an empty map is returned.
|
||||||
*
|
*
|
||||||
* @param ldapConnection
|
* @param ldapConnection
|
||||||
* LDAP connection to find the custom LDAP attributes.
|
* LDAP connection to use to read the attributes of the user.
|
||||||
*
|
*
|
||||||
* @param username
|
* @param username
|
||||||
* The username of the user whose attributes are queried.
|
* The username of the user whose attributes are to be queried.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* All attributes on the user currently bound under the
|
* A map of parameter tokens generated from attributes on the user
|
||||||
* given LDAP connection, as a map of attribute name to
|
* currently bound under the given LDAP connection, as a map of token
|
||||||
* corresponding attribute value, or an empty map if no
|
* name to corresponding value, or an empty map if no attributes are
|
||||||
* attributes are specified or none are found on the user
|
* specified or none are found on the user object.
|
||||||
* object.
|
|
||||||
*
|
*
|
||||||
* @throws GuacamoleException
|
* @throws GuacamoleException
|
||||||
* If an error occurs retrieving the user DN or the attributes.
|
* 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 {
|
String username) throws GuacamoleException {
|
||||||
|
|
||||||
// Get attributes from configuration information
|
// Get attributes from configuration information
|
||||||
List<String> attrList = confService.getAttributes();
|
List<String> attrList = confService.getAttributes();
|
||||||
|
|
||||||
// If there are no attributes there is no reason to search LDAP
|
// 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();
|
return Collections.<String, String>emptyMap();
|
||||||
|
|
||||||
// Build LDAP query parameters
|
// Build LDAP query parameters
|
||||||
String[] attrArray = attrList.toArray(new String[attrList.size()]);
|
String[] attrArray = attrList.toArray(new String[attrList.size()]);
|
||||||
String userDN = getUserBindDN(username);
|
String userDN = getUserBindDN(username);
|
||||||
|
|
||||||
Map<String, String> attrMap = new HashMap<String, String>();
|
Map<String, String> tokens = new HashMap<String, String>();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Get LDAP attributes by querying LDAP
|
// Get LDAP attributes by querying LDAP
|
||||||
LDAPEntry userEntry = ldapConnection.read(userDN, attrArray);
|
LDAPEntry userEntry = ldapConnection.read(userDN, attrArray);
|
||||||
if (userEntry == null)
|
if (userEntry == null)
|
||||||
@@ -291,17 +293,19 @@ public class AuthenticationProviderService {
|
|||||||
if (attrSet == null)
|
if (attrSet == null)
|
||||||
return Collections.<String, String>emptyMap();
|
return Collections.<String, String>emptyMap();
|
||||||
|
|
||||||
// Add each attribute into Map
|
// Convert each retrieved attribute into a corresponding token
|
||||||
for (Object attrObj : attrSet) {
|
for (Object attrObj : attrSet) {
|
||||||
LDAPAttribute attr = (LDAPAttribute)attrObj;
|
LDAPAttribute attr = (LDAPAttribute)attrObj;
|
||||||
attrMap.put(attr.getName(), attr.getStringValue());
|
tokens.put(TokenName.fromAttribute(attr.getName()), attr.getStringValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (LDAPException e) {
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,7 +322,7 @@ public class AuthenticationProviderService {
|
|||||||
* @throws GuacamoleException
|
* @throws GuacamoleException
|
||||||
* If the UserContext cannot be created due to an error.
|
* If the UserContext cannot be created due to an error.
|
||||||
*/
|
*/
|
||||||
public UserContext getUserContext(org.apache.guacamole.net.auth.AuthenticatedUser authenticatedUser)
|
public LDAPUserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Bind using credentials associated with AuthenticatedUser
|
// Bind using credentials associated with AuthenticatedUser
|
||||||
@@ -330,7 +334,7 @@ public class AuthenticationProviderService {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
// Build user context by querying LDAP
|
// Build user context by querying LDAP
|
||||||
UserContext userContext = userContextProvider.get();
|
LDAPUserContext userContext = userContextProvider.get();
|
||||||
userContext.init(authenticatedUser, ldapConnection);
|
userContext.init(authenticatedUser, ldapConnection);
|
||||||
return userContext;
|
return userContext;
|
||||||
|
|
||||||
|
@@ -355,7 +355,8 @@ public class ConfigurationService {
|
|||||||
*/
|
*/
|
||||||
public List<String> getAttributes() throws GuacamoleException {
|
public List<String> getAttributes() throws GuacamoleException {
|
||||||
return environment.getProperty(
|
return environment.getProperty(
|
||||||
LDAPGuacamoleProperties.LDAP_USER_ATTRIBUTES
|
LDAPGuacamoleProperties.LDAP_USER_ATTRIBUTES,
|
||||||
|
Collections.<String>emptyList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,9 +23,11 @@ package org.apache.guacamole.auth.ldap;
|
|||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
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.AbstractAuthenticationProvider;
|
||||||
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.Credentials;
|
import org.apache.guacamole.net.auth.Credentials;
|
||||||
|
import org.apache.guacamole.net.auth.TokenInjectingUserContext;
|
||||||
import org.apache.guacamole.net.auth.UserContext;
|
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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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.auth.ldap;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for generating parameter token names.
|
||||||
|
*/
|
||||||
|
public class TokenName {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix string to add to each parameter token generated from an LDAP
|
||||||
|
* attribute name.
|
||||||
|
*/
|
||||||
|
private static final String LDAP_ATTRIBUTE_TOKEN_PREFIX = "LDAP_";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pattern which matches logical groupings of words within an LDAP
|
||||||
|
* attribute name. This pattern is intended to match logical groupings
|
||||||
|
* regardless of the naming convention used: "CamelCase",
|
||||||
|
* "headlessCamelCase", "lowercase_with_underscores",
|
||||||
|
* "lowercase-with-dashes" or even "aVery-INCONSISTENTMix_ofAllStyles".
|
||||||
|
*/
|
||||||
|
private static final Pattern LDAP_ATTRIBUTE_NAME_GROUPING = Pattern.compile(
|
||||||
|
|
||||||
|
// "Camel" word groups
|
||||||
|
"\\p{javaUpperCase}\\p{javaLowerCase}+"
|
||||||
|
|
||||||
|
// Groups of digits
|
||||||
|
+ "|[0-9]+"
|
||||||
|
|
||||||
|
// Groups of uppercase letters, excluding the uppercase letter
|
||||||
|
// which begins a following "Camel" group
|
||||||
|
+ "|\\p{javaUpperCase}+(?!\\p{javaLowerCase})"
|
||||||
|
|
||||||
|
// Groups of lowercase letters which match no other pattern
|
||||||
|
+ "|\\p{javaLowerCase}+"
|
||||||
|
|
||||||
|
// Groups of word characters letters which match no other pattern
|
||||||
|
+ "|\\b\\w+\\b"
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This utility class should not be instantiated.
|
||||||
|
*/
|
||||||
|
private TokenName() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the name of the parameter token that should be populated with
|
||||||
|
* the value of the given LDAP attribute. The name of the LDAP attribute
|
||||||
|
* will automatically be transformed from "CamelCase", "headlessCamelCase",
|
||||||
|
* "lowercase_with_underscores", and "mixes_ofBoth_Styles" to consistent
|
||||||
|
* "UPPERCASE_WITH_UNDERSCORES". Each returned attribute will be prefixed
|
||||||
|
* with "LDAP_".
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* The name of the LDAP attribute to use to generate the token name.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The name of the parameter token that should be populated with the
|
||||||
|
* value of the LDAP attribute having the given name.
|
||||||
|
*/
|
||||||
|
public static String fromAttribute(String name) {
|
||||||
|
|
||||||
|
// If even one logical word grouping cannot be found, default to
|
||||||
|
// simply converting the attribute to uppercase and adding the
|
||||||
|
// prefix
|
||||||
|
Matcher groupMatcher = LDAP_ATTRIBUTE_NAME_GROUPING.matcher(name);
|
||||||
|
if (!groupMatcher.find())
|
||||||
|
return LDAP_ATTRIBUTE_TOKEN_PREFIX + name.toUpperCase();
|
||||||
|
|
||||||
|
// Split the given name into logical word groups, separated by
|
||||||
|
// underscores and converted to uppercase
|
||||||
|
StringBuilder builder = new StringBuilder(LDAP_ATTRIBUTE_TOKEN_PREFIX);
|
||||||
|
builder.append(groupMatcher.group(0).toUpperCase());
|
||||||
|
|
||||||
|
while (groupMatcher.find()) {
|
||||||
|
builder.append("_");
|
||||||
|
builder.append(groupMatcher.group(0).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -35,12 +35,12 @@ import org.apache.guacamole.auth.ldap.ConfigurationService;
|
|||||||
import org.apache.guacamole.auth.ldap.EscapingService;
|
import org.apache.guacamole.auth.ldap.EscapingService;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.GuacamoleServerException;
|
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.AuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.Connection;
|
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.net.auth.simple.SimpleConnection;
|
||||||
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -122,10 +122,6 @@ public class ConnectionService {
|
|||||||
confService.getLDAPSearchConstraints()
|
confService.getLDAPSearchConstraints()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Build token filter containing credential tokens
|
|
||||||
TokenFilter tokenFilter = new TokenFilter();
|
|
||||||
StandardTokens.addStandardTokens(tokenFilter, user);
|
|
||||||
|
|
||||||
// Produce connections for each readable configuration
|
// Produce connections for each readable configuration
|
||||||
Map<String, Connection> connections = new HashMap<String, Connection>();
|
Map<String, Connection> connections = new HashMap<String, Connection>();
|
||||||
while (results.hasMore()) {
|
while (results.hasMore()) {
|
||||||
@@ -180,13 +176,17 @@ public class ConnectionService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter the configuration, substituting all defined tokens
|
|
||||||
tokenFilter.filterValues(config.getParameters());
|
|
||||||
|
|
||||||
// Store connection using cn for both identifier and name
|
// Store connection using cn for both identifier and name
|
||||||
String name = cn.getStringValue();
|
String name = cn.getStringValue();
|
||||||
Connection connection = new SimpleConnection(name, name, config);
|
Connection connection = new SimpleConnection(name, name, config);
|
||||||
connection.setParentIdentifier(LDAPAuthenticationProvider.ROOT_CONNECTION_GROUP);
|
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);
|
connections.put(name, connection);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
package org.apache.guacamole.auth.ldap.user;
|
package org.apache.guacamole.auth.ldap.user;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
|
import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||||
@@ -29,7 +30,7 @@ import org.apache.guacamole.net.auth.Credentials;
|
|||||||
* An LDAP-specific implementation of AuthenticatedUser, associating a
|
* An LDAP-specific implementation of AuthenticatedUser, associating a
|
||||||
* particular set of credentials with the LDAP authentication provider.
|
* particular set of credentials with the LDAP authentication provider.
|
||||||
*/
|
*/
|
||||||
public class AuthenticatedUser extends AbstractAuthenticatedUser {
|
public class LDAPAuthenticatedUser extends AbstractAuthenticatedUser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the authentication provider associated with this
|
* Reference to the authentication provider associated with this
|
||||||
@@ -44,35 +45,40 @@ public class AuthenticatedUser extends AbstractAuthenticatedUser {
|
|||||||
private Credentials credentials;
|
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
|
* Initializes this AuthenticatedUser using the given credentials and
|
||||||
* arbitrary attributes.
|
* connection parameter tokens.
|
||||||
*
|
*
|
||||||
* @param credentials
|
* @param credentials
|
||||||
* The credentials provided when this user was authenticated.
|
* The credentials provided when this user was authenticated.
|
||||||
*
|
*
|
||||||
* @param attributes
|
* @param tokens
|
||||||
* The map of arbitrary attribute name/value pairs to associate with
|
* A Map of all name/value pairs that should be applied as parameter
|
||||||
* this AuthenticatedUser.
|
* 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.credentials = credentials;
|
||||||
this.attributes = attributes;
|
this.tokens = Collections.unmodifiableMap(tokens);
|
||||||
setIdentifier(credentials.getUsername());
|
setIdentifier(credentials.getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public Map<String, String> getAttributes() {
|
* Returns a Map of all name/value pairs that should be applied as
|
||||||
return attributes;
|
* parameter tokens when connections are established using this
|
||||||
}
|
* AuthenticatedUser.
|
||||||
|
*
|
||||||
@Override
|
* @return
|
||||||
public void setAttributes(Map<String, String> attributes) {
|
* A Map of all name/value pairs that should be applied as parameter
|
||||||
// All attributes are read-only
|
* tokens when connections are established using this
|
||||||
|
* AuthenticatedUser.
|
||||||
|
*/
|
||||||
|
public Map<String, String> getTokens() {
|
||||||
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -42,12 +42,12 @@ import org.slf4j.LoggerFactory;
|
|||||||
* An LDAP-specific implementation of UserContext which queries all Guacamole
|
* An LDAP-specific implementation of UserContext which queries all Guacamole
|
||||||
* connections and users from the LDAP directory.
|
* connections and users from the LDAP directory.
|
||||||
*/
|
*/
|
||||||
public class UserContext extends AbstractUserContext {
|
public class LDAPUserContext extends AbstractUserContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger for this class.
|
* Logger for this class.
|
||||||
*/
|
*/
|
||||||
private final Logger logger = LoggerFactory.getLogger(UserContext.class);
|
private final Logger logger = LoggerFactory.getLogger(LDAPUserContext.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for retrieving Guacamole connections from the LDAP server.
|
* Service for retrieving Guacamole connections from the LDAP server.
|
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.auth.ldap;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test which verifies automatic generation of LDAP-specific connection
|
||||||
|
* parameter token names.
|
||||||
|
*/
|
||||||
|
public class TokenNameTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that TokenName.fromAttribute() generates token names as
|
||||||
|
* specified, regardless of the naming convention of the attribute.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testFromAttribute() {
|
||||||
|
assertEquals("LDAP_A", TokenName.fromAttribute("a"));
|
||||||
|
assertEquals("LDAP_B", TokenName.fromAttribute("b"));
|
||||||
|
assertEquals("LDAP_1", TokenName.fromAttribute("1"));
|
||||||
|
assertEquals("LDAP_SOME_URL", TokenName.fromAttribute("someURL"));
|
||||||
|
assertEquals("LDAP_LOWERCASE_WITH_DASHES", TokenName.fromAttribute("lowercase-with-dashes"));
|
||||||
|
assertEquals("LDAP_HEADLESS_CAMEL_CASE", TokenName.fromAttribute("headlessCamelCase"));
|
||||||
|
assertEquals("LDAP_CAMEL_CASE", TokenName.fromAttribute("CamelCase"));
|
||||||
|
assertEquals("LDAP_CAMEL_CASE", TokenName.fromAttribute("CamelCase"));
|
||||||
|
assertEquals("LDAP_LOWERCASE_WITH_UNDERSCORES", TokenName.fromAttribute("lowercase_with_underscores"));
|
||||||
|
assertEquals("LDAP_UPPERCASE_WITH_UNDERSCORES", TokenName.fromAttribute("UPPERCASE_WITH_UNDERSCORES"));
|
||||||
|
assertEquals("LDAP_A_VERY_INCONSISTENT_MIX_OF_ALL_STYLES", TokenName.fromAttribute("aVery-INCONSISTENTMix_ofAllStyles"));
|
||||||
|
assertEquals("LDAP_ABC_123_DEF_456", TokenName.fromAttribute("abc123def456"));
|
||||||
|
assertEquals("LDAP_ABC_123_DEF_456", TokenName.fromAttribute("ABC123DEF456"));
|
||||||
|
assertEquals("LDAP_WORD_A_WORD_AB_WORD_ABC_WORD", TokenName.fromAttribute("WordAWordABWordABCWord"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -108,8 +108,8 @@ public class QuickConnectionGroup extends AbstractConnectionGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
// This group does not support connections
|
// This group does not support connections
|
||||||
throw new GuacamoleSecurityException("Permission denied.");
|
throw new GuacamoleSecurityException("Permission denied.");
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
package org.apache.guacamole.net.auth;
|
package org.apache.guacamole.net.auth;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,14 +41,4 @@ public abstract class AbstractAuthenticatedUser extends AbstractIdentifiable
|
|||||||
// Nothing to invalidate
|
// Nothing to invalidate
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getAttributes() {
|
|
||||||
return Collections.<String, String>emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAttributes(Map<String, String> attributes) {
|
|
||||||
//do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ import java.util.Set;
|
|||||||
* A user of the Guacamole web application who has been authenticated by an
|
* A user of the Guacamole web application who has been authenticated by an
|
||||||
* AuthenticationProvider.
|
* AuthenticationProvider.
|
||||||
*/
|
*/
|
||||||
public interface AuthenticatedUser extends Identifiable, Attributes {
|
public interface AuthenticatedUser extends Identifiable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identifier reserved for representing a user that has authenticated
|
* The identifier reserved for representing a user that has authenticated
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.net.auth;
|
package org.apache.guacamole.net.auth;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.net.GuacamoleTunnel;
|
import org.apache.guacamole.net.GuacamoleTunnel;
|
||||||
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
||||||
@@ -31,11 +32,21 @@ public interface Connectable {
|
|||||||
/**
|
/**
|
||||||
* Establishes a connection to guacd using the information associated with
|
* Establishes a connection to guacd using the information associated with
|
||||||
* this object. The connection will be provided the given client
|
* 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
|
* @param info
|
||||||
* Information associated with the connecting client.
|
* 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
|
* @return
|
||||||
* A fully-established GuacamoleTunnel.
|
* A fully-established GuacamoleTunnel.
|
||||||
*
|
*
|
||||||
@@ -43,8 +54,8 @@ public interface Connectable {
|
|||||||
* If an error occurs while connecting to guacd, or if permission to
|
* If an error occurs while connecting to guacd, or if permission to
|
||||||
* connect is denied.
|
* connect is denied.
|
||||||
*/
|
*/
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException;
|
Map<String, String> tokens) throws GuacamoleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of active connections associated with this object.
|
* Returns the number of active connections associated with this object.
|
||||||
|
@@ -128,9 +128,9 @@ public class DelegatingConnection implements Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
return connection.connect(info);
|
return connection.connect(info, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -119,8 +119,9 @@ public class DelegatingConnectionGroup implements ConnectionGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException {
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
return connectionGroup.connect(info);
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
return connectionGroup.connect(info, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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.net.auth;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
import org.apache.guacamole.net.GuacamoleTunnel;
|
||||||
|
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection implementation which overrides the connect() function of an
|
||||||
|
* underlying Connection, adding a given set of parameter tokens to the tokens
|
||||||
|
* already supplied.
|
||||||
|
*/
|
||||||
|
public class TokenInjectingConnection extends DelegatingConnection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The additional tokens to include with each call to connect().
|
||||||
|
*/
|
||||||
|
private final Map<String, String> tokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the given Connection, automatically adding the given tokens to
|
||||||
|
* each invocation of connect(). Any additional tokens which have the same
|
||||||
|
* name as existing tokens will override the existing values.
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* The Connection to wrap.
|
||||||
|
*
|
||||||
|
* @param tokens
|
||||||
|
* The additional tokens to include with each call to connect().
|
||||||
|
*/
|
||||||
|
public TokenInjectingConnection(Connection connection,
|
||||||
|
Map<String, String> tokens) {
|
||||||
|
super(connection);
|
||||||
|
this.tokens = tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Apply provided tokens over those given to connect()
|
||||||
|
tokens = new HashMap<>(tokens);
|
||||||
|
tokens.putAll(this.tokens);
|
||||||
|
|
||||||
|
return super.connect(info, tokens);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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.net.auth;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
import org.apache.guacamole.net.GuacamoleTunnel;
|
||||||
|
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConnectionGroup implementation which overrides the connect() function of an
|
||||||
|
* underlying ConnectionGroup, adding a given set of parameter tokens to the
|
||||||
|
* tokens already supplied.
|
||||||
|
*/
|
||||||
|
public class TokenInjectingConnectionGroup extends DelegatingConnectionGroup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The additional tokens to include with each call to connect().
|
||||||
|
*/
|
||||||
|
private final Map<String, String> tokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the given ConnectionGroup, automatically adding the given tokens
|
||||||
|
* to each invocation of connect(). Any additional tokens which have the
|
||||||
|
* same name as existing tokens will override the existing values.
|
||||||
|
*
|
||||||
|
* @param connectionGroup
|
||||||
|
* The ConnectionGroup to wrap.
|
||||||
|
*
|
||||||
|
* @param tokens
|
||||||
|
* The additional tokens to include with each call to connect().
|
||||||
|
*/
|
||||||
|
public TokenInjectingConnectionGroup(ConnectionGroup connectionGroup,
|
||||||
|
Map<String, String> tokens) {
|
||||||
|
super(connectionGroup);
|
||||||
|
this.tokens = tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Apply provided tokens over those given to connect()
|
||||||
|
tokens = new HashMap<>(tokens);
|
||||||
|
tokens.putAll(this.tokens);
|
||||||
|
|
||||||
|
return super.connect(info, tokens);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* 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.net.auth;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UserContext implementation which decorates a given UserContext,
|
||||||
|
* automatically applying additional parameter tokens during the connection
|
||||||
|
* process of any retrieved Connections and ConnectionGroups.
|
||||||
|
*/
|
||||||
|
public class TokenInjectingUserContext extends DelegatingUserContext {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The additional tokens to include with each call to connect() if
|
||||||
|
* getTokens() is not overridden.
|
||||||
|
*/
|
||||||
|
private final Map<String, String> tokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the given UserContext, overriding the connect() function of each
|
||||||
|
* retrieved Connection and ConnectionGroup such that the given additional
|
||||||
|
* parameter tokens are included. Any additional tokens which have the same
|
||||||
|
* name as existing tokens will override the existing values. If tokens
|
||||||
|
* specific to a particular connection or connection group need to be
|
||||||
|
* included, getTokens() may be overridden to provide a different set of
|
||||||
|
* tokens.
|
||||||
|
*
|
||||||
|
* @param userContext
|
||||||
|
* The UserContext to wrap.
|
||||||
|
*
|
||||||
|
* @param tokens
|
||||||
|
* The additional tokens to include with each call to connect().
|
||||||
|
*/
|
||||||
|
public TokenInjectingUserContext(UserContext userContext,
|
||||||
|
Map<String, String> tokens) {
|
||||||
|
super(userContext);
|
||||||
|
this.tokens = tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the given UserContext, overriding the connect() function of each
|
||||||
|
* retrieved Connection and ConnectionGroup such that the additional
|
||||||
|
* parameter tokens returned by getTokens() are included. Any additional
|
||||||
|
* tokens which have the same name as existing tokens will override the
|
||||||
|
* existing values.
|
||||||
|
*
|
||||||
|
* @param userContext
|
||||||
|
* The UserContext to wrap.
|
||||||
|
*/
|
||||||
|
public TokenInjectingUserContext(UserContext userContext) {
|
||||||
|
this(userContext, Collections.<String, String>emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tokens which should be added to an in-progress call to
|
||||||
|
* connect() for the given Connection. If not overridden, this function
|
||||||
|
* will return the tokens provided when this instance of
|
||||||
|
* TokenInjectingUserContext was created.
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* The Connection on which connect() has been called.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The tokens which should be added to the in-progress call to
|
||||||
|
* connect().
|
||||||
|
*/
|
||||||
|
protected Map<String, String> getTokens(Connection connection) {
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tokens which should be added to an in-progress call to
|
||||||
|
* connect() for the given ConnectionGroup. If not overridden, this
|
||||||
|
* function will return the tokens provided when this instance of
|
||||||
|
* TokenInjectingUserContext was created.
|
||||||
|
*
|
||||||
|
* @param connectionGroup
|
||||||
|
* The ConnectionGroup on which connect() has been called.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The tokens which should be added to the in-progress call to
|
||||||
|
* connect().
|
||||||
|
*/
|
||||||
|
protected Map<String, String> getTokens(ConnectionGroup connectionGroup) {
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Directory<ConnectionGroup> getConnectionGroupDirectory()
|
||||||
|
throws GuacamoleException {
|
||||||
|
return new DecoratingDirectory<ConnectionGroup>(super.getConnectionGroupDirectory()) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionGroup decorate(ConnectionGroup object) throws GuacamoleException {
|
||||||
|
return new TokenInjectingConnectionGroup(object, getTokens(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionGroup undecorate(ConnectionGroup object) throws GuacamoleException {
|
||||||
|
return ((TokenInjectingConnectionGroup) object).getDelegateConnectionGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Directory<Connection> getConnectionDirectory()
|
||||||
|
throws GuacamoleException {
|
||||||
|
return new DecoratingDirectory<Connection>(super.getConnectionDirectory()) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Connection decorate(Connection object) throws GuacamoleException {
|
||||||
|
return new TokenInjectingConnection(object, getTokens(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Connection undecorate(Connection object) throws GuacamoleException {
|
||||||
|
return ((TokenInjectingConnection) object).getDelegateConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -31,8 +31,6 @@ import org.apache.guacamole.net.auth.AuthenticatedUser;
|
|||||||
import org.apache.guacamole.net.auth.Credentials;
|
import org.apache.guacamole.net.auth.Credentials;
|
||||||
import org.apache.guacamole.net.auth.UserContext;
|
import org.apache.guacamole.net.auth.UserContext;
|
||||||
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
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
|
* 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
|
@Override
|
||||||
public AuthenticatedUser authenticateUser(final Credentials credentials)
|
public AuthenticatedUser authenticateUser(final Credentials credentials)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Get configurations
|
// Get configurations
|
||||||
Map<String, GuacamoleConfiguration> configs =
|
Map<String, GuacamoleConfiguration> configs =
|
||||||
getFilteredAuthorizedConfigurations(credentials);
|
getAuthorizedConfigurations(credentials);
|
||||||
|
|
||||||
// Return as unauthorized if not authorized to retrieve configs
|
// Return as unauthorized if not authorized to retrieve configs
|
||||||
if (configs == null)
|
if (configs == null)
|
||||||
@@ -233,7 +160,7 @@ public abstract class SimpleAuthenticationProvider
|
|||||||
|
|
||||||
// Get configurations
|
// Get configurations
|
||||||
Map<String, GuacamoleConfiguration> configs =
|
Map<String, GuacamoleConfiguration> configs =
|
||||||
getFilteredAuthorizedConfigurations(authenticatedUser);
|
getAuthorizedConfigurations(authenticatedUser.getCredentials());
|
||||||
|
|
||||||
// Return as unauthorized if not authorized to retrieve configs
|
// Return as unauthorized if not authorized to retrieve configs
|
||||||
if (configs == null)
|
if (configs == null)
|
||||||
|
@@ -38,9 +38,14 @@ import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration;
|
|||||||
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
|
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||||
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
import org.apache.guacamole.protocol.GuacamoleClientInformation;
|
||||||
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
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 {
|
public class SimpleConnection extends AbstractConnection {
|
||||||
|
|
||||||
@@ -95,8 +100,8 @@ public class SimpleConnection extends AbstractConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
|
|
||||||
// Retrieve proxy configuration from environment
|
// Retrieve proxy configuration from environment
|
||||||
Environment environment = new LocalEnvironment();
|
Environment environment = new LocalEnvironment();
|
||||||
@@ -106,6 +111,11 @@ public class SimpleConnection extends AbstractConnection {
|
|||||||
String hostname = proxyConfig.getHostname();
|
String hostname = proxyConfig.getHostname();
|
||||||
int port = proxyConfig.getPort();
|
int port = proxyConfig.getPort();
|
||||||
|
|
||||||
|
// Apply tokens to config parameters
|
||||||
|
GuacamoleConfiguration filteredConfig = new GuacamoleConfiguration(config);
|
||||||
|
TokenFilter tokenFilter = new TokenFilter();
|
||||||
|
tokenFilter.filterValues(config.getParameters());
|
||||||
|
|
||||||
GuacamoleSocket socket;
|
GuacamoleSocket socket;
|
||||||
|
|
||||||
// Determine socket type based on required encryption method
|
// Determine socket type based on required encryption method
|
||||||
@@ -115,7 +125,7 @@ public class SimpleConnection extends AbstractConnection {
|
|||||||
case SSL:
|
case SSL:
|
||||||
socket = new ConfiguredGuacamoleSocket(
|
socket = new ConfiguredGuacamoleSocket(
|
||||||
new SSLGuacamoleSocket(hostname, port),
|
new SSLGuacamoleSocket(hostname, port),
|
||||||
config, info
|
filteredConfig, info
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -123,7 +133,7 @@ public class SimpleConnection extends AbstractConnection {
|
|||||||
case NONE:
|
case NONE:
|
||||||
socket = new ConfiguredGuacamoleSocket(
|
socket = new ConfiguredGuacamoleSocket(
|
||||||
new InetGuacamoleSocket(hostname, port),
|
new InetGuacamoleSocket(hostname, port),
|
||||||
config, info
|
filteredConfig, info
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -109,8 +109,8 @@ public class SimpleConnectionGroup extends AbstractConnectionGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuacamoleTunnel connect(GuacamoleClientInformation info)
|
public GuacamoleTunnel connect(GuacamoleClientInformation info,
|
||||||
throws GuacamoleException {
|
Map<String, String> tokens) throws GuacamoleException {
|
||||||
throw new GuacamoleSecurityException("Permission denied.");
|
throw new GuacamoleSecurityException("Permission denied.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,15 +21,18 @@ package org.apache.guacamole.token;
|
|||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
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.AuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.Credentials;
|
import org.apache.guacamole.net.auth.Credentials;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class which provides access to standardized token names, as well as
|
* Utility class which provides access to standardized token names, as well as
|
||||||
* facilities for generating those tokens from common objects.
|
* 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 {
|
public class StandardTokens {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,11 +79,6 @@ public class StandardTokens {
|
|||||||
*/
|
*/
|
||||||
private static final String TIME_FORMAT = "HHmmss";
|
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.
|
* This utility class should not be instantiated.
|
||||||
*/
|
*/
|
||||||
@@ -150,11 +148,10 @@ public class StandardTokens {
|
|||||||
* Adds tokens which are standardized by guacamole-ext to the given
|
* Adds tokens which are standardized by guacamole-ext to the given
|
||||||
* TokenFilter using the values from the given AuthenticatedUser object,
|
* TokenFilter using the values from the given AuthenticatedUser object,
|
||||||
* including any associated credentials. These standardized tokens include
|
* including any associated credentials. These standardized tokens include
|
||||||
* the current username (GUAC_USERNAME), password (GUAC_PASSWORD), the
|
* the current username (GUAC_USERNAME), password (GUAC_PASSWORD), and the
|
||||||
* server date and time (GUAC_DATE and GUAC_TIME respectively), and custom
|
* server date and time (GUAC_DATE and GUAC_TIME respectively). If either
|
||||||
* user attributes. If either the username or password are not set within
|
* the username or password are not set within the given user or their
|
||||||
* the given user or their provided credentials, the corresponding token(s)
|
* provided credentials, the corresponding token(s) will remain unset.
|
||||||
* will remain unset.
|
|
||||||
*
|
*
|
||||||
* @param filter
|
* @param filter
|
||||||
* The TokenFilter to add standard tokens to.
|
* The TokenFilter to add standard tokens to.
|
||||||
@@ -172,33 +169,6 @@ public class StandardTokens {
|
|||||||
// Add tokens specific to credentials
|
// Add tokens specific to credentials
|
||||||
addStandardTokens(filter, user.getCredentials());
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -128,7 +128,8 @@ public class APIConnectionWrapper implements Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.");
|
throw new UnsupportedOperationException("Operation not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -112,7 +112,8 @@ public class APIConnectionGroupWrapper implements ConnectionGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.");
|
throw new UnsupportedOperationException("Operation not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* 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 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";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -22,6 +22,7 @@ package org.apache.guacamole.tunnel;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.GuacamoleSecurityException;
|
import org.apache.guacamole.GuacamoleSecurityException;
|
||||||
import org.apache.guacamole.GuacamoleSession;
|
import org.apache.guacamole.GuacamoleSession;
|
||||||
@@ -187,6 +188,10 @@ public class TunnelRequestService {
|
|||||||
* @param info
|
* @param info
|
||||||
* Information describing the connected Guacamole client.
|
* 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
|
* @return
|
||||||
* A new tunnel, connected as required by the request.
|
* A new tunnel, connected as required by the request.
|
||||||
*
|
*
|
||||||
@@ -195,7 +200,7 @@ public class TunnelRequestService {
|
|||||||
*/
|
*/
|
||||||
protected GuacamoleTunnel createConnectedTunnel(UserContext context,
|
protected GuacamoleTunnel createConnectedTunnel(UserContext context,
|
||||||
final TunnelRequest.Type type, String id,
|
final TunnelRequest.Type type, String id,
|
||||||
GuacamoleClientInformation info)
|
GuacamoleClientInformation info, Map<String, String> tokens)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Create connected tunnel from identifier
|
// Create connected tunnel from identifier
|
||||||
@@ -216,7 +221,7 @@ public class TunnelRequestService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect tunnel
|
// Connect tunnel
|
||||||
tunnel = connection.connect(info);
|
tunnel = connection.connect(info, tokens);
|
||||||
logger.info("User \"{}\" connected to connection \"{}\".", context.self().getIdentifier(), id);
|
logger.info("User \"{}\" connected to connection \"{}\".", context.self().getIdentifier(), id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -235,7 +240,7 @@ public class TunnelRequestService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect tunnel
|
// Connect tunnel
|
||||||
tunnel = group.connect(info);
|
tunnel = group.connect(info, tokens);
|
||||||
logger.info("User \"{}\" connected to group \"{}\".", context.self().getIdentifier(), id);
|
logger.info("User \"{}\" connected to group \"{}\".", context.self().getIdentifier(), id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -385,16 +390,17 @@ public class TunnelRequestService {
|
|||||||
GuacamoleClientInformation info = getClientInformation(request);
|
GuacamoleClientInformation info = getClientInformation(request);
|
||||||
|
|
||||||
GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
|
GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
|
||||||
|
AuthenticatedUser authenticatedUser = session.getAuthenticatedUser();
|
||||||
UserContext userContext = session.getUserContext(authProviderIdentifier);
|
UserContext userContext = session.getUserContext(authProviderIdentifier);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Create connected tunnel using provided connection ID and client information
|
// 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
|
// Notify listeners to allow connection to be vetoed
|
||||||
fireTunnelConnectEvent(session.getAuthenticatedUser(),
|
fireTunnelConnectEvent(authenticatedUser, authenticatedUser.getCredentials(), tunnel);
|
||||||
session.getAuthenticatedUser().getCredentials(), tunnel);
|
|
||||||
|
|
||||||
// Associate tunnel with session
|
// Associate tunnel with session
|
||||||
return createAssociatedTunnel(tunnel, authToken, session, userContext, type, id);
|
return createAssociatedTunnel(tunnel, authToken, session, userContext, type, id);
|
||||||
|
Reference in New Issue
Block a user