mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Added calls to any authentication success/fail hooks.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
package net.sourceforge.guacamole.net.basic;
|
package net.sourceforge.guacamole.net.basic;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
@@ -11,7 +12,12 @@ 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.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.AuthenticationSuccessEvent;
|
||||||
|
import net.sourceforge.guacamole.net.event.listener.AuthenticationFailureListener;
|
||||||
|
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 net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -37,9 +43,16 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
|
|||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(AuthenticatingHttpServlet.class);
|
private Logger logger = LoggerFactory.getLogger(AuthenticatingHttpServlet.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error message to be provided to the client user if authentication
|
||||||
|
* fails for ANY REASON.
|
||||||
|
*/
|
||||||
private static final String AUTH_ERROR_MESSAGE =
|
private static final String AUTH_ERROR_MESSAGE =
|
||||||
"User not logged in or authentication failed.";
|
"User not logged in or authentication failed.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The AuthenticationProvider to use to authenticate all requests.
|
||||||
|
*/
|
||||||
private AuthenticationProvider authProvider;
|
private AuthenticationProvider authProvider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -56,6 +69,81 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies all listeners in the given collection that authentication has
|
||||||
|
* failed.
|
||||||
|
*
|
||||||
|
* @param listeners A collection of all listeners that should be notified.
|
||||||
|
* @param credentials The credentials associated with the authentication
|
||||||
|
* request that failed.
|
||||||
|
*/
|
||||||
|
private void notifyFailed(Collection listeners, Credentials credentials) {
|
||||||
|
|
||||||
|
// Build event for auth failure
|
||||||
|
AuthenticationFailureEvent event = new AuthenticationFailureEvent(credentials);
|
||||||
|
|
||||||
|
// Notify all listeners
|
||||||
|
for (Object listener : listeners) {
|
||||||
|
try {
|
||||||
|
if (listener instanceof AuthenticationFailureListener)
|
||||||
|
((AuthenticationFailureListener) listener).authenticationFailed(event);
|
||||||
|
}
|
||||||
|
catch (GuacamoleException e) {
|
||||||
|
logger.error("Error notifying AuthenticationFailureListener.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies all listeners in the given collection that authentication was
|
||||||
|
* successful.
|
||||||
|
*
|
||||||
|
* @param listeners A collection of all listeners that should be notified.
|
||||||
|
* @param credentials The credentials associated with the authentication
|
||||||
|
* request that succeeded.
|
||||||
|
* @return true if all listeners are allowing the authentication success,
|
||||||
|
* or if there are no listeners, and false if any listener is
|
||||||
|
* canceling the authentication success. Note that once one
|
||||||
|
* listener cancels, no other listeners will run.
|
||||||
|
* @throws GuacamoleException If any listener throws an error while being
|
||||||
|
* notified. Note that if any listener throws an
|
||||||
|
* error, the success is canceled, and no other
|
||||||
|
* listeners will run.
|
||||||
|
*/
|
||||||
|
private boolean notifySuccess(Collection listeners, Credentials credentials)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Build event for auth success
|
||||||
|
AuthenticationSuccessEvent event = new AuthenticationSuccessEvent(credentials);
|
||||||
|
|
||||||
|
// Notify all listeners
|
||||||
|
for (Object listener : listeners) {
|
||||||
|
if (listener instanceof AuthenticationSuccessListener) {
|
||||||
|
|
||||||
|
// Cancel immediately if hook returns false
|
||||||
|
if (!((AuthenticationSuccessListener) listener).authenticationSucceeded(event))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a predefined, generic error message to the user, along with a
|
||||||
|
* "403 - Forbidden" HTTP status code in the response.
|
||||||
|
*
|
||||||
|
* @param response The response to send the error within.
|
||||||
|
* @throws IOException If an error occurs while sending the error.
|
||||||
|
*/
|
||||||
|
private void failAuthentication(HttpServletResponse response) throws IOException {
|
||||||
|
response.setHeader("X-Guacamole-Error-Message", AUTH_ERROR_MESSAGE);
|
||||||
|
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void service(HttpServletRequest request, HttpServletResponse response)
|
protected void service(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
@@ -70,6 +158,16 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
|
|||||||
// this request.
|
// this request.
|
||||||
if (configs == null) {
|
if (configs == null) {
|
||||||
|
|
||||||
|
SessionListenerCollection listeners;
|
||||||
|
try {
|
||||||
|
listeners = new SessionListenerCollection(httpSession);
|
||||||
|
}
|
||||||
|
catch (GuacamoleException e) {
|
||||||
|
logger.error("Failed to retrieve listeners. Authentication canceled.", e);
|
||||||
|
failAuthentication(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve username and password from parms
|
// Retrieve username and password from parms
|
||||||
String username = request.getParameter("username");
|
String username = request.getParameter("username");
|
||||||
String password = request.getParameter("password");
|
String password = request.getParameter("password");
|
||||||
@@ -85,29 +183,59 @@ public abstract class AuthenticatingHttpServlet extends HttpServlet {
|
|||||||
try {
|
try {
|
||||||
configs = authProvider.getAuthorizedConfigurations(credentials);
|
configs = authProvider.getAuthorizedConfigurations(credentials);
|
||||||
}
|
}
|
||||||
catch (GuacamoleException e) {
|
|
||||||
logger.error("Error retrieving configuration(s) for user {}.", username);
|
|
||||||
|
|
||||||
response.setHeader("X-Guacamole-Error-Message", AUTH_ERROR_MESSAGE);
|
|
||||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
/******** HANDLE FAILED AUTHENTICATION ********/
|
||||||
|
|
||||||
|
// If error retrieving configs, fail authentication, notify listeners
|
||||||
|
catch (GuacamoleException e) {
|
||||||
|
logger.error("Error retrieving configuration(s) for user \"{}\".", username);
|
||||||
|
|
||||||
|
notifyFailed(listeners, credentials);
|
||||||
|
failAuthentication(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no configs, fail authentication, notify listeners
|
||||||
if (configs == null) {
|
if (configs == null) {
|
||||||
logger.warn("Authentication attempt from {} for user \"{}\" failed.",
|
logger.warn("Authentication attempt from {} for user \"{}\" failed.",
|
||||||
request.getRemoteAddr(), username);
|
request.getRemoteAddr(), username);
|
||||||
|
|
||||||
response.setHeader("X-Guacamole-Error-Message", AUTH_ERROR_MESSAGE);
|
notifyFailed(listeners, credentials);
|
||||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
failAuthentication(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("User \"{}\" successfully authenticated from {}.",
|
|
||||||
username, request.getRemoteAddr());
|
/******** HANDLE SUCCESSFUL AUTHENTICATION ********/
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Otherwise, authentication has been succesful
|
||||||
|
logger.info("User \"{}\" successfully authenticated from {}.",
|
||||||
|
username, request.getRemoteAddr());
|
||||||
|
|
||||||
|
// Notify of success, cancel if requested
|
||||||
|
if (!notifySuccess(listeners, credentials)) {
|
||||||
|
logger.info("Successful authentication canceled by hook.");
|
||||||
|
failAuthentication(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (GuacamoleException e) {
|
||||||
|
|
||||||
|
// Cancel authentication success if hook throws exception
|
||||||
|
logger.error("Successful authentication canceled by error in hook.");
|
||||||
|
failAuthentication(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Associate configs with session
|
// Associate configs with session
|
||||||
httpSession.setAttribute("GUAC_CONFIGS", configs);
|
httpSession.setAttribute("GUAC_CONFIGS", configs);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow servlet to run now that authentication has been validated
|
// Allow servlet to run now that authentication has been validated
|
||||||
|
Reference in New Issue
Block a user