Migrate authentication to new API, bump version.

This commit is contained in:
Michael Jumper
2013-01-28 12:41:52 -08:00
committed by Michael Jumper
parent 3216895490
commit 958eedb76b
5 changed files with 84 additions and 40 deletions

View File

@@ -5,7 +5,7 @@
<groupId>net.sourceforge.guacamole</groupId> <groupId>net.sourceforge.guacamole</groupId>
<artifactId>guacamole</artifactId> <artifactId>guacamole</artifactId>
<packaging>war</packaging> <packaging>war</packaging>
<version>0.7.1</version> <version>0.8.0</version>
<name>guacamole</name> <name>guacamole</name>
<url>http://guac-dev.org/</url> <url>http://guac-dev.org/</url>
@@ -88,7 +88,7 @@
<dependency> <dependency>
<groupId>net.sourceforge.guacamole</groupId> <groupId>net.sourceforge.guacamole</groupId>
<artifactId>guacamole-ext</artifactId> <artifactId>guacamole-ext</artifactId>
<version>0.7.0</version> <version>0.8.0</version>
</dependency> </dependency>
<!-- Guacamole JavaScript API --> <!-- Guacamole JavaScript API -->

View File

@@ -21,7 +21,6 @@ package net.sourceforge.guacamole.net.basic;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Map;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -30,6 +29,7 @@ import javax.servlet.http.HttpSession;
import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.auth.AuthenticationProvider; import net.sourceforge.guacamole.net.auth.AuthenticationProvider;
import net.sourceforge.guacamole.net.auth.Credentials; import net.sourceforge.guacamole.net.auth.Credentials;
import net.sourceforge.guacamole.net.auth.UserContext;
import net.sourceforge.guacamole.net.basic.event.SessionListenerCollection; import net.sourceforge.guacamole.net.basic.event.SessionListenerCollection;
import net.sourceforge.guacamole.net.basic.properties.BasicGuacamoleProperties; import net.sourceforge.guacamole.net.basic.properties.BasicGuacamoleProperties;
import net.sourceforge.guacamole.net.event.AuthenticationFailureEvent; import net.sourceforge.guacamole.net.event.AuthenticationFailureEvent;
@@ -37,7 +37,6 @@ import net.sourceforge.guacamole.net.event.AuthenticationSuccessEvent;
import net.sourceforge.guacamole.net.event.listener.AuthenticationFailureListener; import net.sourceforge.guacamole.net.event.listener.AuthenticationFailureListener;
import net.sourceforge.guacamole.net.event.listener.AuthenticationSuccessListener; import net.sourceforge.guacamole.net.event.listener.AuthenticationSuccessListener;
import net.sourceforge.guacamole.properties.GuacamoleProperties; import net.sourceforge.guacamole.properties.GuacamoleProperties;
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -46,12 +45,12 @@ import org.slf4j.LoggerFactory;
* is only called if the HTTP request is authenticated, or the current * is only called if the HTTP request is authenticated, or the current
* HTTP session has already been authenticated. * HTTP session has already been authenticated.
* *
* Authorized configurations are retrieved using the authentication provider * The user context is retrieved using the authentication provider defined in
* defined in guacamole.properties. The authentication provider has access * guacamole.properties. The authentication provider has access to the request
* to the request and session, in addition to any submitted username and * and session, in addition to any submitted username and password, in order
* password, in order to authenticate the user. * to authenticate the user.
* *
* All authorized configurations will be stored in the current HttpSession. * The user context will be stored in the current HttpSession.
* *
* Success and failure are logged. * Success and failure are logged.
* *
@@ -62,9 +61,9 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
private Logger logger = LoggerFactory.getLogger(AuthenticatingHttpServlet.class); private Logger logger = LoggerFactory.getLogger(AuthenticatingHttpServlet.class);
/** /**
* The session attribute holding the map of configurations. * The session attribute holding the current UserContext.
*/ */
private static final String CONFIGURATIONS_ATTRIBUTE = "GUAC_CONFIGS"; private static final String CONTEXT_ATTRIBUTE = "GUAC_CONTEXT";
/** /**
* The session attribute holding the credentials authorizing this session. * The session attribute holding the credentials authorizing this session.
@@ -175,13 +174,13 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
} }
/** /**
* Returns the configurations associated with the given session. * Returns the UserContext associated with the given session.
* *
* @param session The session to retrieve configurations from. * @param session The session to retrieve UserContext from.
* @return The configurations associated with the given session. * @return The UserContext associated with the given session.
*/ */
protected Map<String, GuacamoleConfiguration> getConfigurations(HttpSession session) { protected UserContext getUserContext(HttpSession session) {
return (Map<String, GuacamoleConfiguration>) session.getAttribute(CONFIGURATIONS_ATTRIBUTE); return (UserContext) session.getAttribute(CONTEXT_ATTRIBUTE);
} }
@Override @Override
@@ -190,12 +189,12 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
HttpSession httpSession = request.getSession(true); HttpSession httpSession = request.getSession(true);
// Try to get configs from session // Try to get user context from session
Map<String, GuacamoleConfiguration> configs = getConfigurations(httpSession); UserContext context = getUserContext(httpSession);
// If no configs, try to authenticate the user to get the configs using // If no context, try to authenticate the user to get the context using
// this request. // this request.
if (configs == null) { if (context == null) {
SessionListenerCollection listeners; SessionListenerCollection listeners;
try { try {
@@ -218,17 +217,17 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
credentials.setUsername(username); credentials.setUsername(username);
credentials.setPassword(password); credentials.setPassword(password);
// Get authorized configs // Get authorized context
try { try {
configs = authProvider.getAuthorizedConfigurations(credentials); context = authProvider.getUserContext(credentials);
} }
/******** HANDLE FAILED AUTHENTICATION ********/ /******** HANDLE FAILED AUTHENTICATION ********/
// If error retrieving configs, fail authentication, notify listeners // If error retrieving context, fail authentication, notify listeners
catch (GuacamoleException e) { catch (GuacamoleException e) {
logger.error("Error retrieving configuration(s) for user \"{}\".", logger.error("Error retrieving context for user \"{}\".",
credentials.getUsername(), e); credentials.getUsername(), e);
notifyFailed(listeners, credentials); notifyFailed(listeners, credentials);
@@ -236,8 +235,8 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
return; return;
} }
// If no configs, fail authentication, notify listeners // If no context, fail authentication, notify listeners
if (configs == null) { if (context == null) {
logger.warn("Authentication attempt from {} for user \"{}\" failed.", logger.warn("Authentication attempt from {} for user \"{}\" failed.",
request.getRemoteAddr(), credentials.getUsername()); request.getRemoteAddr(), credentials.getUsername());
@@ -272,20 +271,35 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
} }
// Associate configs and credentials with session // Associate context and credentials with session
httpSession.setAttribute(CONFIGURATIONS_ATTRIBUTE, configs); httpSession.setAttribute(CONTEXT_ATTRIBUTE, context);
httpSession.setAttribute(CREDENTIALS_ATTRIBUTE, credentials); httpSession.setAttribute(CREDENTIALS_ATTRIBUTE, credentials);
} }
// Allow servlet to run now that authentication has been validated // Allow servlet to run now that authentication has been validated
authenticatedService(configs, request, response); authenticatedService(context, request, response);
} }
/**
* Function called after the credentials given in the request (if any)
* are authenticated. If the current session is not associated with
* valid credentials, this function will not be called.
*
* @param context The current UserContext.
* @param request The HttpServletRequest being serviced.
* @param response An HttpServletResponse which controls the HTTP response
* of this servlet.
*
* @throws ServletException If an error occurs that interferes with the
* normal operation of this servlet.
* @throws IOException If an error occurs that prevents this servlet from
* communicating.
*/
protected abstract void authenticatedService( protected abstract void authenticatedService(
Map<String, GuacamoleConfiguration> configs, UserContext context,
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException; throws ServletException, IOException;

View File

@@ -32,6 +32,8 @@ import net.sourceforge.guacamole.net.GuacamoleSocket;
import net.sourceforge.guacamole.net.GuacamoleTunnel; import net.sourceforge.guacamole.net.GuacamoleTunnel;
import net.sourceforge.guacamole.net.InetGuacamoleSocket; import net.sourceforge.guacamole.net.InetGuacamoleSocket;
import net.sourceforge.guacamole.net.auth.Credentials; import net.sourceforge.guacamole.net.auth.Credentials;
import net.sourceforge.guacamole.net.auth.GuacamoleConfigurationDirectory;
import net.sourceforge.guacamole.net.auth.UserContext;
import net.sourceforge.guacamole.net.basic.event.SessionListenerCollection; import net.sourceforge.guacamole.net.basic.event.SessionListenerCollection;
import net.sourceforge.guacamole.net.event.TunnelCloseEvent; import net.sourceforge.guacamole.net.event.TunnelCloseEvent;
import net.sourceforge.guacamole.net.event.TunnelConnectEvent; import net.sourceforge.guacamole.net.event.TunnelConnectEvent;
@@ -57,7 +59,7 @@ public class BasicGuacamoleTunnelServlet extends AuthenticatingHttpServlet {
@Override @Override
protected void authenticatedService( protected void authenticatedService(
Map<String, GuacamoleConfiguration> configs, UserContext context,
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException { throws IOException, ServletException {
@@ -169,8 +171,16 @@ public class BasicGuacamoleTunnelServlet extends AuthenticatingHttpServlet {
// Get credentials // Get credentials
final Credentials credentials = getCredentials(httpSession); final Credentials credentials = getCredentials(httpSession);
// Get authorized configs // Get context
Map<String, GuacamoleConfiguration> configs = getConfigurations(httpSession); UserContext context = getUserContext(httpSession);
// Get configuration directory
GuacamoleConfigurationDirectory directory =
context.getGuacamoleConfigurationDirectory();
// Attempt to get configurations from directory
Map<String, GuacamoleConfiguration> configs =
directory.getConfigurations();
// If no configs/credentials in session, not authorized // If no configs/credentials in session, not authorized
if (credentials == null || configs == null) if (credentials == null || configs == null)

View File

@@ -19,10 +19,9 @@ package net.sourceforge.guacamole.net.basic;
*/ */
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; import net.sourceforge.guacamole.net.auth.UserContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -38,7 +37,7 @@ public class BasicLogin extends AuthenticatingHttpServlet {
@Override @Override
protected void authenticatedService( protected void authenticatedService(
Map<String, GuacamoleConfiguration> configs, UserContext context,
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws IOException { throws IOException {
logger.info("Login was successful."); logger.info("Login was successful.");

View File

@@ -21,11 +21,15 @@ package net.sourceforge.guacamole.net.basic;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.XMLStreamWriter;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.auth.GuacamoleConfigurationDirectory;
import net.sourceforge.guacamole.net.auth.UserContext;
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
/** /**
@@ -38,16 +42,33 @@ public class ConfigurationList extends AuthenticatingHttpServlet {
@Override @Override
protected void authenticatedService( protected void authenticatedService(
Map<String, GuacamoleConfiguration> configs, UserContext context,
HttpServletRequest request, HttpServletResponse response) HttpServletRequest request, HttpServletResponse response)
throws IOException { throws IOException, ServletException {
// Do not cache // Do not cache
response.setHeader("Cache-Control", "no-cache"); response.setHeader("Cache-Control", "no-cache");
// Write XML // Write XML content type
response.setHeader("Content-Type", "text/xml"); response.setHeader("Content-Type", "text/xml");
// Attempt to get configurations
Map<String, GuacamoleConfiguration> configs;
try {
// Get configuration directory
GuacamoleConfigurationDirectory directory =
context.getGuacamoleConfigurationDirectory();
// Get configurations
configs = directory.getConfigurations();
}
catch (GuacamoleException e) {
throw new ServletException("Unable to retrieve configurations.", e);
}
// Write actual XML
try { try {
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();