Announcement Announcement Module
Collapse
No announcement yet.
Authentication, Authorization & Connection Pooling Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Authentication, Authorization & Connection Pooling

    I'm developing a web service (using xfire in Spring) to front end access to our ldap which I talk to with ldaptemplate.

    I have ldaptemplate working well now, with the authentication credentials being set in the application context. But what I want to do is have the credentials passed as parms to the service. Different clients of the service will have different access to attributes set in the ldap (e.g. only user in the HR group will be able to see salary info).

    So how do I pragmatically set the userid and password that is used to connect to the ldap?

    Secondly, how should connection pooling work in this scenario? It seams that a new pool would get created for each user, right? So should connection pooling just be turned off?

    One idea I have to just authenticate the user against the LDAP, but then have everything else be done via the default (application context) user. (I'd also want to check to see if the user was in the webservice group, so I get authorization and not just authentication.)

    Any ideas and or code would be greatly appreciated.

  • #2
    You can do this by passing a custom AuthenticationSource to your ContextSource. Basically, what you'll want to do is store the authentication info (principal and credentials) somewhere thread-safe (typically in a ThreadLocal), and have your AuthenticationSource retrieve it from there when the information is requested by the ContextSource. As an example, have a look at AcegiAuthenticationSource, which retrieves the information from Acegi's SecurityContextHolder.

    As you note, the benefit of pooling becomes less obvious if each Context is authenticated using different credentials. However if you are performing more than one LDAP operation per user request I'd advise against turning pooling off unless server resources are very limited. A better idea would be to configure a shorter timeout on the pooled connections (say, 1-2 seconds), allowing each user to re-use the same connection during each request and quickly releasing it afterwards.

    Comment


    • #3
      How about doing it in Spring LDAP api

      It would be nice to have this ThreadLocal thing supported in api. Okey it´s not so big issue to code your own authentication source and get the credentials there but i think it is unnecessary code and it could be done in ldap template api. If there would be authentication source implementation that get username and password from threadlocal context and class that is setting this it would be great. And some way to use default username (for example rootdn) if thread local object is null.

      Comment


      • #4
        Quite right, we could supply a default implementation but that hasn't been a prioritized area so far. It's not unlikely it'll be included in a later release, but it won't be in the first one (we're hoping to do the release any day now).

        Comment


        • #5
          My understanding is:
          If using custom AuthenticationSource instead of using default user dn and password, PoolingContextSource should not be used. However, when configuring LdapContextSource, we should leave the "pooled" property defaulted to "true".

          Is this correct?

          Actually, is it safe to use PoolingContextSource with AcegiAuthenticationSource? It doesn't seem to pool connections by user dn...

          Comment


          • #6
            I was just trying to do the same thing, using user credentials to bind to LDAP directory.

            Here is the code of my AuthenticationSource implementation :
            Code:
            package fr.nancyu.web.sesame.dao;
            
            import org.springframework.ldap.core.AuthenticationSource;
            
            public class LdapAuthenticationSource implements AuthenticationSource {
            
            	private static ThreadLocal<String> login = new ThreadLocal<String>();
            	private static ThreadLocal<String> password = new ThreadLocal<String>();
            	
            	public static void setLogin(String login) {
            		LdapAuthenticationSource.login.set(login);
            	}
            
            	public static void setPassword(String password) {
            		LdapAuthenticationSource.password.set(password);
            	}
            
            	public String getPrincipal() {
            		String login = LdapAuthenticationSource.login.get();
            		if(login == null || "".equals(login)) {
            			return null;
            		}
            		return login;
            	}
            	
            	public String getCredentials() {
            		String password = LdapAuthenticationSource.password.get();
            		if(password == null || "".equals(password)) {
            			return null;
            		}
            		return password;
            	}
            
            }
            Here is the way I'm setting user CN and password before using LdapTemplate :

            Code:
            LdapAuthenticationSource.setLogin(dn.encode());
            LdapAuthenticationSource.setPassword(password);
            
            ...
            
            ldapTemplate.search(...);

            Comment

            Working...
            X