Return-Path: Delivered-To: apmail-portals-jetspeed-dev-archive@www.apache.org Received: (qmail 30458 invoked from network); 13 Jan 2010 01:50:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 13 Jan 2010 01:50:49 -0000 Received: (qmail 70854 invoked by uid 500); 13 Jan 2010 01:50:48 -0000 Delivered-To: apmail-portals-jetspeed-dev-archive@portals.apache.org Received: (qmail 70766 invoked by uid 500); 13 Jan 2010 01:50:48 -0000 Mailing-List: contact jetspeed-dev-help@portals.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Jetspeed Developers List" Delivered-To: mailing list jetspeed-dev@portals.apache.org Received: (qmail 70756 invoked by uid 99); 13 Jan 2010 01:50:48 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jan 2010 01:50:48 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jan 2010 01:50:47 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id F3922238897D; Wed, 13 Jan 2010 01:50:26 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r898611 - in /portals/jetspeed-2/portal/trunk: components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/ components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/ components/jetspeed-security/src/... Date: Wed, 13 Jan 2010 01:50:26 -0000 To: jetspeed-dev@portals.apache.org From: ate@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100113015026.F3922238897D@eris.apache.org> Author: ate Date: Wed Jan 13 01:50:25 2010 New Revision: 898611 URL: http://svn.apache.org/viewvc?rev=898611&view=rev Log: JS2-1096: Several issues with LdapAuthenticationProvider and LdapContextProxy: rewrite using Spring LDAP instead See: http://issues.apache.org/jira/browse/JS2-1096 This also contains some minimal cleanup and added TODO markers, and should as side-effect also have fixed JS2-1030. Removed: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/ldap/ Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseAuthenticationProvider.java portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseAuthenticationProvider.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseAuthenticationProvider.java?rev=898611&r1=898610&r2=898611&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseAuthenticationProvider.java (original) +++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/BaseAuthenticationProvider.java Wed Jan 13 01:50:25 2010 @@ -23,9 +23,7 @@ import org.apache.jetspeed.components.util.system.SystemResourceUtil; import org.apache.jetspeed.components.util.system.ClassLoaderSystemResourceUtilImpl; -import org.apache.jetspeed.security.AuthenticatedUser; import org.apache.jetspeed.security.AuthenticationProvider; -import org.apache.jetspeed.security.SecurityException; /** * @see org.apache.jetspeed.security.AuthenticationProvider Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java?rev=898611&r1=898610&r2=898611&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java (original) +++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java Wed Jan 13 01:50:25 2010 @@ -16,11 +16,7 @@ */ package org.apache.jetspeed.security.impl; -import java.util.Hashtable; - import javax.naming.AuthenticationException; -import javax.naming.Context; -import javax.naming.InitialContext; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.DirContext; @@ -34,47 +30,60 @@ import org.apache.jetspeed.security.SecurityException; import org.apache.jetspeed.security.User; import org.apache.jetspeed.security.UserManager; -import org.apache.jetspeed.security.mapping.ldap.util.DnUtils; import org.apache.jetspeed.security.spi.JetspeedSecuritySynchronizer; import org.apache.jetspeed.security.spi.UserPasswordCredentialManager; -import org.apache.jetspeed.security.spi.impl.ldap.LdapContextProxy; + +import org.springframework.ldap.pool.factory.PoolingContextSource; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.filter.AndFilter; +import org.springframework.ldap.filter.EqualsFilter; +import org.springframework.ldap.filter.Filter; +import org.springframework.ldap.filter.HardcodedFilter; +import org.springframework.ldap.support.LdapUtils; /** - * @author Vivek Kumar - * @version $Id: + * @author Ate Douma + * @version $Id$ */ public class LdapAuthenticationProvider extends BaseAuthenticationProvider { private JetspeedSecuritySynchronizer synchronizer; private UserPasswordCredentialManager upcm; private UserManager manager; - private LdapContextProxy context; - - public LdapAuthenticationProvider(String providerName, String providerDescription, String loginConfig, UserPasswordCredentialManager upcm, - UserManager manager) + private PoolingContextSource poolingContextsource; + private String userEntryPrefix; + private DistinguishedName userSearchPath; + private SearchControls searchControls; + private Filter userFilter; + + public LdapAuthenticationProvider(String providerName, String providerDescription, String loginConfig, + UserPasswordCredentialManager upcm, UserManager manager, JetspeedSecuritySynchronizer synchronizer, PoolingContextSource poolingContextSource, + String ldapBase, String userSearchBase, String userFilter, String userEntryPrefix, String searchScope) { super(providerName, providerDescription, loginConfig); this.upcm = upcm; this.manager = manager; - } - - public void setContext(LdapContextProxy context) - { - this.context = context; - } - - public void setSynchronizer(JetspeedSecuritySynchronizer synchronizer) - { this.synchronizer = synchronizer; + this.poolingContextsource = poolingContextSource; + this.userEntryPrefix = userEntryPrefix; + this.userSearchPath = new DistinguishedName(ldapBase); + this.userSearchPath.append(new DistinguishedName(userSearchBase)); + if (!StringUtils.isEmpty(userFilter)) + { + this.userFilter = new HardcodedFilter(userFilter); + } + this.searchControls = new SearchControls(); + this.searchControls.setReturningAttributes(new String[]{}); + this.searchControls.setReturningObjFlag(true); + this.searchControls.setSearchScope(Integer.parseInt(searchScope)); } public AuthenticatedUser authenticate(String userName, String password) throws SecurityException { AuthenticatedUser authUser = null; - boolean authenticated = false; try { - if (userName == null) + if (StringUtils.isEmpty(userName)) { throw new SecurityException(SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped(JetspeedPrincipalType.USER, userName)); } @@ -82,16 +91,17 @@ { throw new SecurityException(SecurityException.PASSWORD_REQUIRED); } - authenticated = authenticateUser(userName, password); - if (authenticated) + authenticateUser(userName, password); + if (synchronizer != null) { - User user = getUser(userName); - authUser = new AuthenticatedUserImpl(user, new UserCredentialImpl(upcm.getPasswordCredential(user))); + synchronizer.synchronizeUserPrincipal(userName,false); } + User user = manager.getUser(userName); + authUser = new AuthenticatedUserImpl(user, new UserCredentialImpl(upcm.getPasswordCredential(user))); } catch (SecurityException authEx) { - if (authEx.getCause().getMessage().equalsIgnoreCase("[LDAP: error code 49 - Invalid Credentials]")) + if (authEx.getCause() != null && authEx.getCause().getMessage().equalsIgnoreCase("[LDAP: error code 49 - Invalid Credentials]")) { throw new SecurityException(SecurityException.INCORRECT_PASSWORD); } @@ -103,40 +113,39 @@ return authUser; } - private User getUser(String userName) throws SecurityException - { - if (synchronizer != null) - { - synchronizer.synchronizeUserPrincipal(userName,false); - } - return manager.getUser(userName); - } - - private boolean authenticateUser(String userName, String password) throws SecurityException + private void authenticateUser(String userName, String password) throws SecurityException { + DirContext ctx = null; try { - Hashtable env = (Hashtable) context.getCtx().getEnvironment().clone(); - // String savedPassword = String.valueOf(getPassword(uid)); - String dn = lookupByUid(userName); - if (dn == null) + Filter filter = new EqualsFilter(userEntryPrefix, userName); + if (userFilter != null) { - throw new SecurityException(SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped(JetspeedPrincipalType.USER, userName)); + filter = new AndFilter().and(userFilter).and(filter); } - // Build user dn using lookup value, just appending the user filter after the uid won't work when users - // are/can be stored in a subtree (searchScope sub-tree) - // The looked up dn though is/should always be correct, just need to append the root context. - if (!StringUtils.isEmpty(context.getRootContext())) - { - if (DnUtils.encodeDn(dn).indexOf(DnUtils.encodeDn(context.getRootContext())) < 0) + ctx = poolingContextsource.getReadOnlyContext(); + NamingEnumeration results = ctx.search(userSearchPath, filter.encode(), searchControls); + LdapUtils.closeContext(ctx); + ctx = null; + + String dn = null; + if (null != results && results.hasMore()) + { + SearchResult result = results.next(); + dn = result.getName(); + if (result.isRelative()) { - dn += "," + DnUtils.encodeDn(context.getRootContext()); + DistinguishedName name = (DistinguishedName)userSearchPath.clone(); + name.append(new DistinguishedName(dn)); + dn = name.encode(); } } - env.put(Context.SECURITY_PRINCIPAL, dn); - env.put(Context.SECURITY_CREDENTIALS, password); - new InitialContext(env); - return true; + if (dn == null) + { + throw new SecurityException(SecurityException.PRINCIPAL_DOES_NOT_EXIST.createScoped(JetspeedPrincipalType.USER, userName)); + } + // Note: this "authenticating" context is (logically) not pooled + ctx = poolingContextsource.getContextSource().getContext(dn, password); } catch (AuthenticationException aex) { @@ -146,86 +155,9 @@ { throw new SecurityException(SecurityException.UNEXPECTED.create(getClass().getName(), "authenticateUser", nex.getMessage())); } - } - - public String lookupByUid(final String uid) throws SecurityException - { - try - { - SearchControls cons = setSearchControls(); - NamingEnumeration searchResults = searchByWildcardedUid(uid, cons); - return getFirstDnForUid(searchResults); - } - catch (NamingException e) - { - throw new SecurityException(e); - } - } - - protected SearchControls setSearchControls() - { - SearchControls controls = new SearchControls(); - controls.setReturningAttributes(new String[] {}); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setReturningObjFlag(true); - return controls; - } - - protected NamingEnumeration searchByWildcardedUid(final String filter, SearchControls cons) throws NamingException - { - // usa a template method to use users/groups/roles - String query = ""; - if (StringUtils.isEmpty(getSearchSuffix())) - { - query = "(" + context.getEntryPrefix() + "=" + (StringUtils.isEmpty(filter) ? "*" : filter) + ")"; - } - else - { - query = "(&(" + context.getEntryPrefix() + "=" + (StringUtils.isEmpty(filter) ? "*" : filter) + ")" + getSearchSuffix() + ")"; - } - // logger.debug("searchByWildCardedUid = " + query); - cons.setSearchScope(Integer.parseInt(context.getMemberShipSearchScope())); - // TODO: added this here for OpenLDAP (when users are stored in ou=People,o=evenSeas) - // String searchBase = StringUtils.replace(getSearchDomain(), "," + context.getRootContext(), ""); - NamingEnumeration results = ((DirContext) context.getCtx()).search(getSearchDomain(), query, cons); - return results; - } - - private String getFirstDnForUid(NamingEnumeration searchResults) throws NamingException - { - String userDn = null; - while ((null != searchResults) && searchResults.hasMore()) - { - SearchResult searchResult = (SearchResult) searchResults.next(); - userDn = searchResult.getName(); - String searchDomain = getSearchDomain(); - if (searchDomain.length() > 0) - { - userDn += "," + StringUtils.replace(searchDomain, "," + context.getRootContext(), ""); - } - } - return userDn; - } - - private String getSearchSuffix() - { - return context.getUserFilter(); - } - - private String getSearchDomain() - { - StringBuffer searchDomain = new StringBuffer(); - if (!StringUtils.isEmpty(context.getUserSearchBase())) - { - searchDomain.append(context.getUserSearchBase()); - } - if (searchDomain.length() == 0) + finally { - if (!StringUtils.isEmpty(context.getRootContext())) - { - searchDomain.append(context.getRootContext()); - } + LdapUtils.closeContext(ctx); } - return searchDomain.toString(); } } Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java?rev=898611&r1=898610&r2=898611&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java (original) +++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java Wed Jan 13 01:50:25 2010 @@ -291,6 +291,7 @@ logger.error("Unexpected SecurityException trying to remove (" + relatedPrincipal.getType().getName() + "," + principal.getType().getName() + "," + associationName + ") association during synchronization.", e); } + // TODO: proper exception handling! } } } @@ -317,6 +318,7 @@ { logger.error("Unexpected SecurityException during synchronization.", e); } + // TODO: proper exception handling! } protected JetspeedPrincipal synchronizePrincipalAttributes(Entity entity) @@ -349,6 +351,7 @@ { logger.error("Unexpected exception in adding new pricipal of type " + updatedPrincipal.getType().getName() + ".", sexp); } + // TODO: proper exception handling! } attrsToBeUpdated.addAll(mappedEntityAttrs.values()); } @@ -410,6 +413,7 @@ { logger.error("Unexpected exception for attribute " + addedEntityAttr.getMappedName() + ".", e); } + // TODO: proper exception handling! } } } @@ -432,9 +436,10 @@ } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + logger.error("Unexpected SecurityException: could not remove attribute "+principalAttrEntry.getKey()+" for principal " + updatedPrincipal.getName() + " of type " + + updatedPrincipal.getType().getName(), e); } + // TODO: proper exception handling! } } // step 3, update synchronized principal @@ -452,6 +457,7 @@ logger.error("Unexpected SecurityException: could not synchronize principal " + updatedPrincipal.getName() + " of type " + updatedPrincipal.getType().getName(), e); } + // TODO: proper exception handling! } } } Modified: portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml?rev=898611&r1=898610&r2=898611&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml (original) +++ portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml Wed Jan 13 01:50:25 2010 @@ -73,18 +73,20 @@ - + - - - - login.conf - - - - - + + + + + + + + + + + + - + @@ -156,7 +158,7 @@ - + @@ -181,7 +183,6 @@ - @@ -201,7 +202,7 @@ - + @@ -226,7 +227,6 @@ - @@ -311,40 +311,37 @@ - + - - ${ldap.url} - - - ${ldap.base} - - - ${ldap.userDn} + + + + - - ${ldap.password} - - + - - - ${ldap.context.factory} - - - ${ldap.user.filter} - - - ${ldap.search.scope} - - - ${ldap.user.searchBase} - - - ${ldap.user.entryPrefix} - + + + + + + + + + + + + + + + + + + + Modified: portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties?rev=898611&r1=898610&r2=898611&view=diff ============================================================================== --- portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties (original) +++ portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties Wed Jan 13 01:50:25 2010 @@ -343,7 +343,11 @@ ldap.user.searchBase= ldap.user.entryPrefix=uid ldap.role.searchBase=ou=Roles,o=Jetspeed +ldap.role.filter = (objectClass=groupOfUniqueNames) ldap.group.searchBase=ou=Groups,o=Jetspeed +ldap.group.filter = (objectClass=groupOfUniqueNames) +ldap.context.pool.maxActive = 20 +ldap.context.pool.maxIdle = 20 #------------------------------------------------------------------------- # P R O F I L E R --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org For additional commands, e-mail: jetspeed-dev-help@portals.apache.org