mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-587: Track and load authentication providers only within ExtensionModule. Default to basic auth. Explicitly deprecate.
This commit is contained in:
@@ -85,7 +85,7 @@ public class BasicServletContextListener extends GuiceServletContextListener {
|
||||
new EnvironmentModule(environment),
|
||||
new LogModule(environment),
|
||||
new ExtensionModule(environment),
|
||||
new RESTAuthModule(environment, sessionMap),
|
||||
new RESTAuthModule(sessionMap),
|
||||
new RESTServletModule(),
|
||||
new TunnelModule()
|
||||
);
|
||||
|
@@ -39,10 +39,13 @@ import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties;
|
||||
|
||||
/**
|
||||
* A ClassLoader implementation which finds classes within a configurable
|
||||
* directory. This directory is set within guacamole.properties.
|
||||
* directory. This directory is set within guacamole.properties. This class
|
||||
* is deprecated in favor of DirectoryClassLoader, which is automatically
|
||||
* configured based on the presence/absence of GUACAMOLE_HOME/lib.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
@Deprecated
|
||||
public class GuacamoleClassLoader extends ClassLoader {
|
||||
|
||||
/**
|
||||
|
@@ -28,9 +28,11 @@ import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import net.sourceforge.guacamole.net.basic.BasicFileAuthenticationProvider;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.environment.Environment;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties;
|
||||
import org.glyptodon.guacamole.net.basic.resource.Resource;
|
||||
import org.glyptodon.guacamole.net.basic.resource.ResourceServlet;
|
||||
import org.glyptodon.guacamole.net.basic.resource.SequenceResource;
|
||||
@@ -74,6 +76,12 @@ public class ExtensionModule extends ServletModule {
|
||||
*/
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
* The currently-bound authentication provider, if any. At the moment, we
|
||||
* only support one authentication provider loaded at any one time.
|
||||
*/
|
||||
private Class<? extends AuthenticationProvider> boundAuthenticationProvider = null;
|
||||
|
||||
/**
|
||||
* Returns the classloader that should be used as the parent classloader
|
||||
* for all extensions. If the GUACAMOLE_HOME/lib directory exists, this
|
||||
@@ -113,9 +121,81 @@ public class ExtensionModule extends ServletModule {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the value of the now-deprecated "auth-provider" property from
|
||||
* guacamole.properties, returning the corresponding AuthenticationProvider
|
||||
* class. If no authentication provider could be read, or the property is
|
||||
* not present, null is returned.
|
||||
*
|
||||
* As this property is deprecated, this function will also log warning
|
||||
* messages if the property is actually specified.
|
||||
*
|
||||
* @return
|
||||
* The value of the deprecated "auth-provider" property, or null if the
|
||||
* property is not present.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // We must continue to use this property until it is truly no longer supported
|
||||
private Class<AuthenticationProvider> getAuthProviderProperty() {
|
||||
|
||||
// Get and bind auth provider instance, if defined via property
|
||||
try {
|
||||
|
||||
// Use "auth-provider" property if present, but warn about deprecation
|
||||
Class<AuthenticationProvider> authenticationProvider = environment.getProperty(BasicGuacamoleProperties.AUTH_PROVIDER);
|
||||
if (authenticationProvider != null)
|
||||
logger.warn("The \"auth-provider\" and \"lib-directory\" properties are now deprecated. Please use the \"extensions\" and \"lib\" directories within GUACAMOLE_HOME instead.");
|
||||
|
||||
return authenticationProvider;
|
||||
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.warn("Value of deprecated \"auth-provider\" property within guacamole.properties is not valid: {}", e.getMessage());
|
||||
logger.debug("Error reading authentication provider from guacamole.properties.", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given AuthenticationProvider class such that any service
|
||||
* requiring access to the AuthenticationProvider can obtain it via
|
||||
* injection.
|
||||
*
|
||||
* @param authenticationProvider
|
||||
* The AuthenticationProvider class to bind.
|
||||
*/
|
||||
private void bindAuthenticationProvider(Class<? extends AuthenticationProvider> authenticationProvider) {
|
||||
|
||||
// Choose auth provider for binding if not already chosen
|
||||
if (boundAuthenticationProvider != null)
|
||||
boundAuthenticationProvider = authenticationProvider;
|
||||
|
||||
// If an auth provider is already chosen, skip and warn
|
||||
else {
|
||||
logger.debug("Ignoring AuthenticationProvider \"{}\".", authenticationProvider);
|
||||
logger.warn("Only one authentication extension may be used at a time. Please "
|
||||
+ "make sure that only one authentication extension is present "
|
||||
+ "within the GUACAMOLE_HOME/" + EXTENSIONS_DIRECTORY + " "
|
||||
+ "directory, and that you are not also specifying the deprecated "
|
||||
+ "\"auth-provider\" property within guacamole.properties.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind authentication provider
|
||||
logger.debug("Binding AuthenticationProvider \"{}\".", authenticationProvider);
|
||||
bind(AuthenticationProvider.class).to(authenticationProvider).in(Singleton.class);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
|
||||
// Load authentication provider from guacamole.properties for sake of backwards compatibility
|
||||
Class<AuthenticationProvider> authProviderProperty = getAuthProviderProperty();
|
||||
if (authProviderProperty != null)
|
||||
bindAuthenticationProvider(authProviderProperty);
|
||||
|
||||
// Retrieve and validate extensions directory
|
||||
File extensionsDir = new File(environment.getGuacamoleHome(), EXTENSIONS_DIRECTORY);
|
||||
if (!extensionsDir.isDirectory())
|
||||
@@ -153,12 +233,10 @@ public class ExtensionModule extends ServletModule {
|
||||
javaScriptResources.addAll(extension.getJavaScriptResources());
|
||||
cssResources.addAll(extension.getCSSResources());
|
||||
|
||||
// Load all authentication providers as singletons
|
||||
// Attempt to load all authentication providers
|
||||
Collection<Class<AuthenticationProvider>> authenticationProviders = extension.getAuthenticationProviderClasses();
|
||||
for (Class<AuthenticationProvider> authenticationProvider : authenticationProviders) {
|
||||
logger.debug("Binding AuthenticationProvider \"{}\".", authenticationProvider);
|
||||
bind(AuthenticationProvider.class).to(authenticationProvider).in(Singleton.class);
|
||||
}
|
||||
for (Class<AuthenticationProvider> authenticationProvider : authenticationProviders)
|
||||
bindAuthenticationProvider(authenticationProvider);
|
||||
|
||||
// Log successful loading of extension by name
|
||||
logger.info("Extension \"{}\" loaded.", extension.getName());
|
||||
@@ -171,6 +249,12 @@ public class ExtensionModule extends ServletModule {
|
||||
|
||||
}
|
||||
|
||||
// Default to basic auth if nothing else chosen/provided
|
||||
if (boundAuthenticationProvider == null) {
|
||||
logger.info("Using default, \"basic\", XML-driven authentication.");
|
||||
bindAuthenticationProvider(BasicFileAuthenticationProvider.class);
|
||||
}
|
||||
|
||||
// Dynamically generate app.js and app.css from extensions
|
||||
serve("/app.js").with(new ResourceServlet(new SequenceResource(javaScriptResources)));
|
||||
serve("/app.css").with(new ResourceServlet(new SequenceResource(cssResources)));
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.properties;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.basic.GuacamoleClassLoader;
|
||||
@@ -30,14 +29,18 @@ import org.glyptodon.guacamole.properties.GuacamoleProperty;
|
||||
|
||||
/**
|
||||
* A GuacamoleProperty whose value is the name of a class to use to
|
||||
* authenticate users. This class must implement AuthenticationProvider.
|
||||
* authenticate users. This class must implement AuthenticationProvider. Use
|
||||
* of this property type is deprecated in favor of the
|
||||
* GUACAMOLE_HOME/extensions directory.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public abstract class AuthenticationProviderProperty implements GuacamoleProperty<AuthenticationProvider> {
|
||||
@Deprecated
|
||||
public abstract class AuthenticationProviderProperty implements GuacamoleProperty<Class<AuthenticationProvider>> {
|
||||
|
||||
@Override
|
||||
public AuthenticationProvider parseValue(String authProviderClassName) throws GuacamoleException {
|
||||
@SuppressWarnings("unchecked") // Explicitly checked within by isAssignableFrom()
|
||||
public Class<AuthenticationProvider> parseValue(String authProviderClassName) throws GuacamoleException {
|
||||
|
||||
// If no property provided, return null.
|
||||
if (authProviderClassName == null)
|
||||
@@ -46,35 +49,21 @@ public abstract class AuthenticationProviderProperty implements GuacamolePropert
|
||||
// Get auth provider instance
|
||||
try {
|
||||
|
||||
Object obj = GuacamoleClassLoader.getInstance().loadClass(authProviderClassName)
|
||||
.getConstructor().newInstance();
|
||||
// Get authentication provider class
|
||||
Class<?> authProviderClass = GuacamoleClassLoader.getInstance().loadClass(authProviderClassName);
|
||||
|
||||
if (!(obj instanceof AuthenticationProvider))
|
||||
// Verify the located class is actually a subclass of AuthenticationProvider
|
||||
if (!AuthenticationProvider.class.isAssignableFrom(authProviderClass))
|
||||
throw new GuacamoleException("Specified authentication provider class is not a AuthenticationProvider.");
|
||||
|
||||
return (AuthenticationProvider) obj;
|
||||
// Return located class
|
||||
return (Class<AuthenticationProvider>) authProviderClass;
|
||||
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new GuacamoleException("Authentication provider class not found", e);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new GuacamoleException("Default constructor for authentication provider not present", e);
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
throw new GuacamoleException("Creation of authentication provider disallowed; check your security settings", e);
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw new GuacamoleException("Unable to instantiate authentication provider", e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new GuacamoleException("Unable to access default constructor of authentication provider", e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new GuacamoleException("Internal error in constructor of authentication provider", e.getTargetException());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,6 @@
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.properties;
|
||||
|
||||
import org.glyptodon.guacamole.properties.BooleanGuacamoleProperty;
|
||||
import org.glyptodon.guacamole.properties.FileGuacamoleProperty;
|
||||
import org.glyptodon.guacamole.properties.IntegerGuacamoleProperty;
|
||||
|
||||
@@ -40,8 +39,10 @@ public class BasicGuacamoleProperties {
|
||||
|
||||
/**
|
||||
* The authentication provider to user when retrieving the authorized
|
||||
* configurations of a user.
|
||||
* configurations of a user. This property is currently supported, but
|
||||
* deprecated in favor of the GUACAMOLE_HOME/extensions directory.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final AuthenticationProviderProperty AUTH_PROVIDER = new AuthenticationProviderProperty() {
|
||||
|
||||
@Override
|
||||
@@ -50,8 +51,11 @@ public class BasicGuacamoleProperties {
|
||||
};
|
||||
|
||||
/**
|
||||
* The directory to search for authentication provider classes.
|
||||
* The directory to search for authentication provider classes. This
|
||||
* property is currently supported, but deprecated in favor of the
|
||||
* GUACAMOLE_HOME/lib directory.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final FileGuacamoleProperty LIB_DIRECTORY = new FileGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
@@ -60,7 +64,9 @@ public class BasicGuacamoleProperties {
|
||||
};
|
||||
|
||||
/**
|
||||
* The comma-separated list of all classes to use as event listeners.
|
||||
* The comma-separated list of all classes to use as event listeners. This
|
||||
* property is currently supported, but deprecated in favor of declared
|
||||
* event listeners within extension manifests.
|
||||
*/
|
||||
public static final EventListenersProperty EVENT_LISTENERS = new EventListenersProperty() {
|
||||
|
||||
|
@@ -30,10 +30,13 @@ import org.glyptodon.guacamole.properties.GuacamoleProperty;
|
||||
|
||||
/**
|
||||
* A GuacamoleProperty whose value is a comma-separated list of class names,
|
||||
* where each class will be used as a listener for events.
|
||||
* where each class will be used as a listener for events. This type of
|
||||
* property is deprecated in favor of declaring event listeners within
|
||||
* extension manifests.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class EventListenersProperty implements GuacamoleProperty<Collection<Class>> {
|
||||
|
||||
@Override
|
||||
|
@@ -23,10 +23,6 @@
|
||||
package org.glyptodon.guacamole.net.basic.rest;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.environment.Environment;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties;
|
||||
import org.glyptodon.guacamole.net.basic.rest.auth.AuthTokenGenerator;
|
||||
import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService;
|
||||
import org.glyptodon.guacamole.net.basic.rest.auth.SecureRandomAuthTokenGenerator;
|
||||
@@ -47,11 +43,6 @@ public class RESTAuthModule extends AbstractModule {
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(RESTAuthModule.class);
|
||||
|
||||
/**
|
||||
* The Guacamole server environment.
|
||||
*/
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
* Singleton instance of TokenSessionMap.
|
||||
*/
|
||||
@@ -61,16 +52,11 @@ public class RESTAuthModule extends AbstractModule {
|
||||
* Creates a module which handles binding of authentication-related
|
||||
* objects, including the singleton TokenSessionMap.
|
||||
*
|
||||
* @param environment
|
||||
* The environment to use when configuring authentication.
|
||||
*
|
||||
* @param tokenSessionMap
|
||||
* An instance of TokenSessionMap to inject as a singleton wherever
|
||||
* needed.
|
||||
*/
|
||||
public RESTAuthModule(Environment environment,
|
||||
TokenSessionMap tokenSessionMap) {
|
||||
this.environment = environment;
|
||||
public RESTAuthModule(TokenSessionMap tokenSessionMap) {
|
||||
this.tokenSessionMap = tokenSessionMap;
|
||||
}
|
||||
|
||||
@@ -84,22 +70,6 @@ public class RESTAuthModule extends AbstractModule {
|
||||
bind(AuthenticationService.class);
|
||||
bind(AuthTokenGenerator.class).to(SecureRandomAuthTokenGenerator.class);
|
||||
|
||||
// Get and bind auth provider instance, if defined via property
|
||||
try {
|
||||
|
||||
// Use "auth-provider" property if present, but warn about deprecation
|
||||
AuthenticationProvider authProvider = environment.getProperty(BasicGuacamoleProperties.AUTH_PROVIDER);
|
||||
if (authProvider != null) {
|
||||
logger.warn("The \"auth-provider\" and \"lib-directory\" properties are now deprecated. Please use the \"extensions\" and \"lib\" directories within GUACAMOLE_HOME instead.");
|
||||
bind(AuthenticationProvider.class).toInstance(authProvider);
|
||||
}
|
||||
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.warn("Value of deprecated \"auth-provider\" property within guacamole.properties is not valid: {}", e.getMessage());
|
||||
logger.debug("Error reading authentication provider from guacamole.properties.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user