Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id D5AFF200B16 for ; Mon, 20 Jun 2016 19:18:17 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id D4432160A55; Mon, 20 Jun 2016 17:18:17 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id CCF4B160A26 for ; Mon, 20 Jun 2016 19:18:16 +0200 (CEST) Received: (qmail 72004 invoked by uid 500); 20 Jun 2016 17:18:16 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 71995 invoked by uid 99); 20 Jun 2016 17:18:16 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Jun 2016 17:18:16 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id E1821DFC6F; Mon, 20 Jun 2016 17:18:15 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: coheigea@apache.org To: commits@cxf.apache.org Message-Id: <199e3bb523834e819c3aaec00373cc0d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: cxf git commit: CXF-6947 - Make it possible to use custom LDAP filters when retrieving group information Date: Mon, 20 Jun 2016 17:18:15 +0000 (UTC) archived-at: Mon, 20 Jun 2016 17:18:18 -0000 Repository: cxf Updated Branches: refs/heads/master 189b6643d -> a1d8f8415 CXF-6947 - Make it possible to use custom LDAP filters when retrieving group information Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a1d8f841 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a1d8f841 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a1d8f841 Branch: refs/heads/master Commit: a1d8f8415cf5413aeda21b4e20ffded18889a25b Parents: 189b664 Author: Colm O hEigeartaigh Authored: Mon Jun 20 18:17:25 2016 +0100 Committer: Colm O hEigeartaigh Committed: Mon Jun 20 18:17:25 2016 +0100 ---------------------------------------------------------------------- .../cxf/sts/claims/LdapGroupClaimsHandler.java | 24 ++++++- .../org/apache/cxf/sts/claims/LdapUtils.java | 39 +++++++---- .../systest/kerberos/ldap/LDAPClaimsTest.java | 73 ++++++++++++++++++++ systests/kerberos/src/test/resources/ldap.ldif | 8 +++ systests/kerberos/src/test/resources/ldap.xml | 27 ++++++++ 5 files changed, 158 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/a1d8f841/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapGroupClaimsHandler.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapGroupClaimsHandler.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapGroupClaimsHandler.java index fbbbdd8..51e01a8 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapGroupClaimsHandler.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapGroupClaimsHandler.java @@ -38,6 +38,8 @@ import org.apache.cxf.rt.security.claims.Claim; import org.apache.cxf.rt.security.claims.ClaimCollection; import org.apache.cxf.sts.token.realm.RealmSupport; import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.filter.EqualsFilter; +import org.springframework.ldap.filter.Filter; public class LdapGroupClaimsHandler implements ClaimsHandler, RealmSupport { @@ -59,6 +61,7 @@ public class LdapGroupClaimsHandler implements ClaimsHandler, RealmSupport { private Map appliesToScopeMapping; private boolean useFullGroupNameAsValue; private List supportedRealms; + private List customFilters; private String realm; @@ -230,9 +233,15 @@ public class LdapGroupClaimsHandler implements ClaimsHandler, RealmSupport { LOG.finer("Retrieve groups for user " + user); } + List filters = new ArrayList<>(); + filters.add(new EqualsFilter(this.groupMemberAttribute, user)); + if (customFilters != null && !customFilters.isEmpty()) { + filters.addAll(customFilters); + } + List groups = LdapUtils.getAttributeOfEntries(ldap, this.groupBaseDn, this.getGroupObjectClass(), - this.groupMemberAttribute, user, "cn"); + filters, "cn"); if (groups == null || groups.size() == 0) { if (LOG.isLoggable(Level.INFO)) { @@ -335,5 +344,18 @@ public class LdapGroupClaimsHandler implements ClaimsHandler, RealmSupport { int trimEnd = filter.length() - ROLE.length() - roleStart; return group.substring(roleStart, group.length() - trimEnd); } + + public List getCustomFilters() { + return customFilters; + } + + /** + * Define some custom filters to use in retrieving group membership information. This allows you to restrict + * the groups that are returned based on some attribute value, for example. + * @param customFilters + */ + public void setCustomFilters(List customFilters) { + this.customFilters = customFilters; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/a1d8f841/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapUtils.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapUtils.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapUtils.java index 76c78fb..55106bc 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapUtils.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/LdapUtils.java @@ -18,6 +18,7 @@ */ package org.apache.cxf.sts.claims; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -39,6 +40,7 @@ import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.AbstractContextMapper; import org.springframework.ldap.filter.AndFilter; import org.springframework.ldap.filter.EqualsFilter; +import org.springframework.ldap.filter.Filter; public final class LdapUtils { @@ -95,26 +97,39 @@ public final class LdapUtils { String objectClass, String filterAttributeName, String filterAttributeValue, String searchAttribute) { + List filters = + Collections.singletonList(new EqualsFilter(filterAttributeName, filterAttributeValue)); + return getAttributeOfEntries(ldapTemplate, baseDN, objectClass, filters, searchAttribute); + } + + public static List getAttributeOfEntries( + LdapTemplate ldapTemplate, String baseDN, + String objectClass, List filters, + String searchAttribute) { + List ldapAttributes = null; AttributesMapper mapper = new AttributesMapper() { - public Object mapFromAttributes(Attributes attrs) throws NamingException { - NamingEnumeration attrEnum = attrs.getAll(); - while (attrEnum.hasMore()) { - return (String) attrEnum.next().get(); - } - return null; + public Object mapFromAttributes(Attributes attrs) throws NamingException { + NamingEnumeration attrEnum = attrs.getAll(); + while (attrEnum.hasMore()) { + return (String) attrEnum.next().get(); } - }; - + return null; + } + }; + String[] searchAttributes = new String[] {searchAttribute}; - + List result = null; AndFilter filter = new AndFilter(); - filter.and( - new EqualsFilter("objectclass", objectClass)).and( - new EqualsFilter(filterAttributeName, filterAttributeValue)); + filter.and(new EqualsFilter("objectclass", objectClass)); + if (filters != null) { + for (Filter f : filters) { + filter.and(f); + } + } result = ldapTemplate.search((baseDN == null) ? "" : baseDN, filter.toString(), SearchControls.SUBTREE_SCOPE, searchAttributes, mapper); http://git-wip-us.apache.org/repos/asf/cxf/blob/a1d8f841/systests/kerberos/src/test/java/org/apache/cxf/systest/kerberos/ldap/LDAPClaimsTest.java ---------------------------------------------------------------------- diff --git a/systests/kerberos/src/test/java/org/apache/cxf/systest/kerberos/ldap/LDAPClaimsTest.java b/systests/kerberos/src/test/java/org/apache/cxf/systest/kerberos/ldap/LDAPClaimsTest.java index 112ad81..47fc3b6 100644 --- a/systests/kerberos/src/test/java/org/apache/cxf/systest/kerberos/ldap/LDAPClaimsTest.java +++ b/systests/kerberos/src/test/java/org/apache/cxf/systest/kerberos/ldap/LDAPClaimsTest.java @@ -40,6 +40,7 @@ import org.apache.cxf.rt.security.claims.ClaimCollection; import org.apache.cxf.sts.claims.ClaimTypes; import org.apache.cxf.sts.claims.ClaimsParameters; import org.apache.cxf.sts.claims.LdapClaimsHandler; +import org.apache.cxf.sts.claims.LdapGroupClaimsHandler; import org.apache.cxf.sts.claims.ProcessedClaim; import org.apache.cxf.sts.claims.ProcessedClaimCollection; import org.apache.cxf.ws.security.sts.provider.STSException; @@ -365,6 +366,78 @@ public class LDAPClaimsTest extends AbstractLdapTestUnit { Assert.isTrue(foundCert); } + @org.junit.Test + public void testRetrieveRolesForAlice() throws Exception { + LdapGroupClaimsHandler claimsHandler = + (LdapGroupClaimsHandler)appContext.getBean("testGroupClaimsHandler"); + + String user = props.getProperty("claimUser"); + Assert.notNull(user, "Property 'claimUser' not configured"); + + ClaimCollection requestedClaims = new ClaimCollection(); + Claim claim = new Claim(); + URI roleURI = URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"); + claim.setClaimType(roleURI); + requestedClaims.add(claim); + + ClaimsParameters params = new ClaimsParameters(); + params.setPrincipal(new CustomTokenPrincipal(user)); + ProcessedClaimCollection retrievedClaims = + claimsHandler.retrieveClaimValues(requestedClaims, params); + + Assert.isTrue(retrievedClaims.size() == 1); + Assert.isTrue(retrievedClaims.get(0).getClaimType().equals(roleURI)); + Assert.isTrue(retrievedClaims.get(0).getValues().size() == 2); + } + + @org.junit.Test + public void testRetrieveRolesForBob() throws Exception { + LdapGroupClaimsHandler claimsHandler = + (LdapGroupClaimsHandler)appContext.getBean("testGroupClaimsHandlerOtherUsers"); + + String user = props.getProperty("otherClaimUser"); + Assert.notNull(user, "Property 'claimUser' not configured"); + + ClaimCollection requestedClaims = new ClaimCollection(); + Claim claim = new Claim(); + URI roleURI = URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"); + claim.setClaimType(roleURI); + requestedClaims.add(claim); + + ClaimsParameters params = new ClaimsParameters(); + params.setPrincipal(new CustomTokenPrincipal(user)); + ProcessedClaimCollection retrievedClaims = + claimsHandler.retrieveClaimValues(requestedClaims, params); + + Assert.isTrue(retrievedClaims.size() == 1); + Assert.isTrue(retrievedClaims.get(0).getClaimType().equals(roleURI)); + Assert.isTrue(retrievedClaims.get(0).getValues().size() == 2); + } + + @org.junit.Test + public void testRetrieveRolesForBobInBusinessCategoryWidgets() throws Exception { + LdapGroupClaimsHandler claimsHandler = + (LdapGroupClaimsHandler)appContext.getBean("testGroupClaimsHandlerFilter"); + + String user = props.getProperty("otherClaimUser"); + Assert.notNull(user, "Property 'claimUser' not configured"); + + ClaimCollection requestedClaims = new ClaimCollection(); + Claim claim = new Claim(); + URI roleURI = URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"); + claim.setClaimType(roleURI); + requestedClaims.add(claim); + + ClaimsParameters params = new ClaimsParameters(); + params.setPrincipal(new CustomTokenPrincipal(user)); + ProcessedClaimCollection retrievedClaims = + claimsHandler.retrieveClaimValues(requestedClaims, params); + + Assert.isTrue(retrievedClaims.size() == 1); + Assert.isTrue(retrievedClaims.get(0).getClaimType().equals(roleURI)); + Assert.isTrue(retrievedClaims.get(0).getValues().size() == 1); + } + private ClaimCollection createRequestClaimCollection() { ClaimCollection claims = new ClaimCollection(); Claim claim = new Claim(); http://git-wip-us.apache.org/repos/asf/cxf/blob/a1d8f841/systests/kerberos/src/test/resources/ldap.ldif ---------------------------------------------------------------------- diff --git a/systests/kerberos/src/test/resources/ldap.ldif b/systests/kerberos/src/test/resources/ldap.ldif index 0456f93..ac82b07 100644 --- a/systests/kerberos/src/test/resources/ldap.ldif +++ b/systests/kerberos/src/test/resources/ldap.ldif @@ -33,6 +33,14 @@ cn: boss member: cn=alice,ou=users,dc=example,dc=com description: The boss +dn: cn=manager,ou=groups,dc=example,dc=com +objectClass: groupOfNames +objectClass: top +cn: manager +businessCategory: widgets +member: cn=bob,ou=other-users,dc=example,dc=com +description: The boss + # Web server identity/service principal. dn: cn=bob,ou=other-users,dc=example,dc=com objectclass: top http://git-wip-us.apache.org/repos/asf/cxf/blob/a1d8f841/systests/kerberos/src/test/resources/ldap.xml ---------------------------------------------------------------------- diff --git a/systests/kerberos/src/test/resources/ldap.xml b/systests/kerberos/src/test/resources/ldap.xml index 11583e7..a64ad07 100644 --- a/systests/kerberos/src/test/resources/ldap.xml +++ b/systests/kerberos/src/test/resources/ldap.xml @@ -50,4 +50,31 @@ + + + + + + + + + + + + + + + + businessCategory + + + widgets + + + + + + + +