Announcement Announcement Module
Collapse
No announcement yet.
additional attributes queried when using spring ldaptemplate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • additional attributes queried when using spring ldaptemplate

    Disclosure: I'm new at spring-ldap and I didn't write this code but now have to debug. Even so, I sure would appreciate the help...

    We've started using spring-ldap-1.3.3 with WebLogic 9.2. Specifying a list of attributes to query (example: {"cn", "uid", givenName"}), and using a template.search(....) gives the correct results... no problem there.

    -- The ISSUE:
    LDAP logs show that the query is asking for additional attributes and the LDAP admin does not like this:

    ... SRCH base="..." scope=1 filter="..." attrs="cn uid givenName javaSerializedData javaClassName javaFactory javaCodebase javaReferenceAddress javaClassNames javaremotelocation"

    The ldap admin is complaining that we are querying non-indexed values and thus slowing things down. I can't find really anything *wrong* with querying these attributes, they don't give exceptions, but why does the spring-ldap do this? and more importantly how can I get rid of those? Is is some combo of using spring with WL JNDI?

    If I do an ldap query using direct WebLogic JNDI w/o spring templates I get the the same log entry MINUS the javaXXXX attributes. So it seems to be strictly a spring thing.

    Pointers to doc, even an RTFM (as long as you please tell me which manual and which chapter/section)... all helpful. I've search this forum and googled but can't find anything related.

    Many thanks.

  • #2
    After more testing, webLogic is irrelevant... please ignore that.

    I ran the sample PersonDaoImpl & TraditionalPersonDaoImpl from the 1.3.3 release and got equal results (yeah for that!)

    The traditional method produces this entry in the ldap access log:
    SRCH ... attrs="cn givenName mail description"

    but the spring-ldap version creates this entry:
    SRCH ... attrs="cn givenName mail description objectClass javaSerializedData javaClassName javaFactory javaCodebase javaReferenceAddress javaClassNames javaremotelocation"

    Both use com.sun.jndi.ldap.LdapCtxFactory... the only difference that I can see is using spring-ldap.

    I still need help if anyone can provide me with info. Many thanks in advance.


    My ldap.xml if that helps (well, one attempt... I played with the context factory but nothing produced different results):

    <bean id="personDao" class="org.mlp.basic.dao.PersonDaoImpl">
    <property name="ldapTemplate" ref="ldapTemplate" />
    </bean>

    <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate" >
    <constructor-arg ref="contextSource" />
    </bean>

    <bean id="contextSource" class="org.springframework.ldap.core.support.DirCo ntextSource">
    <property name="url" value="${ldap.url}" />
    <property name="contextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
    <property name="base" value="${ldap.base}" />
    <property name="userDn" value="${ldap.username}" />
    <property name="password" value="${ldap.password}" />
    </bean>

    <bean id="traditionalPersonDao" class="org.mlp.basic.dao.TraditionalPersonDaoImpl" >
    <property name="url" value="${ldap.url}" />
    <property name="base" value="${ldap.base}" />
    <property name="userDn" value="${ldap.username}" />
    <property name="password" value="${ldap.password}" />
    </bean>
    Last edited by marshapetry; Oct 28th, 2009, 10:38 AM. Reason: wanted to incdlue full ldap.xml

    Comment


    • #3
      First we should get the version straight. You repeatedly write "the 1.3.3 release". The latest version of Spring LDAP is 1.3.0.RELEASE. Are you referring to a custom build or something?

      Second, you should use [code][/code] tags around your code or printouts. That makes it easy to read and doesn't add spaces or weird breaks in the text.

      Spring LDAP is basically a thin wrapper on top of JNDI, so it's unlikely that Spring LDAP is causing any peculiar behavior that isn't also caused when using raw JNDI. However, there could be a setting on SearchControls that differs, or something like that.

      The TraditionalPersonDaoImpl does this in the findAll method:

      Code:
               SearchControls controls = new SearchControls();
               controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
               results = ctx.search("", "(objectclass=person)", controls);
      The PersonDaoImpl does this:

      Code:
      	return ldapTemplate.search(DistinguishedName.EMPTY_PATH, filter.encode(), getContextMapper());
      which eventually boils down to this in LdapTemplate:

      Code:
      	SearchControls controls = new SearchControls();
      	controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
      	controls.setReturningObjFlag(true);
      	controls.setReturningAttributes(null);
      	return ctx.search("", "(objectclass=person)", controls);
      The returningAttributes is stated in the javadoc to be null by default, so that shouldn't be the cause. However, returningObjFlag is false by default. That's the only difference that I can see between the traditional JNDI method and the Spring LDAP version.

      One method, getAllPersonNames, uses an AttributesMapper instead of a ContextMapper, thus causing returningObjFlag to be false. Could you check the log for that specific method and compare the traditional with the Spring LDAP version?

      Comment


      • #4
        Thank you, I will try to do my formatting better.
        At this point ldap admin has compromised and is OK with the javaXXXX attrs - they are not causing any problems and are taking only minimal (if any) extra processing time. So this is now more a research exercise than problem - I am not requesting help. I will post any further info, if valuable, for others who may notice the same thing.


        Release 1.3.0 - standard, nothing custom. Sorry for the typo. Java 1.5, SunOne directory

        Below is the relevant code --- I've tried to make them as equivalent as possible and as stripped down as possible so that they're easy to read. Running each of these returns the same data but the ldap log of PersonDaoImpl has javaXXX attrs and TradtionalPersonDaoImpl does not (as noted in prev posts):

        TraditionalPersonDaoImpl:
        Code:
        public List<Person> findAll() {
            DirContext ctx = createAuthenticatedContext();
            LinkedList<Person> list = new LinkedList<Person>();
            
            NamingEnumeration results = null;
            try {
                 String[] myAttrs = new String[]{"cn", "uid"};
                 String filterStr = "(&(objectclass=top)(!(uid=*-xx)))";
        
                 SearchControls controls = new SearchControls();
                 controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
                 controls.setReturningAttributes(myAttrs);
        
                 results = ctx.search("", filterStr, controls);
        
                 while (results.hasMore()) {
                      SearchResult searchResult = (SearchResult) results.next();
                      String dn = searchResult.getName();
                      Attributes attributes = searchResult.getAttributes();
                      list.add((mapToPerson(dn, attributes)));
                  }
            }
                ...catch code not changed...
        PersonDaoImpl:
        Code:
        public List<Person> findAll() {
            String[] myAttrs = new String[]{"cn", "uid"};
            String filterStr = "(&(objectclass=top)(!(uid=*-xx)))";
            return ldapTemplate.search(
                         DistinguishedName.EMPTY_PATH, 
                         filterStr,
                         SearchControls.ONELEVEL_SCOPE,
                         myAttrs,
                         getContextMapper());
        }
        I have stepped through the spring source up to the basic jndi call and it looks as though the myAttrs remain intact. Yet there is consistently the addition of the javaXXX in the ldap call.

        I will do 2 things: 1) run the Attributes Mapper and 2) try returningObjFlag both true/false (I think I did that already but I'll double check) and post the results here. Also, if I find a definite answer I will post but other than that I will leave this topic unfinished unless someone cares to know more.
        Last edited by marshapetry; Oct 29th, 2009, 12:19 PM. Reason: made the code formatted better

        Comment


        • #5
          JNDI (and Spring LDAP) provides two versions of each search call: one with a String base name and one with a Name base name. Could you try the Spring LDAP version but replace DistinguishedName.EMPTY_PATH with an empty String? Just to make sure there's no funny stuff when using a Name.

          Comment


          • #6
            Well, I'll be...

            I did find a difference.

            When I use a context mapper, it doesn't matter whether I set ReturningObjFlag to true or false, the ldap request *always* asks for the javaXXXX attrs.

            However! When I used an AttributesMapper with controls.setReturningObjFlag(false), it did NOT request the javaXXXX attrs. It was the only combination I could find that did not request them. If controls.setReturningObjFlag(true) then it, once again, asked for the javaXXX attrs.

            Here's the call that worked (by "worked" I mean did NOT request the javaXXX attrs):

            Code:
                public List<Person> findAllUsingAttributesMapper() {
                    String[] myAttrs = new String[]{"cn", "uid"};
                    String filterStr = "(&(objectclass=top)(!(uid=*-xx)))";
            		
                    SearchControls controls = new SearchControls(
                            SearchControls.ONELEVEL_SCOPE,0,0,myAttrs,false,true);
                 
            //              When controls.setReturningObjFlag(false) and using an AttibutesMapper,
            //                   the ldap log request does NOT include the javaXXXXX attrs
            //              When controls.setReturningObjFlag(true) and using an AttibutesMapper,
            //                   the ldap log request DOES include the javaXXXXX attrs
                    
                    return ldapTemplate.search(
                            DistinguishedName.EMPTY_PATH, 
                            filterStr,
                            controls,
                            getAttributesMapper());
                }
            Didn't matter whether I used the DistinguishedName or an empty string.

            Comment


            • #7
              When I use a context mapper, it doesn't matter whether I set ReturningObjFlag to true or false, the ldap request *always* asks for the javaXXXX attrs.
              Well, I can explain that. Spring LDAP will deeper down in the code make sure that returningObjFlag is true whenever a ContextMapper is used. That particular mapper needs the object to be returned, otherwise an exception will be thrown when the mapper kicks in.

              So, just to be clear, if you run your plain JNDI test with the addition of setting returningObjFlag to true in your SearchControls, I'm pretty sure that you will get the extra attributes too.

              Comment


              • #8
                Yes, you are correct. If I use jndi with setting ReturningObjFlag to true, it requests the javaXXXX attrs.

                I guess I did not realize that ContextMapper intentionally always gets those extra attributes. I don't exactly understand why but I'm only moderately familiar with ldap so I'll do a little reading to try and figure out why.

                This means that for us to play nice with the ldap admins we will have to use the AttributeMapper... but I simply may not tell him that I found another way to query

                Thank you.

                Comment


                • #9
                  The returningObj property enables JNDI to decode JNDI References and Serializable objects stored in LDAP. Spring LDAP sets the flag mainly for getting the search result converted to a DirContext. I guess we should re-evaluate the need for this.

                  If you look at Sun's implementation of LdapContext, LdapCtx, you see that the search implementation adds all attributes in an array called Obj.JAVA_ATTRIBUTES, if the returningObjFlag is true:

                  Code:
                   1798           // if objects are requested then request the Java attributes too
                   1799           // so that the objects can be constructed
                   1800           if (cons.getReturningObjFlag()) {
                   1801               if (reqAttrs != null) {
                   1802   
                   1803                   // check for presence of "*" (user attributes wildcard)
                   1804                   boolean hasWildcard = false;
                   1805                   for (int i = reqAttrs.length - 1; i >= 0; i--) {
                   1806                       if (reqAttrs[i].equals("*")) {
                   1807                           hasWildcard = true;
                   1808                           break;
                   1809                       }
                   1810                   }
                   1811                   if (! hasWildcard) {
                   1812                       String[] totalAttrs =
                   1813                           new String[reqAttrs.length +Obj.JAVA_ATTRIBUTES.length];
                   1814                       System.arraycopy(reqAttrs, 0, totalAttrs, 0,
                   1815                           reqAttrs.length);
                   1816                       System.arraycopy(Obj.JAVA_ATTRIBUTES, 0, totalAttrs,
                   1817                           reqAttrs.length, Obj.JAVA_ATTRIBUTES.length);
                   1818   
                   1819                       cons.setReturningAttributes(totalAttrs);
                   1820                   }
                   1821               }
                   1822           }
                  If we take a look at the Obj class, we see the following attributes:

                  Code:
                     65       // LDAP attributes used to support Java objects.
                     66       static final String[] JAVA_ATTRIBUTES = {
                     67           "objectClass",
                     68           "javaSerializedData",
                     69           "javaClassName",
                     70           "javaFactory",
                     71           "javaCodeBase",
                     72           "javaReferenceAddress",
                     73           "javaClassNames",
                     74           "javaRemoteLocation"     // Deprecated
                     75       };
                  They map nicely to your list of unexpected attributes:

                  Code:
                  javaSerializedData javaClassName javaFactory javaCodebase javaReferenceAddress javaClassNames javaremotelocation

                  Comment


                  • #10
                    Now as some time has gone by...

                    Does anybody know if there is a solution available in the meantime to avoid these additional parameters when using SearchControls.setReturningObjFlag(true)?

                    Thanks in advance for any hint.

                    Comment

                    Working...
                    X