mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-09 06:31:22 +00:00
GUAC-1115: Move LDAP connection management into own service.
This commit is contained in:
@@ -25,8 +25,6 @@ package org.glyptodon.guacamole.auth.ldap;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.novell.ldap.LDAPConnection;
|
import com.novell.ldap.LDAPConnection;
|
||||||
import com.novell.ldap.LDAPException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.glyptodon.guacamole.auth.ldap.user.AuthenticatedUser;
|
import org.glyptodon.guacamole.auth.ldap.user.AuthenticatedUser;
|
||||||
import org.glyptodon.guacamole.auth.ldap.user.UserContext;
|
import org.glyptodon.guacamole.auth.ldap.user.UserContext;
|
||||||
@@ -51,6 +49,12 @@ public class AuthenticationProviderService {
|
|||||||
*/
|
*/
|
||||||
private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class);
|
private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for creating and managing connections to LDAP servers.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private LDAPConnectionService ldapService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for retrieving LDAP server configuration information.
|
* Service for retrieving LDAP server configuration information.
|
||||||
*/
|
*/
|
||||||
@@ -75,28 +79,6 @@ public class AuthenticationProviderService {
|
|||||||
@Inject
|
@Inject
|
||||||
private Provider<UserContext> userContextProvider;
|
private Provider<UserContext> userContextProvider;
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnects the given LDAP connection, logging any failure to do so
|
|
||||||
* appropriately.
|
|
||||||
*
|
|
||||||
* @param ldapConnection
|
|
||||||
* The LDAP connection to disconnect.
|
|
||||||
*/
|
|
||||||
private void disconnect(LDAPConnection ldapConnection) {
|
|
||||||
|
|
||||||
// Attempt disconnect
|
|
||||||
try {
|
|
||||||
ldapConnection.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn if disconnect unexpectedly fails
|
|
||||||
catch (LDAPException e) {
|
|
||||||
logger.warn("Unable to disconnect from LDAP server: {}", e.getMessage());
|
|
||||||
logger.debug("LDAP disconnect failed.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the DN which corresponds to the user having the given
|
* Determines the DN which corresponds to the user having the given
|
||||||
* username. The DN will either be derived directly from the user base DN,
|
* username. The DN will either be derived directly from the user base DN,
|
||||||
@@ -122,7 +104,7 @@ public class AuthenticationProviderService {
|
|||||||
if (searchBindDN != null) {
|
if (searchBindDN != null) {
|
||||||
|
|
||||||
// Create an LDAP connection using the search account
|
// Create an LDAP connection using the search account
|
||||||
LDAPConnection searchConnection = bindAs(
|
LDAPConnection searchConnection = ldapService.bindAs(
|
||||||
searchBindDN,
|
searchBindDN,
|
||||||
confService.getSearchBindPassword()
|
confService.getSearchBindPassword()
|
||||||
);
|
);
|
||||||
@@ -147,7 +129,7 @@ public class AuthenticationProviderService {
|
|||||||
|
|
||||||
// Always disconnect
|
// Always disconnect
|
||||||
finally {
|
finally {
|
||||||
disconnect(searchConnection);
|
ldapService.disconnect(searchConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -157,78 +139,6 @@ public class AuthenticationProviderService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds to the LDAP server using the provided user DN and password.
|
|
||||||
*
|
|
||||||
* @param userDN
|
|
||||||
* The DN of the user to bind as, or null to bind anonymously.
|
|
||||||
*
|
|
||||||
* @param password
|
|
||||||
* The password to use when binding as the specified user, or null to
|
|
||||||
* attempt to bind without a password.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* A bound LDAP connection, or null if the connection could not be
|
|
||||||
* bound.
|
|
||||||
*
|
|
||||||
* @throws GuacamoleException
|
|
||||||
* If an error occurs while binding to the LDAP server.
|
|
||||||
*/
|
|
||||||
private LDAPConnection bindAs(String userDN, String password)
|
|
||||||
throws GuacamoleException {
|
|
||||||
|
|
||||||
LDAPConnection ldapConnection;
|
|
||||||
|
|
||||||
// Connect to LDAP server
|
|
||||||
try {
|
|
||||||
ldapConnection = new LDAPConnection();
|
|
||||||
ldapConnection.connect(
|
|
||||||
confService.getServerHostname(),
|
|
||||||
confService.getServerPort()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (LDAPException e) {
|
|
||||||
logger.error("Unable to connect to LDAP server: {}", e.getMessage());
|
|
||||||
logger.debug("Failed to connect to LDAP server.", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind using provided credentials
|
|
||||||
try {
|
|
||||||
|
|
||||||
byte[] passwordBytes;
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Convert password into corresponding byte array
|
|
||||||
if (password != null)
|
|
||||||
passwordBytes = password.getBytes("UTF-8");
|
|
||||||
else
|
|
||||||
passwordBytes = null;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException e) {
|
|
||||||
logger.error("Unexpected lack of support for UTF-8: {}", e.getMessage());
|
|
||||||
logger.debug("Support for UTF-8 (as required by Java spec) not found.", e);
|
|
||||||
disconnect(ldapConnection);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind as user
|
|
||||||
ldapConnection.bind(LDAPConnection.LDAP_V3, userDN, passwordBytes);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disconnect if an error occurs during bind
|
|
||||||
catch (LDAPException e) {
|
|
||||||
logger.debug("LDAP bind failed.", e);
|
|
||||||
disconnect(ldapConnection);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ldapConnection;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds to the LDAP server using the provided Guacamole credentials. The
|
* Binds to the LDAP server using the provided Guacamole credentials. The
|
||||||
* DN of the user is derived using the LDAP configuration properties
|
* DN of the user is derived using the LDAP configuration properties
|
||||||
@@ -272,7 +182,7 @@ public class AuthenticationProviderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bind using user's DN
|
// Bind using user's DN
|
||||||
return bindAs(userDN, password);
|
return ldapService.bindAs(userDN, password);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +230,7 @@ public class AuthenticationProviderService {
|
|||||||
|
|
||||||
// Always disconnect
|
// Always disconnect
|
||||||
finally {
|
finally {
|
||||||
disconnect(ldapConnection);
|
ldapService.disconnect(ldapConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -359,7 +269,7 @@ public class AuthenticationProviderService {
|
|||||||
|
|
||||||
// Always disconnect
|
// Always disconnect
|
||||||
finally {
|
finally {
|
||||||
disconnect(ldapConnection);
|
ldapService.disconnect(ldapConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -81,6 +81,7 @@ public class LDAPAuthenticationProviderModule extends AbstractModule {
|
|||||||
bind(ConfigurationService.class);
|
bind(ConfigurationService.class);
|
||||||
bind(ConnectionService.class);
|
bind(ConnectionService.class);
|
||||||
bind(EscapingService.class);
|
bind(EscapingService.class);
|
||||||
|
bind(LDAPConnectionService.class);
|
||||||
bind(UserService.class);
|
bind(UserService.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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.auth.ldap;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.novell.ldap.LDAPConnection;
|
||||||
|
import com.novell.ldap.LDAPException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for creating and managing connections to LDAP servers.
|
||||||
|
*
|
||||||
|
* @author Michael Jumper
|
||||||
|
*/
|
||||||
|
public class LDAPConnectionService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger for this class.
|
||||||
|
*/
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(LDAPConnectionService.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for retrieving LDAP server configuration information.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private ConfigurationService confService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds to the LDAP server using the provided user DN and password.
|
||||||
|
*
|
||||||
|
* @param userDN
|
||||||
|
* The DN of the user to bind as, or null to bind anonymously.
|
||||||
|
*
|
||||||
|
* @param password
|
||||||
|
* The password to use when binding as the specified user, or null to
|
||||||
|
* attempt to bind without a password.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A bound LDAP connection, or null if the connection could not be
|
||||||
|
* bound.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs while binding to the LDAP server.
|
||||||
|
*/
|
||||||
|
public LDAPConnection bindAs(String userDN, String password)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
LDAPConnection ldapConnection;
|
||||||
|
|
||||||
|
// Connect to LDAP server
|
||||||
|
try {
|
||||||
|
ldapConnection = new LDAPConnection();
|
||||||
|
ldapConnection.connect(
|
||||||
|
confService.getServerHostname(),
|
||||||
|
confService.getServerPort()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (LDAPException e) {
|
||||||
|
logger.error("Unable to connect to LDAP server: {}", e.getMessage());
|
||||||
|
logger.debug("Failed to connect to LDAP server.", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind using provided credentials
|
||||||
|
try {
|
||||||
|
|
||||||
|
byte[] passwordBytes;
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Convert password into corresponding byte array
|
||||||
|
if (password != null)
|
||||||
|
passwordBytes = password.getBytes("UTF-8");
|
||||||
|
else
|
||||||
|
passwordBytes = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
logger.error("Unexpected lack of support for UTF-8: {}", e.getMessage());
|
||||||
|
logger.debug("Support for UTF-8 (as required by Java spec) not found.", e);
|
||||||
|
disconnect(ldapConnection);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind as user
|
||||||
|
ldapConnection.bind(LDAPConnection.LDAP_V3, userDN, passwordBytes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect if an error occurs during bind
|
||||||
|
catch (LDAPException e) {
|
||||||
|
logger.debug("LDAP bind failed.", e);
|
||||||
|
disconnect(ldapConnection);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ldapConnection;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects the given LDAP connection, logging any failure to do so
|
||||||
|
* appropriately.
|
||||||
|
*
|
||||||
|
* @param ldapConnection
|
||||||
|
* The LDAP connection to disconnect.
|
||||||
|
*/
|
||||||
|
public void disconnect(LDAPConnection ldapConnection) {
|
||||||
|
|
||||||
|
// Attempt disconnect
|
||||||
|
try {
|
||||||
|
ldapConnection.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn if disconnect unexpectedly fails
|
||||||
|
catch (LDAPException e) {
|
||||||
|
logger.warn("Unable to disconnect from LDAP server: {}", e.getMessage());
|
||||||
|
logger.debug("LDAP disconnect failed.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user