So this is my first time working with Spring so bear with me!

I am pretty sure the problem is that my set-up for DnPatterns and the group search base is incorrect.

There is an external AD I am trying to hook up to. Using ad explorer I've found an entry, below is the dn of the user and then the login in id they usually use to logIn

As listend in the profile of the user in the AD Explorer View

DN -> CN=LastName\, FirstName, OU=Users,OU=Calgary,DC=CORP,DC=DEPARTMENT,DC=com

Username & password User will provide on login:

UserName ->  LastFirst5
Password ->  Password

The path to reach the user info in the Directory Explorer is as shown

DC=CORP,DC=DEPARTMENT,DC=com -> OU=Calgary -> OU=Users -> CN=LastName,FirstName

This is my config set-up:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin();
    }


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .ldapAuthentication()
                .userDnPatterns("DC=corp,DC=department,DC=com")
                .groupSearchBase("OU=Users,OU=Calgary,DC=CORP,DC=Department,DC=com")
                .contextSource()
                .url("ldap://corp.Ad.com/")
                .and()
                .passwordCompare()
                .passwordEncoder(new LdapShaPasswordEncoder())
                .passwordAttribute("userPassword");
    }

1 Answers

1
EricLavault On Best Solutions
  • First the context source url should include the base DN for searching and/or authenticating users.

    .contextSource()
      .url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
    
  • userDnPatterns() is used to match the login name of a user as it appears in the RDN of your user entries - if it appears ! - the server then substitutes the login name entered by the user for the {0} placeholder, and from that recreates the user dn by appending the base dn from the LDAP url. The problem is that in your directory, a user dn is not built from its username but from its cn attribute that is different so you can't have a match (LastName, FirstName ≠ LastFirst5), hence you can't authenticate users with this method (but a correct pattern would look like cn={0},ou=Users if username and cn were equivalent).

  • userSearchFilter() on the other hand can be used to match the login name provided by the user using a regular search filter. Optionally userSearchBase() can be used with it to set an optional branch rdn where user entries are located and from which to perform the search, if not specified the search includes your entire directory starting from the base dn of the LDAP url.

    .and()
      .userSearchBase('ou=Users,ou=Calgary')
      .userSearchFilter('(sAMAccountName={0})')
    

    Note that if you have users in other cities like OU=Users,OU=OtherCity,DC=..., you will need another configuration in order to authenticate them without knowing from which city to start the search. In this case you would reset the search base to match all entries under the base dn and, since you only want users to be able to login, you would refine the filter accordingly :

    .and()
      .userSearchBase('')
      .userSearchFilter('(&(sAMAccountName={0})(objectClass=user)')
    
  • You don't need groupSearchBase() without groupSearchFilter(), and these 2 are needed only for authorization (to verify the user has a given role <=> is member of a given group).

  • To be able to search & match a user entry, the authentication request itself needs to connect and bind to the LDAP server, most servers don't accept anonymous bindings so you may need to set managerDn() and managerPassword() :

    .contextSource()
      .url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
      .managerDn('admin')
      .managerPassword('password')
    

https://community.jaspersoft.com/documentation/jasperreports-server-authentication-cookbook/performing-ldap-user-search