Announcement Announcement Module
Collapse
No announcement yet.
Verify password against LDAP server (how?) Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Verify password against LDAP server (how?)

    Hi,

    I have a custom login page/form which sends the username + password to a custom UserDetailsService.

    I need to verify the entered password against LDAP. But, I don't know how to retrieve the password.
    When browsing the AD with LDAP, I do not see a password attribute. All users have a password though.

    Currently I have this code:

    Code:
    /**
    	 * custom load user details test
    	 * @param userID the user id
    	 * @param password the entered password in the Form
    	 */
    	public void loadUserDetails(String userID, String password){
    
    		this.filterBasedLdapUserSearch.setDerefLinkFlag(true);
    		this.filterBasedLdapUserSearch.setSearchSubtree(true);
    		// get the user's entire context
    		DirContextOperations context = this.filterBasedLdapUserSearch.searchForUser(userID);
    
    
    
    		String password2 = context.getStringAttribute(?????????);
    	}
    All configuration is fine, because I can load a user's details+authorizations by only querying the AD with the user's login name (which is done in another method).

    So, how can I get the password from the AD using Spring LDAP via the DirContextOperations ?

    Thanks for your help,
    Coen

  • #2
    Look at:

    10.3.2. Using Bind Authentication
    10.4.1. LdapAuthenticator Implementations
    http://static.springsource.org/sprin...ence/ldap.html

    https://src.springframework.org/svn/...t-security.xml

    Comment


    • #3
      Yes, I already have that

      See my previous post. I have a successful authentication working based on SSO and a PreauthenticationFilter.

      Right now, I need an alternative scenario where I can query the AD via Spring LDAP and retrieve the password.
      The retrieved password then needs to be compared to the password entered by the user in the login form.

      The question I am asking is: how to retrieve the password from the AD?

      Now I am using:

      Code:
      DirContextOperations context = this.filterBasedLdapUserSearch.searchForUser(userID);
      
      String password2 = context.WHICHMETHOD????
      So, the user is found in the AD, but how can I get his password? I.e. context.getStringAttribute( .... which parameter??..... )

      Thanks,
      Coen

      Comment


      • #4
        What is your primary goal? Authenticate user against the Active Directory?

        If yes, the alternative way to password comparision is BindAuthenticator + LdapAuthenticationProvider.



        http://msdn.microsoft.com/en-us/libr...ROT.13%29.aspx
        dBCSPwd - Access is never granted
        unicodePwd - Access is never granted
        userPassword - When the dSHeuristics.fUserPwdSupport flag is false, the requester must be granted RIGHT_DS_READ_PROPERTY. When the dSHeuristics.fUserPwdSupport flag is true, access is never granted.

        dBCSPwd
        http://msdn.microsoft.com/en-us/libr...ROT.10%29.aspx

        unicodePwd
        http://msdn.microsoft.com/en-us/libr...ROT.10%29.aspx

        userPassword
        http://msdn.microsoft.com/en-us/libr...ROT.13%29.aspx
        Last edited by Andrei Tsibets; Sep 3rd, 2009, 08:55 AM.

        Comment


        • #5
          Ok, I found a solution. I was using spring-ldap 1.2. I saw that version 1.3.0.RELEASE has a new method.

          Code:
          ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(),
          					password);
          This does the trick.

          Cheers,
          Coen

          Comment


          • #6
            Should we use the ldapTemplate.authenticate call in loadUserDetails? I thought UserDetailsService was for loading the details of the user and populating the GrantedAuthorities. Maybe I'm getting the sequence of things confused. When does AuthenticationProvider.authenticate() get called in relation to UserDetailsService.loadUserDetails(). I thought authenticate was before loadUserDetails...

            In other words, shouldn't ldapTemplate.authenticate be called from the authenticate method of a custom AuthenticationProvider? Or actually, looking at BindAuthenticator's authenticate method, shouldn't lines 81-87 be replaced with a call to ldapTemplate.authenticate to make use of Spring LDAP 1.3? Sort of like what we find here: http://blog.jayway.com/2009/02/02/si...g-spring-ldap/ and also in Coenos' solution above.


            edit: I see this is being discussed in JIRA SEC-962: https://jira.springsource.org/browse/SEC-962
            Last edited by djKianoosh; Feb 23rd, 2010, 05:43 PM.

            Comment


            • #7
              The LDAP AuthenticationProvider doesn't use a UserDetailsService, so I don't really understand your question.

              Also, BindAuthenticator alread uses Spring LDAP 1.3's API addition to allow explicit binds by username/password.

              Comment


              • #8
                ok, let me see if i can explain (and hopefully clear my own thoughts about this in the process)...

                so the following configuration works (modified slightly from the ldap based example spring-security-samples-ldap-3.0.0.RELEASE.zip ), and it uses a BindAuthenticator for authentication:

                Code:
                    <!-- Simple namespace-based configuration -->
                
                    <s:ldap-server ldif="classpath:users.ldif" port="33389"/>
                
                    <s:authentication-manager>
                        <s:ldap-authentication-provider
                            group-search-filter="member={0}"
                            group-search-base="ou=groups"
                            user-search-base="ou=people"
                            user-search-filter="uid={0}"
                        />
                        <s:authentication-provider ref='secondLdapProvider' />
                    </s:authentication-manager>
                
                
                    <!-- Traditional Bean version of the same configuration -->
                
                    <!-- This bean points at the embedded directory server created by the ldap-server element above  -->
                    <!-- Modified based on Example 8.1 of section 8.1.3.2. Custom Principal and Credentials Management in the Spring LDAP Reference doc -->
                
                	<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
                		<property name="url" value="ldap://localhost:33389" />
                		<property name="base" value="dc=springframework,dc=org" />
                		<property name="authenticationSource" ref="springSecurityAuthenticationSource" />
                	</bean>
                	<bean id="springSecurityAuthenticationSource"
                		class="org.springframework.security.ldap.SpringSecurityAuthenticationSource" />
                    <bean id="secondLdapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
                        <constructor-arg>
                            <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                                <constructor-arg ref="contextSource" />
                                <property name="userSearch">
                                    <bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
                                      <constructor-arg index="0" value="ou=people"/>
                                      <constructor-arg index="1" value="(uid={0})"/>
                                      <constructor-arg index="2" ref="contextSource" />
                                    </bean>
                                </property>
                            </bean>
                        </constructor-arg>
                        <constructor-arg>
                            <bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
                                <constructor-arg ref="contextSource" />
                                <constructor-arg value="ou=groups" />
                                <property name="groupSearchFilter" value="(member={0})"/>
                                <property name="rolePrefix" value="ROLE_"/>
                                <property name="searchSubtree" value="true"/>
                                <property name="convertToUpperCase" value="true"/>
                            </bean>
                        </constructor-arg>
                    </bean>
                But for authorization, well, I guess it doesn't use LdapUserDetailsService? So the 'secondLdapProvider' bean has a 'DefaultLdapAuthoritiesPopulator' and that is what populates the roles, then? So I guess my question is when does LdapUserDetailsService come in to play?

                Comment


                • #9
                  So re-read chapter 5 of the spring security doc and it makes sense again. LdapUserDetailsService in this case is used to load the information about the user. That's separate from the actual authentication and authorization that happens on login.

                  Originally posted by Chapter 5, Spring Sec Doc
                  On successful authentication, UserDetails is used to build the Authentication object that is
                  stored in the SecurityContextHolder (more on this below). The good news is that we provide
                  a number of UserDetailsService implementations, including one that uses an in-memory map
                  (InMemoryDaoImpl) and another that uses JDBC (JdbcDaoImpl). Most users tend to write their
                  own, though, with their implementations often simply sitting on top of an existing Data Access Object
                  (DAO) that represents their employees, customers, or other users of the application. Remember the
                  advantage that whatever your UserDetailsService returns can always be obtained from the
                  SecurityContextHolder using the above code fragment.

                  Comment


                  • #10
                    Originally posted by djKianoosh View Post
                    So re-read chapter 5 of the spring security doc and it makes sense again. LdapUserDetailsService in this case is used to load the information about the user. That's separate from the actual authentication and authorization that happens on login.
                    You are exactly correct!

                    Comment

                    Working...
                    X