mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
GUAC-586: Implement AuthenticatedUser. Refactor to support authenticateUser(), etc. within the database AuthenticationProvider implementations.
This commit is contained in:
@@ -25,6 +25,7 @@ package org.glyptodon.guacamole.auth.jdbc.user;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +33,7 @@ import org.glyptodon.guacamole.net.auth.Credentials;
|
|||||||
*
|
*
|
||||||
* @author Michael Jumper
|
* @author Michael Jumper
|
||||||
*/
|
*/
|
||||||
public class AuthenticatedUser {
|
public class AuthenticatedUser implements org.glyptodon.guacamole.net.auth.AuthenticatedUser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user that authenticated.
|
* The user that authenticated.
|
||||||
@@ -44,6 +45,11 @@ public class AuthenticatedUser {
|
|||||||
*/
|
*/
|
||||||
private final Credentials credentials;
|
private final Credentials credentials;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The AuthenticationProvider that authenticated this user.
|
||||||
|
*/
|
||||||
|
private final AuthenticationProvider authenticationProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The host from which this user authenticated.
|
* The host from which this user authenticated.
|
||||||
*/
|
*/
|
||||||
@@ -106,13 +112,18 @@ public class AuthenticatedUser {
|
|||||||
* Creates a new AuthenticatedUser associating the given user with their
|
* Creates a new AuthenticatedUser associating the given user with their
|
||||||
* corresponding credentials.
|
* corresponding credentials.
|
||||||
*
|
*
|
||||||
|
* @param authenticationProvider
|
||||||
|
* The AuthenticationProvider that has authenticated the given user.
|
||||||
|
*
|
||||||
* @param user
|
* @param user
|
||||||
* The user this object should represent.
|
* The user this object should represent.
|
||||||
*
|
*
|
||||||
* @param credentials
|
* @param credentials
|
||||||
* The credentials given by the user when they authenticated.
|
* The credentials given by the user when they authenticated.
|
||||||
*/
|
*/
|
||||||
public AuthenticatedUser(ModeledUser user, Credentials credentials) {
|
public AuthenticatedUser(AuthenticationProvider authenticationProvider,
|
||||||
|
ModeledUser user, Credentials credentials) {
|
||||||
|
this.authenticationProvider = authenticationProvider;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.credentials = credentials;
|
this.credentials = credentials;
|
||||||
this.remoteHost = getRemoteHost(credentials);
|
this.remoteHost = getRemoteHost(credentials);
|
||||||
@@ -134,6 +145,7 @@ public class AuthenticatedUser {
|
|||||||
* @return
|
* @return
|
||||||
* The credentials given during authentication by this user.
|
* The credentials given during authentication by this user.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Credentials getCredentials() {
|
public Credentials getCredentials() {
|
||||||
return credentials;
|
return credentials;
|
||||||
}
|
}
|
||||||
@@ -148,4 +160,19 @@ public class AuthenticatedUser {
|
|||||||
return remoteHost;
|
return remoteHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticationProvider getAuthenticationProvider() {
|
||||||
|
return authenticationProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return user.getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIdentifier(String identifier) {
|
||||||
|
user.setIdentifier(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -25,17 +25,19 @@ package org.glyptodon.guacamole.auth.jdbc.user;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import org.glyptodon.guacamole.GuacamoleException;
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
|
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||||
import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
|
import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
|
||||||
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
|
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service which creates new UserContext instances for valid users based on
|
* Service which authenticates users based on credentials and provides for
|
||||||
* credentials.
|
* the creation of corresponding, new UserContext objects for authenticated
|
||||||
|
* users.
|
||||||
*
|
*
|
||||||
* @author Michael Jumper
|
* @author Michael Jumper
|
||||||
*/
|
*/
|
||||||
public class UserContextService {
|
public class AuthenticationProviderService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for accessing users.
|
* Service for accessing users.
|
||||||
@@ -51,11 +53,44 @@ public class UserContextService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates the user having the given credentials, returning a new
|
* Authenticates the user having the given credentials, returning a new
|
||||||
* UserContext instance only if the credentials are valid. If the
|
* AuthenticatedUser instance only if the credentials are valid. If the
|
||||||
* credentials are invalid or expired, an appropriate GuacamoleException
|
* credentials are invalid or expired, an appropriate GuacamoleException
|
||||||
* will be thrown.
|
* will be thrown.
|
||||||
*
|
*
|
||||||
|
* @param authenticationProvider
|
||||||
|
* The AuthenticationProvider on behalf of which the user is being
|
||||||
|
* authenticated.
|
||||||
|
*
|
||||||
* @param credentials
|
* @param credentials
|
||||||
|
* The credentials to use to produce the AuthenticatedUser.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A new AuthenticatedUser instance for the user identified by the
|
||||||
|
* given credentials.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs during authentication, or if the given
|
||||||
|
* credentials are invalid or expired.
|
||||||
|
*/
|
||||||
|
public AuthenticatedUser authenticateUser(AuthenticationProvider authenticationProvider,
|
||||||
|
Credentials credentials) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Authenticate user
|
||||||
|
AuthenticatedUser user = userService.retrieveAuthenticatedUser(authenticationProvider, credentials);
|
||||||
|
if (user != null)
|
||||||
|
return user;
|
||||||
|
|
||||||
|
// Otherwise, unauthorized
|
||||||
|
throw new GuacamoleInvalidCredentialsException("Invalid login", CredentialsInfo.USERNAME_PASSWORD);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returning a new UserContext instance for the given already-authenticated
|
||||||
|
* user. A new placeholder account will be created for any user that does
|
||||||
|
* not already exist within the database.
|
||||||
|
*
|
||||||
|
* @param authenticatedUser
|
||||||
* The credentials to use to produce the UserContext.
|
* The credentials to use to produce the UserContext.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
@@ -66,23 +101,18 @@ public class UserContextService {
|
|||||||
* If an error occurs during authentication, or if the given
|
* If an error occurs during authentication, or if the given
|
||||||
* credentials are invalid or expired.
|
* credentials are invalid or expired.
|
||||||
*/
|
*/
|
||||||
public org.glyptodon.guacamole.net.auth.UserContext
|
public UserContext getUserContext(org.glyptodon.guacamole.net.auth.AuthenticatedUser authenticatedUser)
|
||||||
getUserContext(Credentials credentials)
|
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Authenticate user
|
// Retrieve user account for already-authenticated user
|
||||||
ModeledUser user = userService.retrieveUser(credentials);
|
ModeledUser user = userService.retrieveUser(authenticatedUser);
|
||||||
if (user != null) {
|
if (user == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
// Upon successful authentication, return new user context
|
// Link to user context
|
||||||
UserContext context = userContextProvider.get();
|
UserContext context = userContextProvider.get();
|
||||||
context.init(user.getCurrentUser());
|
context.init(user.getCurrentUser());
|
||||||
return context;
|
return context;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, unauthorized
|
|
||||||
throw new GuacamoleInvalidCredentialsException("Invalid login", CredentialsInfo.USERNAME_PASSWORD);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@@ -40,6 +40,7 @@ import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionMapper;
|
|||||||
import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
|
import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
|
||||||
import org.glyptodon.guacamole.form.Field;
|
import org.glyptodon.guacamole.form.Field;
|
||||||
import org.glyptodon.guacamole.form.PasswordField;
|
import org.glyptodon.guacamole.form.PasswordField;
|
||||||
|
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||||
import org.glyptodon.guacamole.net.auth.User;
|
import org.glyptodon.guacamole.net.auth.User;
|
||||||
import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
|
import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
|
||||||
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
|
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
|
||||||
@@ -265,18 +266,22 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
|
|||||||
* the necessary additional parameters to reset the user's password, the
|
* the necessary additional parameters to reset the user's password, the
|
||||||
* password is reset.
|
* password is reset.
|
||||||
*
|
*
|
||||||
|
* @param authenticationProvider
|
||||||
|
* The AuthenticationProvider on behalf of which the user is being
|
||||||
|
* retrieved.
|
||||||
|
*
|
||||||
* @param credentials
|
* @param credentials
|
||||||
* The credentials to use when locating the user.
|
* The credentials to use when locating the user.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* The existing ModeledUser object if the credentials given are valid,
|
* An AuthenticatedUser containing the existing ModeledUser object if
|
||||||
* null otherwise.
|
* the credentials given are valid, null otherwise.
|
||||||
*
|
*
|
||||||
* @throws GuacamoleException
|
* @throws GuacamoleException
|
||||||
* If the provided credentials to not conform to expectations.
|
* If the provided credentials to not conform to expectations.
|
||||||
*/
|
*/
|
||||||
public ModeledUser retrieveUser(Credentials credentials)
|
public AuthenticatedUser retrieveAuthenticatedUser(AuthenticationProvider authenticationProvider,
|
||||||
throws GuacamoleException {
|
Credentials credentials) throws GuacamoleException {
|
||||||
|
|
||||||
// Get username and password
|
// Get username and password
|
||||||
String username = credentials.getUsername();
|
String username = credentials.getUsername();
|
||||||
@@ -298,7 +303,7 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
|
|||||||
|
|
||||||
// Create corresponding user object, set up cyclic reference
|
// Create corresponding user object, set up cyclic reference
|
||||||
ModeledUser user = getObjectInstance(null, userModel);
|
ModeledUser user = getObjectInstance(null, userModel);
|
||||||
user.setCurrentUser(new AuthenticatedUser(user, credentials));
|
user.setCurrentUser(new AuthenticatedUser(authenticationProvider, user, credentials));
|
||||||
|
|
||||||
// Verify user account is still valid as of today
|
// Verify user account is still valid as of today
|
||||||
if (!user.isAccountValid())
|
if (!user.isAccountValid())
|
||||||
@@ -343,6 +348,41 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return now-authenticated user
|
// Return now-authenticated user
|
||||||
|
return user.getCurrentUser();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the user corresponding to the given AuthenticatedUser from the
|
||||||
|
* database. If no such user exists, a placeholder entry will be created
|
||||||
|
* first.
|
||||||
|
*
|
||||||
|
* @param authenticatedUser
|
||||||
|
* The AuthenticatedUser to retrieve the corresponding ModeledUser of.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The ModeledUser which corresponds to the given AuthenticatedUser,
|
||||||
|
* created first if necessary.
|
||||||
|
*/
|
||||||
|
public ModeledUser retrieveUser(org.glyptodon.guacamole.net.auth.AuthenticatedUser authenticatedUser) {
|
||||||
|
|
||||||
|
// If we already queried this user, return that rather than querying again
|
||||||
|
if (authenticatedUser instanceof AuthenticatedUser)
|
||||||
|
return ((AuthenticatedUser) authenticatedUser).getUser();
|
||||||
|
|
||||||
|
// Get username
|
||||||
|
String username = authenticatedUser.getIdentifier();
|
||||||
|
|
||||||
|
// Retrieve corresponding user model, if such a user exists
|
||||||
|
UserModel userModel = userMapper.selectOne(username);
|
||||||
|
if (userModel == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Create corresponding user object, set up cyclic reference
|
||||||
|
ModeledUser user = getObjectInstance(null, userModel);
|
||||||
|
user.setCurrentUser(new AuthenticatedUser(authenticatedUser.getAuthenticationProvider(), user, authenticatedUser.getCredentials()));
|
||||||
|
|
||||||
|
// Return already-authenticated user
|
||||||
return user;
|
return user;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -31,9 +31,10 @@ import org.glyptodon.guacamole.net.auth.UserContext;
|
|||||||
import org.glyptodon.guacamole.auth.jdbc.JDBCAuthenticationProviderModule;
|
import org.glyptodon.guacamole.auth.jdbc.JDBCAuthenticationProviderModule;
|
||||||
import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService;
|
import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService;
|
||||||
import org.glyptodon.guacamole.auth.jdbc.tunnel.ConfigurableGuacamoleTunnelService;
|
import org.glyptodon.guacamole.auth.jdbc.tunnel.ConfigurableGuacamoleTunnelService;
|
||||||
import org.glyptodon.guacamole.auth.jdbc.user.UserContextService;
|
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticationProviderService;
|
||||||
import org.glyptodon.guacamole.environment.Environment;
|
import org.glyptodon.guacamole.environment.Environment;
|
||||||
import org.glyptodon.guacamole.environment.LocalEnvironment;
|
import org.glyptodon.guacamole.environment.LocalEnvironment;
|
||||||
|
import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -191,18 +192,37 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserContext getUserContext(Credentials credentials)
|
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Create AuthenticatedUser based on credentials, if valid
|
||||||
|
AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class);
|
||||||
|
return authProviderService.authenticateUser(this, credentials);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser,
|
||||||
|
Credentials credentials) throws GuacamoleException {
|
||||||
|
|
||||||
|
// No need to update authenticated users
|
||||||
|
return authenticatedUser;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Create UserContext based on credentials, if valid
|
// Create UserContext based on credentials, if valid
|
||||||
UserContextService userContextService = injector.getInstance(UserContextService.class);
|
AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class);
|
||||||
return userContextService.getUserContext(credentials);
|
return authProviderService.getUserContext(authenticatedUser);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserContext updateUserContext(UserContext context,
|
public UserContext updateUserContext(UserContext context,
|
||||||
Credentials credentials) throws GuacamoleException {
|
AuthenticatedUser authenticatedUser) throws GuacamoleException {
|
||||||
|
|
||||||
// No need to update the context
|
// No need to update the context
|
||||||
return context;
|
return context;
|
||||||
|
@@ -31,9 +31,10 @@ import org.glyptodon.guacamole.net.auth.UserContext;
|
|||||||
import org.glyptodon.guacamole.auth.jdbc.JDBCAuthenticationProviderModule;
|
import org.glyptodon.guacamole.auth.jdbc.JDBCAuthenticationProviderModule;
|
||||||
import org.glyptodon.guacamole.auth.jdbc.tunnel.ConfigurableGuacamoleTunnelService;
|
import org.glyptodon.guacamole.auth.jdbc.tunnel.ConfigurableGuacamoleTunnelService;
|
||||||
import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService;
|
import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService;
|
||||||
import org.glyptodon.guacamole.auth.jdbc.user.UserContextService;
|
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticationProviderService;
|
||||||
import org.glyptodon.guacamole.environment.Environment;
|
import org.glyptodon.guacamole.environment.Environment;
|
||||||
import org.glyptodon.guacamole.environment.LocalEnvironment;
|
import org.glyptodon.guacamole.environment.LocalEnvironment;
|
||||||
|
import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -191,18 +192,37 @@ public class PostgreSQLAuthenticationProvider implements AuthenticationProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserContext getUserContext(Credentials credentials)
|
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Create AuthenticatedUser based on credentials, if valid
|
||||||
|
AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class);
|
||||||
|
return authProviderService.authenticateUser(this, credentials);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser,
|
||||||
|
Credentials credentials) throws GuacamoleException {
|
||||||
|
|
||||||
|
// No need to update authenticated users
|
||||||
|
return authenticatedUser;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Create UserContext based on credentials, if valid
|
// Create UserContext based on credentials, if valid
|
||||||
UserContextService userContextService = injector.getInstance(UserContextService.class);
|
AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class);
|
||||||
return userContextService.getUserContext(credentials);
|
return authProviderService.getUserContext(authenticatedUser);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserContext updateUserContext(UserContext context,
|
public UserContext updateUserContext(UserContext context,
|
||||||
Credentials credentials) throws GuacamoleException {
|
AuthenticatedUser authenticatedUser) throws GuacamoleException {
|
||||||
|
|
||||||
// No need to update the context
|
// No need to update the context
|
||||||
return context;
|
return context;
|
||||||
|
Reference in New Issue
Block a user