mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUAC-586: Separate authentication from authorization.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.auth;
|
||||
|
||||
|
||||
/**
|
||||
* Basic implementation of an AuthenticatedUser which uses the username to
|
||||
* determine equality. Username comparison is case-sensitive.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public abstract class AbstractAuthenticatedUser implements AuthenticatedUser {
|
||||
|
||||
/**
|
||||
* The name of this user.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (username == null) return 0;
|
||||
return username.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
// Not equal if null or not a User
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof AbstractAuthenticatedUser)) return false;
|
||||
|
||||
// Get username
|
||||
String objUsername = ((AbstractAuthenticatedUser) obj).username;
|
||||
|
||||
// If null, equal only if this username is null
|
||||
if (objUsername == null) return username == null;
|
||||
|
||||
// Otherwise, equal only if strings are identical
|
||||
return objUsername.equals(username);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.auth;
|
||||
|
||||
|
||||
/**
|
||||
* A user of the Guacamole web application who has been authenticated by an
|
||||
* AuthenticationProvider.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface AuthenticatedUser extends Identifiable {
|
||||
|
||||
/**
|
||||
* Returns the AuthenticationProvider that authenticated this user.
|
||||
*
|
||||
* @return
|
||||
* The AuthenticationProvider that authenticated this user.
|
||||
*/
|
||||
AuthenticationProvider getAuthenticationProvider();
|
||||
|
||||
/**
|
||||
* Returns the credentials that the user provided when they successfully
|
||||
* authenticated.
|
||||
*
|
||||
* @return
|
||||
* The credentials provided by the user when they authenticated.
|
||||
*/
|
||||
Credentials getCredentials();
|
||||
|
||||
}
|
@@ -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
|
||||
@@ -25,46 +25,112 @@ package org.glyptodon.guacamole.net.auth;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
|
||||
/**
|
||||
* Provides means of accessing and managing the available
|
||||
* GuacamoleConfiguration objects and User objects. Access to each configuration
|
||||
* and each user is limited by a given Credentials object.
|
||||
* Provides means of authorizing users and for accessing and managing data
|
||||
* associated with those users. Access to such data is limited according to the
|
||||
* AuthenticationProvider implementation.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface AuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Returns the UserContext of the user authorized by the given credentials.
|
||||
* Returns an AuthenticatedUser representing the user authenticated by the
|
||||
* given credentials, if any.
|
||||
*
|
||||
* @param credentials The credentials to use to retrieve the environment.
|
||||
* @return The UserContext of the user authorized by the given credentials,
|
||||
* or null if the credentials are not authorized.
|
||||
* @param credentials
|
||||
* The credentials to use for authentication.
|
||||
*
|
||||
* @throws GuacamoleException If an error occurs while creating the
|
||||
* UserContext.
|
||||
* @return
|
||||
* An AuthenticatedUser representing the user authenticated by the
|
||||
* given credentials, if any, or null if the credentials are invalid.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while authenticating the user, or if access is
|
||||
* temporarily, permanently, or conditionally denied, such as if the
|
||||
* supplied credentials are insufficient or invalid.
|
||||
*/
|
||||
UserContext getUserContext(Credentials credentials)
|
||||
AuthenticatedUser authenticateUser(Credentials credentials)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns a new or updated UserContext for the user authorized by the
|
||||
* give credentials and having the given existing UserContext. Note that
|
||||
* because this function will be called for all future requests after
|
||||
* initial authentication, including tunnel requests, care must be taken
|
||||
* to avoid using functions of HttpServletRequest which invalidate the
|
||||
* entire request body, such as getParameter().
|
||||
* Returns a new or updated AuthenticatedUser for the given credentials
|
||||
* already having produced the given AuthenticatedUser. Note that because
|
||||
* this function will be called for all future requests after initial
|
||||
* authentication, including tunnel requests, care must be taken to avoid
|
||||
* using functions of HttpServletRequest which invalidate the entire request
|
||||
* body, such as getParameter(). Doing otherwise may cause the
|
||||
* GuacamoleHTTPTunnelServlet to fail.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials to use for authentication.
|
||||
*
|
||||
* @param context The existing UserContext belonging to the user in
|
||||
* question.
|
||||
* @param credentials The credentials to use to retrieve or update the
|
||||
* environment.
|
||||
* @return The updated UserContext, which need not be the same as the
|
||||
* UserContext given, or null if the user is no longer authorized.
|
||||
* @param authenticatedUser
|
||||
* An AuthenticatedUser object representing the user authenticated by
|
||||
* an arbitrary set of credentials. The AuthenticatedUser may come from
|
||||
* this AuthenticationProvider or any other installed
|
||||
* AuthenticationProvider.
|
||||
*
|
||||
* @throws GuacamoleException If an error occurs while updating the
|
||||
* UserContext.
|
||||
* @return
|
||||
* An updated AuthenticatedUser representing the user authenticated by
|
||||
* the given credentials, if any, or null if the credentials are
|
||||
* invalid.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while updating the AuthenticatedUser.
|
||||
*/
|
||||
UserContext updateUserContext(UserContext context, Credentials credentials)
|
||||
AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser,
|
||||
Credentials credentials) throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns the UserContext of the user authenticated by the given
|
||||
* credentials.
|
||||
*
|
||||
* @param authenticatedUser
|
||||
* An AuthenticatedUser object representing the user authenticated by
|
||||
* an arbitrary set of credentials. The AuthenticatedUser may come from
|
||||
* this AuthenticationProvider or any other installed
|
||||
* AuthenticationProvider.
|
||||
*
|
||||
* @return
|
||||
* A UserContext describing the permissions, connection, connection
|
||||
* groups, etc. accessible or associated with the given authenticated
|
||||
* user, or null if this AuthenticationProvider refuses to provide any
|
||||
* such data.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while creating the UserContext.
|
||||
*/
|
||||
UserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns a new or updated UserContext for the given AuthenticatedUser
|
||||
* already having the given UserContext. Note that because this function
|
||||
* will be called for all future requests after initial authentication,
|
||||
* including tunnel requests, care must be taken to avoid using functions
|
||||
* of HttpServletRequest which invalidate the entire request body, such as
|
||||
* getParameter(). Doing otherwise may cause the GuacamoleHTTPTunnelServlet
|
||||
* to fail.
|
||||
*
|
||||
* @param context
|
||||
* The existing UserContext belonging to the user in question.
|
||||
*
|
||||
* @param authenticatedUser
|
||||
* An AuthenticatedUser object representing the user authenticated by
|
||||
* an arbitrary set of credentials. The AuthenticatedUser may come from
|
||||
* this AuthenticationProvider or any other installed
|
||||
* AuthenticationProvider.
|
||||
*
|
||||
* @return
|
||||
* An updated UserContext describing the permissions, connection,
|
||||
* connection groups, etc. accessible or associated with the given
|
||||
* authenticated user, or null if this AuthenticationProvider refuses
|
||||
* to provide any such data.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while updating the UserContext.
|
||||
*/
|
||||
UserContext updateUserContext(UserContext context,
|
||||
AuthenticatedUser authenticatedUser) throws GuacamoleException;
|
||||
|
||||
}
|
||||
|
@@ -23,8 +23,11 @@
|
||||
package org.glyptodon.guacamole.net.auth.simple;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.AbstractAuthenticatedUser;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
@@ -62,12 +65,100 @@ public abstract class SimpleAuthenticationProvider
|
||||
getAuthorizedConfigurations(Credentials credentials)
|
||||
throws GuacamoleException;
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
/**
|
||||
* AuthenticatedUser which contains its own predefined set of authorized
|
||||
* configurations.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
private class SimpleAuthenticatedUser extends AbstractAuthenticatedUser {
|
||||
|
||||
// Get username, if any
|
||||
String username = credentials.getUsername();
|
||||
/**
|
||||
* The credentials provided when this AuthenticatedUser was
|
||||
* authenticated.
|
||||
*/
|
||||
private final Credentials credentials;
|
||||
|
||||
/**
|
||||
* The GuacamoleConfigurations that this AuthenticatedUser is
|
||||
* authorized to use.
|
||||
*/
|
||||
private final Map<String, GuacamoleConfiguration> configs;
|
||||
|
||||
/**
|
||||
* Creates a new SimpleAuthenticatedUser associated with the given
|
||||
* credentials and having access to the given Map of
|
||||
* GuacamoleConfigurations.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials provided by the user when they authenticated.
|
||||
*
|
||||
* @param configs
|
||||
* A Map of all GuacamoleConfigurations for which this user has
|
||||
* access. The keys of this Map are Strings which uniquely identify
|
||||
* each configuration.
|
||||
*/
|
||||
public SimpleAuthenticatedUser(Credentials credentials, Map<String, GuacamoleConfiguration> configs) {
|
||||
|
||||
// Store credentials and configurations
|
||||
this.credentials = credentials;
|
||||
this.configs = configs;
|
||||
|
||||
// Pull username from credentials if it exists
|
||||
String username = credentials.getUsername();
|
||||
if (username != null && !username.isEmpty())
|
||||
setIdentifier(username);
|
||||
|
||||
// Otherwise generate a random username
|
||||
else
|
||||
setIdentifier(UUID.randomUUID().toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map containing all GuacamoleConfigurations that this user
|
||||
* is authorized to use. The keys of this Map are Strings which
|
||||
* uniquely identify each configuration.
|
||||
*
|
||||
* @return
|
||||
* A Map of all configurations for which this user is authorized.
|
||||
*/
|
||||
public Map<String, GuacamoleConfiguration> getAuthorizedConfigurations() {
|
||||
return configs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationProvider getAuthenticationProvider() {
|
||||
return SimpleAuthenticationProvider.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credentials getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 =
|
||||
@@ -85,19 +176,85 @@ public abstract class SimpleAuthenticationProvider
|
||||
for (GuacamoleConfiguration config : configs.values())
|
||||
tokenFilter.filterValues(config.getParameters());
|
||||
|
||||
// Return user context restricted to authorized configs
|
||||
if (username != null && !username.isEmpty())
|
||||
return new SimpleUserContext(username, configs);
|
||||
return configs;
|
||||
|
||||
// If there is no associated username, let SimpleUserContext generate one
|
||||
else
|
||||
return new SimpleUserContext(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)
|
||||
return ((SimpleAuthenticatedUser) authenticatedUser).getAuthorizedConfigurations();
|
||||
|
||||
// Otherwise, pull using credentials
|
||||
return getFilteredAuthorizedConfigurations(authenticatedUser.getCredentials());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticatedUser authenticateUser(final Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get configurations
|
||||
Map<String, GuacamoleConfiguration> configs =
|
||||
getFilteredAuthorizedConfigurations(credentials);
|
||||
|
||||
// Return as unauthorized if not authorized to retrieve configs
|
||||
if (configs == null)
|
||||
return null;
|
||||
|
||||
return new SimpleAuthenticatedUser(credentials, configs);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get configurations
|
||||
Map<String, GuacamoleConfiguration> configs =
|
||||
getFilteredAuthorizedConfigurations(authenticatedUser);
|
||||
|
||||
// Return as unauthorized if not authorized to retrieve configs
|
||||
if (configs == null)
|
||||
return null;
|
||||
|
||||
// Return user context restricted to authorized configs
|
||||
return new SimpleUserContext(authenticatedUser.getIdentifier(), configs);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser,
|
||||
Credentials credentials) throws GuacamoleException {
|
||||
|
||||
// Simply return the given user, updating nothing
|
||||
return authenticatedUser;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext updateUserContext(UserContext context,
|
||||
Credentials credentials) throws GuacamoleException {
|
||||
AuthenticatedUser authorizedUser) throws GuacamoleException {
|
||||
|
||||
// Simply return the given context, updating nothing
|
||||
return context;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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
|
||||
@@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.environment.Environment;
|
||||
import org.glyptodon.guacamole.net.GuacamoleTunnel;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -46,9 +46,9 @@ public class GuacamoleSession {
|
||||
private static final Logger logger = LoggerFactory.getLogger(GuacamoleSession.class);
|
||||
|
||||
/**
|
||||
* The credentials provided when the user authenticated.
|
||||
* The user associated with this session.
|
||||
*/
|
||||
private Credentials credentials;
|
||||
private AuthenticatedUser authenticatedUser;
|
||||
|
||||
/**
|
||||
* The user context associated with this session.
|
||||
@@ -72,8 +72,8 @@ public class GuacamoleSession {
|
||||
* The environment of the Guacamole server associated with this new
|
||||
* session.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials provided by the user during login.
|
||||
* @param authenticatedUser
|
||||
* The authenticated user to associate this session with.
|
||||
*
|
||||
* @param userContext
|
||||
* The user context to associate this session with.
|
||||
@@ -81,34 +81,33 @@ public class GuacamoleSession {
|
||||
* @throws GuacamoleException
|
||||
* If an error prevents the session from being created.
|
||||
*/
|
||||
public GuacamoleSession(Environment environment, Credentials credentials,
|
||||
UserContext userContext) throws GuacamoleException {
|
||||
public GuacamoleSession(Environment environment,
|
||||
AuthenticatedUser authenticatedUser, UserContext userContext)
|
||||
throws GuacamoleException {
|
||||
this.lastAccessedTime = System.currentTimeMillis();
|
||||
this.credentials = credentials;
|
||||
this.authenticatedUser = authenticatedUser;
|
||||
this.userContext = userContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credentials used when the user associated with this session
|
||||
* authenticated.
|
||||
* Returns the authenticated user associated with this session.
|
||||
*
|
||||
* @return
|
||||
* The credentials used when the user associated with this session
|
||||
* authenticated.
|
||||
* The authenticated user associated with this session.
|
||||
*/
|
||||
public Credentials getCredentials() {
|
||||
return credentials;
|
||||
public AuthenticatedUser getAuthenticatedUser() {
|
||||
return authenticatedUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the credentials associated with this session with the given
|
||||
* credentials.
|
||||
* Replaces the authenticated user associated with this session with the
|
||||
* given authenticated user.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials to associate with this session.
|
||||
* @param authenticatedUser
|
||||
* The authenticated user to associated with this session.
|
||||
*/
|
||||
public void setCredentials(Credentials credentials) {
|
||||
this.credentials = credentials;
|
||||
public void setAuthenticatedUser(AuthenticatedUser authenticatedUser) {
|
||||
this.authenticatedUser = authenticatedUser;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -24,6 +24,7 @@ package org.glyptodon.guacamole.net.basic.extension;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
@@ -118,7 +119,7 @@ public class AuthenticationProviderFacade implements AuthenticationProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(Credentials credentials)
|
||||
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Ignore auth attempts if no auth provider could be loaded
|
||||
@@ -128,13 +129,13 @@ public class AuthenticationProviderFacade implements AuthenticationProvider {
|
||||
}
|
||||
|
||||
// Delegate to underlying auth provider
|
||||
return authProvider.getUserContext(credentials);
|
||||
return authProvider.authenticateUser(credentials);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext updateUserContext(UserContext context, Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
public AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser,
|
||||
Credentials credentials) throws GuacamoleException {
|
||||
|
||||
// Ignore auth attempts if no auth provider could be loaded
|
||||
if (authProvider == null) {
|
||||
@@ -143,7 +144,38 @@ public class AuthenticationProviderFacade implements AuthenticationProvider {
|
||||
}
|
||||
|
||||
// Delegate to underlying auth provider
|
||||
return authProvider.updateUserContext(context, credentials);
|
||||
return authProvider.updateAuthenticatedUser(authenticatedUser, credentials);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Ignore auth attempts if no auth provider could be loaded
|
||||
if (authProvider == null) {
|
||||
logger.warn("User data retrieval attempt denied because the authentication system could not be loaded. Please check for errors earlier in the logs.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Delegate to underlying auth provider
|
||||
return authProvider.getUserContext(authenticatedUser);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserContext updateUserContext(UserContext context,
|
||||
AuthenticatedUser authenticatedUser)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Ignore auth attempts if no auth provider could be loaded
|
||||
if (authProvider == null) {
|
||||
logger.warn("User data refresh attempt denied because the authentication system could not be loaded. Please check for errors earlier in the logs.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Delegate to underlying auth provider
|
||||
return authProvider.updateUserContext(context, authenticatedUser);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -38,6 +38,7 @@ import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.environment.Environment;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
@@ -223,27 +224,27 @@ public class TokenRESTService {
|
||||
credentials.setRequest(request);
|
||||
credentials.setSession(request.getSession(true));
|
||||
|
||||
UserContext userContext;
|
||||
AuthenticatedUser authenticatedUser;
|
||||
try {
|
||||
|
||||
// Update existing user context if session already exists
|
||||
// Re-authenticate user if session exists
|
||||
if (existingSession != null)
|
||||
userContext = authProvider.updateUserContext(existingSession.getUserContext(), credentials);
|
||||
authenticatedUser = authProvider.updateAuthenticatedUser(existingSession.getAuthenticatedUser(), credentials);
|
||||
|
||||
/// Otherwise, generate a new user context
|
||||
/// Otherwise, authenticate as a new user
|
||||
else {
|
||||
|
||||
userContext = authProvider.getUserContext(credentials);
|
||||
authenticatedUser = authProvider.authenticateUser(credentials);
|
||||
|
||||
// Log successful authentication
|
||||
if (userContext != null && logger.isInfoEnabled())
|
||||
if (authenticatedUser != null && logger.isInfoEnabled())
|
||||
logger.info("User \"{}\" successfully authenticated from {}.",
|
||||
userContext.self().getIdentifier(), getLoggableAddress(request));
|
||||
authenticatedUser.getIdentifier(), getLoggableAddress(request));
|
||||
|
||||
}
|
||||
|
||||
// Request standard username/password if no user context was produced
|
||||
if (userContext == null)
|
||||
// Request standard username/password if no user was produced
|
||||
if (authenticatedUser == null)
|
||||
throw new GuacamoleInvalidCredentialsException("Permission Denied.",
|
||||
CredentialsInfo.USERNAME_PASSWORD);
|
||||
|
||||
@@ -265,22 +266,34 @@ public class TokenRESTService {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Generate or update user context
|
||||
UserContext userContext;
|
||||
if (existingSession != null)
|
||||
userContext = authProvider.updateUserContext(existingSession.getUserContext(), authenticatedUser);
|
||||
else
|
||||
userContext = authProvider.getUserContext(authenticatedUser);
|
||||
|
||||
// STUB: Request standard username/password if no user context was produced
|
||||
if (userContext == null)
|
||||
throw new GuacamoleInvalidCredentialsException("Permission Denied.",
|
||||
CredentialsInfo.USERNAME_PASSWORD);
|
||||
|
||||
// Update existing session, if it exists
|
||||
String authToken;
|
||||
if (existingSession != null) {
|
||||
authToken = token;
|
||||
existingSession.setCredentials(credentials);
|
||||
existingSession.setAuthenticatedUser(authenticatedUser);
|
||||
existingSession.setUserContext(userContext);
|
||||
}
|
||||
|
||||
// If no existing session, generate a new token/session pair
|
||||
else {
|
||||
authToken = authTokenGenerator.getToken();
|
||||
tokenSessionMap.put(authToken, new GuacamoleSession(environment, credentials, userContext));
|
||||
tokenSessionMap.put(authToken, new GuacamoleSession(environment, authenticatedUser, userContext));
|
||||
}
|
||||
|
||||
logger.debug("Login was successful for user \"{}\".", userContext.self().getIdentifier());
|
||||
return new APIAuthToken(authToken, userContext.self().getIdentifier());
|
||||
logger.debug("Login was successful for user \"{}\".", authenticatedUser.getIdentifier());
|
||||
return new APIAuthToken(authToken, authenticatedUser.getIdentifier());
|
||||
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,7 @@ import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleCredentialsException;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.permission.Permission;
|
||||
@@ -338,7 +339,15 @@ public class UserRESTService {
|
||||
credentials.setSession(request.getSession(true));
|
||||
|
||||
// Verify that the old password was correct
|
||||
if (authProvider.getUserContext(credentials) == null) {
|
||||
try {
|
||||
if (authProvider.authenticateUser(credentials) == null) {
|
||||
throw new APIException(APIError.Type.PERMISSION_DENIED,
|
||||
"Permission denied.");
|
||||
}
|
||||
}
|
||||
|
||||
// Pass through any credentials exceptions as simple permission denied
|
||||
catch (GuacamoleCredentialsException e) {
|
||||
throw new APIException(APIError.Type.PERMISSION_DENIED,
|
||||
"Permission denied.");
|
||||
}
|
||||
|
Reference in New Issue
Block a user