From 5ca32a221afb9ff478e8b460e45fc14e790bcc5d Mon Sep 17 00:00:00 2001 From: Jared Frees Date: Fri, 8 Jun 2018 12:34:06 -0400 Subject: [PATCH] GUACAMOLE-524: Add LDAP attributes to credentials. AuthenticationProviderService gets LDAP attributes from confService and queries the LDAP server to find values on user for specified attributes. Added a Map to Credentials named ldapAttrs and a getLDAPAttributes() and setLDAPAttributes() to manipulate ldapAttrs on credentials. Once AuthenticationProviderService gets the values for the LDAP attributes it sets ldapAttrs on the credentials object. --- .../ldap/AuthenticationProviderService.java | 71 ++++++++++++++++++- .../guacamole/net/auth/Credentials.java | 25 ++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java index a25c697e6..2d28c79be 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java @@ -26,12 +26,21 @@ import java.util.List; import org.apache.guacamole.auth.ldap.user.AuthenticatedUser; import org.apache.guacamole.auth.ldap.user.UserContext; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.auth.ldap.user.UserService; import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.credentials.CredentialsInfo; import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.Iterator; +import com.novell.ldap.LDAPAttributeSet; +import com.novell.ldap.LDAPEntry; +import com.novell.ldap.LDAPAttribute; +import com.novell.ldap.LDAPException; /** * Service providing convenience functions for the LDAP AuthenticationProvider @@ -189,7 +198,7 @@ public class AuthenticationProviderService { /** * Returns an AuthenticatedUser representing the user authenticated by the - * given credentials. + * given credentials. Also adds custom LDAP attributes to credentials object. * * @param credentials * The credentials to use for authentication. @@ -221,6 +230,14 @@ public class AuthenticationProviderService { throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD); try { + try { + String username = credentials.getUsername(); + Map ldapAttrs = getLDAPAttributes(ldapConnection, username); + credentials.setLDAPAttributes(ldapAttrs); + } + catch (LDAPException e) { + throw new GuacamoleServerException("Error while querying for LDAP User Attributes.", e); + } // Return AuthenticatedUser if bind succeeds AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); @@ -236,6 +253,58 @@ public class AuthenticationProviderService { } + /** + * Returns all custom LDAP attributes on the user currently bound under + * the given LDAP connection. The custom attributes are specified in + * guacamole.properties. + * + * @param ldapConnection + * LDAP connection to find the custom LDAP attributes. + * @param username + * The username of the user whose attributes are queried. + * + * @return + * All attributes on the user currently bound under the + * given LDAP connection, as a map of attribute name to + * corresponding attribute value. + * + * @throws LDAPException + * If an error occurs while searching for the user attributes. + * + * @throws GuacamoleException + * If an error occurs retrieving the user DN. + */ + private Map getLDAPAttributes(LDAPConnection ldapConnection, + String username) throws LDAPException, GuacamoleException { + + // Get attributes from configuration information + List attrList = confService.getAttributes(); + + // If there are no attributes there is no reason to search LDAP + if (attrList.size() == 0) + return null; + + // Build LDAP query parameters + String[] attrArray = attrList.toArray(new String[attrList.size()]); + String userDN = getUserBindDN(username); + + // Get LDAP attributes by querying LDAP + LDAPEntry userEntry = ldapConnection.read(userDN, attrArray); + LDAPAttributeSet attrSet = userEntry.getAttributeSet(); + + // Add each attribute into Map + Map attrMap = new HashMap(); + Iterator attrIterator = attrSet.iterator(); + while (attrIterator.hasNext()) { + LDAPAttribute attr = (LDAPAttribute)attrIterator.next(); + String attrName = attr.getName(); + String attrValue = attr.getStringValue(); + attrMap.put(attrName, attrValue); + } + + return attrMap; + } + /** * Returns a UserContext object initialized with data accessible to the * given AuthenticatedUser. diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Credentials.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Credentials.java index 142c51653..076970737 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Credentials.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Credentials.java @@ -22,7 +22,7 @@ package org.apache.guacamole.net.auth; import java.io.Serializable; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; - +import java.util.Map; /** * Simple arbitrary set of credentials, including a username/password pair, @@ -72,6 +72,29 @@ public class Credentials implements Serializable { */ private transient HttpSession session; + /** + * Arbitrary LDAP attributes specified in guacamole.properties + */ + private Map ldapAttrs; + + /** + * Returns the lDAP attributes associated with this set of credentials. + * @return The LDAP attributes Map associated with this set of credentials, + * or null if no LDAP Attributes have been set. + */ + public Map getLDAPAttributes() { + return ldapAttrs; + } + + /** + * Sets the LDAP attributes associated with this set of credentials. + * @param attributes The LDAP attributes to associate with this set of + * credentials. + */ + public void setLDAPAttributes(Map attributes) { + this.ldapAttrs = attributes; + } + /** * Returns the password associated with this set of credentials. * @return The password associated with this username/password pair, or