Announcement Announcement Module
No announcement yet.
Authentication with LDAP or POP3? Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Authentication with LDAP or POP3?


    I was wondering if it is possible to do the verification of provided username and password using LDAP (Active Directory) or POP3 server to avoid the need for separate username/password pairs for different corporate systems.

    At the moment I'm using DaoAuthenticationProvider and I store usernames and passwords in DB separately for my intranet app.
    To implement the POP3 authentication I need to verify the password but I never get it, because there is only username passed into the loadUserByUsername(username) method.

    Is there any possible solution to this problem in Acegi?


  • #2
    Could you use the new JaasAuthenticationProvider along with one of the existing JAAS-based LDAP LoginModules that are out there are present?

    You could write a new AuthenticationProvider that simply tries to login to the POP3 account using the presented username and password. But I would caution against that as it's fairly ugly (getting a mail server involved with authentication) and for similar effort you could bind against the LDAP server.

    Or, you could write an LDAP-based AuthenticationDao. For that to work you would need to connect to the LDAP server with an account capable of reading the password properties of LDAP users, because as you point out you never get the authentication request's password passed to the AuthenticationDao.

    The best option would be to write an LDAP AuthenticationProvider. This would bind to the LDAP server with the presented username and password. Thus even if the LDAP server stores it in an encoded form or simply doesn't return the password, you'd still in effect validate the credentials by the act of binding to the server. Don't forget about caching if you go this part. A cache would be a good idea (like UserCache in the DaoAuthenticationProvider land) to avoid needless round-trips to the LDAP server.

    Of course, code contributions are always welcome, as LDAP comes up reasonably frequently (and unfortunately I don't have time to setup an LDAP server simply to write an LdapAuthenticationProvider).


    • #3
      Ben, Thanks for explaining the possibilities. It seems I will have to play with that in near future, so when I create something working I will be pleased to contribute it.


      • #4


        I have created a new AuthenticationProvider based on DaoAuthenticationProvider called PasswordDaoAuthenticationProvider. It works in a similar way as DaoAuthenticationProvider but delegates the responsibility of password validation to the PasswordAuthenticationDao:

        public interface PasswordAuthenticationDao {
          public UserDetails loadUserByUsernameAndPassword(String username, String password)
                throws DataAccessException, BadCredentialsException;
        So this provider could be used in environments where it is not possible to return the (encoded) password. And for example LdapPasswordAuthenticationDaoImpl can be written. Inside of this DAO implementation can be combined access into any DB or LDAP (DB for loading user object and LDAP for username/password validation).

        I have also created appropriate PasswordUserCache, because username+password must be the cache key in this case.

        All the created classes and interfaces are distinguished by the "Password" prefix and the rest of the names is the same as in the current DaoAuthentication case.

        Let me know if you would like to add it into acegisecurity or not.
        If yes we can think about better names for the classes and I could write some unit tests for it.

        I'm sending you the sources by email.



        • #5
          Hi Karel

          Quite a good approach. I did think about whether this would be better in DaoAuthenticationProvider itself, but I think you're approach is the right one given it would make DaoAuthenticationProvider so much more complex with unclear responsibilities compared with its associated DAO.

          If you'd like to provide some unit tests and hopefully an LDAP implementation for your new package, I'd be very pleased to add them to CVS.


          • #6
            Ok great, I will review the javadoc comments, create tests and send it to you. Then I will start to play games with the LdapPasswordAuthenticationDaoImpl .


            • #7
              As per my off-list reply, I've checked the initial code into CVS. Just waiting on the LDAP-specific PasswordAuthenticationDao now.


              • #8
                kajism, have you gotten anywhere with the LdapPasswordAuthenticationDaoImpl implementation yet? I am working on a project that would benefit from having the functionality that has been discussed in this thread.



                • #9
                  Karel sent me a basic LDAP implementation and unit test, but I haven't got an LDAP server setup to test it. If some people would volunteer to integration test it, I'd be happy to add to CVS.


                  • #10
                    LDAP Authentication Provider


                    I have written an LDAP Authentication Provider. If anyone is interested I can see if my employer would let me contribute it.


                    Stephen Baishya


                    • #11
                      Hi Stephen: does it use PasswordAuthenticationDao? I already have Karel's original plus some enhancements provided by Daniel Miller. I have just committed them to a new "sandbox" area of Acegi Security CVS, so please feel free to try them out and submit any improvements.


                      • #12
                        No, it's a non-DAO provider. DAO didn't seem appropriate for LDAP as you would most commonly use a 'bind' to authenticate rather than retrieving the password.

                        It supports the following:
                        • Authenticate via bind.
                          Authorise via group membership (i.e. a role is represented by a group, which itself can be a member of another group up to a configurable level of nesting).
                          Authorise via a role attribute on the prinicipal object.


                        • #13
                          LdapAuthenticationPasswordDao provides authentication via binding. In fact that is why a new PasswordAuthenticationDao was created. Your GrantedAuthority resolution sounds interesting. It would be good if we could combine the two efforts. It was felt designing the PasswordAuthenticationDao approach was optimal as it allows the use of a pluggable DAO whilst still enjoying provider-managed caching etc.


                          • #14

                            I'm just getting familiar with Acegi today and am trying to map a role/group/user authorization approach onto Acegi. Obviously, these concepts aren't exposed explicitly in Acegi and it is up to an user impl to provide this functionality with a custom AuthenticationDao. (Right?) It seems Stephen has gone down the path of managing the mapping of to Roles and Groups to GrantedAuthorities. I'd be interested in hearing about that in more detail. Seems like an impl that supports role/group/user based authorization would be a nice out of the box feature to have. Just my 2 cents, I'm just getting my sea legs with Acegi - great work btw!



                            • #15
                              Hi Mark

                              Yes, you're right in that Acegi Security does not provide group support out-of-the-box. Nor does it really provide role support out-of-the-box.

                              We have gone with a more flexible GrantedAuthority[] approach. This allows developers to reflect whatever assignable permissions they like. If all they need is a simple RBAC or group model, they can just use a very simple GrantedAuthority implementation called GrantedAuthorityImpl. If on the other hand they need to consider in access control decisions whether a permission was obtained directly or via a group, they can easily create an AuthorityFromGroup implementation which notes the group. The onus is on the DAO which returns the GrantedAuthority[] to fill it with appropriate instances to reflect the security needs of the application. I think this is a reasonable approach, given the types of permissions (GrantedAuthority implementations) developers may need to reflect could vary widely between applications.

                              There is an LDAP-based DAO in the Acegi Security CVS sandbox. You might be interested in taking a look at it and building group support on it (perhaps it already has it - I haven't had a good look). The same goes for the JdbcDaoImpl. I have no problems if people wish to add group support to the DAOs. We just need to keep any group management responsibility in the actual DAO implementations, and not at a higher layer.