mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-1152: Correctly differentiate between client errors and server errors.
By definition, a client error is not an internal error, but an intentional refusal of the server to handle a malformed or otherwise invalid request. These should not be handled in the same way as server errors which unexpectedly block processing of a request and should be corrected by an administrator. In the case of GUACAMOLE-1152, client errors should not be ignored even if failures are explicitly configured as tolerated for the associated authentication provider.
This commit is contained in:
@@ -21,12 +21,12 @@ package org.apache.guacamole.extension;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import org.apache.guacamole.GuacamoleClientException;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||||
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.net.auth.credentials.GuacamoleCredentialsException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -190,41 +190,15 @@ public class AuthenticationProviderFacade implements AuthenticationProvider {
|
|||||||
return authProvider.authenticateUser(credentials);
|
return authProvider.authenticateUser(credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass through credential exceptions untouched, as these are not
|
// Pass through client exceptions untouched, including credential
|
||||||
// internal failures
|
// exceptions, as these are not internal failures
|
||||||
catch (GuacamoleCredentialsException e) {
|
catch (GuacamoleClientException e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass through all other exceptions (aborting authentication entirely)
|
// Pass through all other exceptions (aborting authentication entirely)
|
||||||
// only if not configured to ignore such failures
|
// only if not configured to ignore such failures
|
||||||
catch (GuacamoleException e) {
|
catch (GuacamoleException | RuntimeException | Error e) {
|
||||||
|
|
||||||
// Skip using this authentication provider if configured to ignore
|
|
||||||
// internal failures during auth
|
|
||||||
if (isFailureTolerated()) {
|
|
||||||
warnAuthProviderSkipped(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
warnAuthAborted();
|
|
||||||
throw e;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (RuntimeException e) {
|
|
||||||
|
|
||||||
// Skip using this authentication provider if configured to ignore
|
|
||||||
// internal failures during auth
|
|
||||||
if (isFailureTolerated()) {
|
|
||||||
warnAuthProviderSkipped(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
warnAuthAborted();
|
|
||||||
throw e;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Error e) {
|
|
||||||
|
|
||||||
// Skip using this authentication provider if configured to ignore
|
// Skip using this authentication provider if configured to ignore
|
||||||
// internal failures during auth
|
// internal failures during auth
|
||||||
@@ -274,41 +248,15 @@ public class AuthenticationProviderFacade implements AuthenticationProvider {
|
|||||||
return authProvider.getUserContext(authenticatedUser);
|
return authProvider.getUserContext(authenticatedUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass through credential exceptions untouched, as these are not
|
// Pass through client exceptions untouched, including credential
|
||||||
// internal failures
|
// exceptions, as these are not internal failures
|
||||||
catch (GuacamoleCredentialsException e) {
|
catch (GuacamoleClientException e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass through all other exceptions (aborting authentication entirely)
|
// Pass through all other exceptions (aborting authentication entirely)
|
||||||
// only if not configured to ignore such failures
|
// only if not configured to ignore such failures
|
||||||
catch (GuacamoleException e) {
|
catch (GuacamoleException | RuntimeException | Error e) {
|
||||||
|
|
||||||
// Skip using this authentication provider if configured to ignore
|
|
||||||
// internal failures during auth
|
|
||||||
if (isFailureTolerated()) {
|
|
||||||
warnAuthProviderSkipped(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
warnAuthAborted();
|
|
||||||
throw e;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (RuntimeException e) {
|
|
||||||
|
|
||||||
// Skip using this authentication provider if configured to ignore
|
|
||||||
// internal failures during auth
|
|
||||||
if (isFailureTolerated()) {
|
|
||||||
warnAuthProviderSkipped(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
warnAuthAborted();
|
|
||||||
throw e;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Error e) {
|
|
||||||
|
|
||||||
// Skip using this authentication provider if configured to ignore
|
// Skip using this authentication provider if configured to ignore
|
||||||
// internal failures during auth
|
// internal failures during auth
|
||||||
|
@@ -27,6 +27,7 @@ import javax.ws.rs.core.MediaType;
|
|||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.ext.ExceptionMapper;
|
import javax.ws.rs.ext.ExceptionMapper;
|
||||||
import javax.ws.rs.ext.Provider;
|
import javax.ws.rs.ext.Provider;
|
||||||
|
import org.apache.guacamole.GuacamoleClientException;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.GuacamoleUnauthorizedException;
|
import org.apache.guacamole.GuacamoleUnauthorizedException;
|
||||||
import org.apache.guacamole.rest.auth.AuthenticationService;
|
import org.apache.guacamole.rest.auth.AuthenticationService;
|
||||||
@@ -91,14 +92,25 @@ public class RESTExceptionMapper implements ExceptionMapper<Throwable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate GuacamoleException subclasses to HTTP error codes
|
// Translate GuacamoleException subclasses to HTTP error codes
|
||||||
if (t instanceof GuacamoleException)
|
if (t instanceof GuacamoleException) {
|
||||||
|
|
||||||
|
// Always log the human-readable details of GuacacamoleExceptions
|
||||||
|
// for the benefit of the administrator
|
||||||
|
if (t instanceof GuacamoleClientException)
|
||||||
|
logger.debug("Client request rejected: {}", t.getMessage());
|
||||||
|
else {
|
||||||
|
logger.error("Request could not be processed: {}", t.getMessage());
|
||||||
|
logger.debug("Processing of request aborted by extension.", t);
|
||||||
|
}
|
||||||
|
|
||||||
return Response
|
return Response
|
||||||
.status(((GuacamoleException) t).getHttpStatusCode())
|
.status(((GuacamoleException) t).getHttpStatusCode())
|
||||||
.entity(new APIError((GuacamoleException) t))
|
.entity(new APIError((GuacamoleException) t))
|
||||||
.type(MediaType.APPLICATION_JSON)
|
.type(MediaType.APPLICATION_JSON)
|
||||||
.build();
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
// Rethrow unchecked exceptions such that they are properly wrapped
|
// Wrap unchecked exceptions
|
||||||
String message = t.getMessage();
|
String message = t.getMessage();
|
||||||
if (message != null)
|
if (message != null)
|
||||||
logger.error("Unexpected internal error: {}", message);
|
logger.error("Unexpected internal error: {}", message);
|
||||||
|
Reference in New Issue
Block a user