使用Java程序从LDAP检索用户的嵌套组

时间:2014-02-14 21:35:33

标签: java ldap nested-groups

我在网上搜索,发现了类似的问题。因为我是LDAP的新手,所以不得不寻求帮助。

现在代码为用户带来了所有组。当user1登录时,它会带来A组。

新要求是: 如果A组是B组的成员,我们还需要检索B组以及A组。

我试图通过调整查询来实现这一目标。我读到了一些匹配规则 OID 1.2.840.113556.1.4.1941& LDAP_MATCHING_RULE_IN_CHAIN 即可。但无法弄清楚如何在我的代码中实现。

    import javax.naming.Context;
    import javax.naming.NamingEnumeration;
    import javax.naming.NamingException;
    import javax.naming.directory.SearchControls;
    import javax.naming.directory.SearchResult;
    import javax.naming.ldap.InitialLdapContext;
    import javax.naming.ldap.LdapContext;
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Hashtable;
    import java.util.List;


    public abstract class SAPSecurityFilter implements Filter {

        protected abstract SAPPrincipal buildGroups(SAPPrincipal principal, NamingEnumeration<SearchResult> results) throws NamingException;

        private static final String SECURE_ENTERPRISE_DIRECTORY = "ldaps://ldap.abc.com:636/o=abc.com";
        private static final String PRINCIPAL_NAME = "SAPPrincipal";
        private static final String ENTERPRISE_DIRECTORY = "ldap://ldap.abc.com:389/o=abc.com";
        private static final String USER_KEY = "HTTP_SM_USER";
        private static final String BASE = "ou=Groups";
        private static final String GROUP_QUERY = "(member=uid=%s,ou=People,o=abc.com)";
        private final CacheManager cacheManager;

        private List<String> excludeUrlPatterns = new ArrayList<String>();


        public SAPSecurityFilter() {
            // Setup Cache for principals
            // cache Manager
            URL url = getClass().getResource("/data-cache.xml");
            cacheManager = new CacheManager(url);
        }

        public void destroy() {
            // TODO Auto-generated method stub

        }

        /**
         * doFilter
         * <p/>
         * Read the request headers for the HTTP_SM_USER value
         * This value is the users email address.
         * Using the email address lookup the users values in Enterprise directory
         * Populate the principal and place it in request scope.
         */
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain) throws IOException, ServletException {

            //SAPt the request into HttpServletRequest
            String path = ((HttpServletRequest) request).getPathInfo();
            if (patternExcluded(path) || "OPTIONS".equalsIgnoreSAPe(((HttpServletRequest) request).getMethod())) {
                chain.doFilter(request, response);
            } else {
                String smUser = ((HttpServletRequest) request).getRemoteUser();
                HttpSession session = ((HttpServletRequest) request).getSession();
                if (smUser == null) throw new ServletException("USER TOKEN MISSING");

                // use the smUser to get the data needed to build a principal
                LdapContext ctx = null;
                // build SAP principal //
                SAPPrincipal principal = new SAPPrincipal();
                principal.setName(smUser);
                //Cache cache = cacheManager.getCache("principalCache");

                //Element element = cache.get(smUser);
                // Cache miss for user

                if (session.getAttribute(PRINCIPAL_NAME) == null) {

                    try {
                        ctx = getLdapContext(smUser);
                        SearchControls constraints = new SearchControls();
                        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
                        String[] attrs = {"cn"};
                        constraints.setReturningAttributes(attrs);

                        String filter = String.format(GROUP_QUERY, smUser);
                        NamingEnumeration<SearchResult> results = ctx.search(BASE, filter, constraints);
                        principal = buildGroups(principal, results);
                        //cache.put(new Element(smUser, principal));
                        session.setAttribute(PRINCIPAL_NAME, principal);
                    } catch (NamingException ne) {
                        throw new ServletException(ne);

                    } finally {
                        try {
                            if (ctx != null) ctx.close();
                        } catch (NamingException ne) {
                            // swallow on purpose
                        }
                    }
                    // Cache Hit for user
                } else {
                    principal = (SAPPrincipal) session.getAttribute(PRINCIPAL_NAME);
                }

                // add principal to securityContext and SAPContext//
                SAPContext.setPrincipal(principal);
                chain.doFilter(new SecurityRequestWrapper(principal, (HttpServletRequest) request), response);
            }

        }

1 个答案:

答案 0 :(得分:2)

您的过滤器必须类似于:

(member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))

形式:http://ldapwiki.willeke.com/wiki/Active%20Directory%20User%20Related%20Searches

-Jim