LDAP / AD authentication

Got an idea? Missing something? Post your feature request here.

Moderator: moderators

LDAP / AD authentication

Postby Svenson » Mon Oct 16, 2006 11:45 am

Hi.

Would it by possible to have LDAP User authentication ?
It would be awesome if Subsonic could authenticate users against Active Directory.


Thanks,
Svenni
Svenson
 
Posts: 6
Joined: Mon Oct 16, 2006 12:15 am

Postby sindre_mehus » Mon Oct 16, 2006 6:56 pm

Thanks for the suggestion, I'll consider it. It all depends on how hard it is to implement, and how user-friendly it will be.

Sindre
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway

Postby thofmann » Sun Dec 30, 2007 1:07 pm

Hi,

I've found out about subsonic only a few weeks ago and I really love it.

I also wanted to use Active Directory (AD) for authentication and authorization. After playing around with the source a bit I found out that using AD for authentication is no problem. Authorization would also work based on group memberships but unfortunately subsonic does not use the GrantedAuthority instances available in acegi for all decisions that involve roles. Instead, the information is taken from the net.sourceforge.subsonic.domain.User which is populated from the role information in the database.

So supporting LDAP authorization would require some more code changes. Authentication on the other hand is pretty easy to do with the following changes to applicationContext-security.xml:


Code: Select all
    <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <!-- add the following line for LDAP authentication -->
               <ref local="activeDirectoryAuthenticationProvider"/>
                <!-- comment out the following line to disable database authentication -->
                <!--  <ref local="daoAuthenticationProvider"/> -->
                <bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
                    <property name="key" value="subsonic"/>
                </bean>
                <bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
                    <property name="key" value="subsonic"/>
                </bean>
            </list>
        </property>
    </bean>


Add the following bean definitions:

Code: Select all
   <bean id="initialDirContextFactory"
      class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
      <constructor-arg
         value="ldap://domain.com.hostname:389/cn=Users,dc=domain,dc=com" />
      <property name="managerDn">
         <value>
            <!-- the DN of a user that is able to read data from LDAP -->
            <![CDATA[CN=LDAP,CN=Users,DC=domain,DC=com]]>
         </value>
      </property>
      <property name="managerPassword">
         <!-- the password of the DN set above -->
         <value>secretpassword</value>
      </property>
      <property name="extraEnvVars">
         <map>
            <entry>
               <key>
                  <value>java.naming.referral</value>
               </key>
               <value>follow</value>
            </entry>
         </map>
      </property>
   </bean>

   <bean id="activeDirectoryAuthenticationProvider"
      class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
      <constructor-arg>
         <ref local="bindAuthenticator" />
      </constructor-arg>
      <constructor-arg>
         <ref local="userDetailsServiceBasedAuthoritiesPopulator" />
      </constructor-arg>
   </bean>

   <bean id="bindAuthenticator"
      class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
      <constructor-arg>
         <ref local="initialDirContextFactory" />
      </constructor-arg>
      <property name="userSearch">
         <ref local="userSearch" />
      </property>
   </bean>

   <bean id="userDetailsServiceBasedAuthoritiesPopulator"
      class="net.sourceforge.subsonic.ldap.UserDetailsServiceBasedAuthoritiesPopulator">
      <property name="userDetailsService" ref="securityService"/>
   </bean>

   <bean id="userSearch"
      class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
      <constructor-arg>
         <value></value>
      </constructor-arg>
      <constructor-arg>
         <value>(sAMAccountName={0})</value>
      </constructor-arg>
      <constructor-arg>
         <ref local="initialDirContextFactory" />
      </constructor-arg>
      <property name="searchSubtree">
         <value>true</value>
      </property>
      <property name="derefLinkFlag">
         <value>true</value>
      </property>
   </bean>


In addition to these configuration settings a new class needs to be added to the WEB-INF classes directory compiled from this source:
Code: Select all
package net.sourceforge.subsonic.ldap;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.ldap.LdapDataAccessException;
import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;

/**
* An {@link LdapAuthoritiesPopulator} that retrieves the roles from the
* database using the {@link UserDetailsService} instead of retrieving the roles
* from LDAP. An instance of this class can be configured for the
* {@link org.acegisecurity.providers.ldap.LdapAuthenticationProvider} when
* authentication should be done using LDAP and authorization using the
* information stored in the database.
*
* @author Thomas M. Hofmann
*/
public class UserDetailsServiceBasedAuthoritiesPopulator implements
      LdapAuthoritiesPopulator {

   private UserDetailsService userDetailsService;

   public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails)
         throws LdapDataAccessException {
      return userDetailsService.loadUserByUsername(userDetails.getUsername())
            .getAuthorities();
   }

   public void setUserDetailsService(UserDetailsService userDetailsService) {
      this.userDetailsService = userDetailsService;
   }
}


When you make these changes you will need to make sure that the user is added both in AD and in subsonic. The roles / user rights are stilled defined in subsonic only. Only the password / credentials are taken from LDAP so that your users do not need to change there passwords at several places / applications.

Thomas
thofmann
 
Posts: 3
Joined: Mon Nov 26, 2007 8:42 am

Postby sindre_mehus » Wed Jan 02, 2008 12:55 pm

Hi Thomas,

Thanks for posting this! I'll consider adding LDAP support as part of the official release, but I need to fulfill the following requirements:

o It should be possible to enable/disable/edit LDAP settings dynamically from the web UI.
o It should be configurable on a per-user basis whether that user is authenticated by LDAP or by Subsonic's internal database.
o It should not be necessary to know the LDAP manager username/password.
o It should work with other LDAP servers, not only AD.

I'll have a look and see how difficult this would be.

Thanks again,
Sindre
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway

Postby sindre_mehus » Mon Jan 07, 2008 7:29 am

I'm happy to inform you that LDAP authentication has been implemented for the 3.4 release.

Sindre
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway

Postby Svenson » Mon Jan 21, 2008 12:55 am

Yehh, this is great news !

Will there be a beta version of 3.4 soon ?
I would really like to give it a try :)
Svenson
 
Posts: 6
Joined: Mon Oct 16, 2006 12:15 am

Postby mistaox » Fri Feb 01, 2008 9:45 pm

hmm...well this is half of what i expected....

LDAP auth seems pointless if it is still dependant on a local Subsonic user account.
Also, having to create identical user names between Subsonic and AD seems rather redundant.

This feature should allow for Users to be managed exclusively by AD and the roles should be handled by Subsonic.

Subsonic should be able to pull user names from a AD Security Group and allow the Subsonic Admin to create even more granular permissions within Subsonic.

So if I add user "jsmith" to my "Subsonic-Users" Security group, Subsonic should then allow me to specify what roles or permissions he should have.
mistaox
 
Posts: 54
Joined: Sat Dec 09, 2006 7:36 am

Postby sindre_mehus » Fri Feb 01, 2008 11:00 pm

mistaox wrote:This feature should allow for Users to be managed exclusively by AD and the roles should be handled by Subsonic.

It does.
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway

Postby mistaox » Mon Feb 04, 2008 3:32 pm

NOICE!!!
mistaox
 
Posts: 54
Joined: Sat Dec 09, 2006 7:36 am

Postby Svenson » Tue Apr 08, 2008 5:46 pm

Hi Sindre.
This is looking really good.

But the current LDAP lookup does not support BindDN and password.
And many LDAP / AD servers do not support anonymous bind.

Is it possible to give option to supply Bind user and password ?

Cheers !


ps . Here is an example of the error I get.

Code: Select all
[2008-04-03 13:39:31,850] INFO SubsonicLdapBindAuthenticator - Failed to authenticate user 'testuser' in LDAP.
org.acegisecurity.ldap.LdapDataAccessException: LdapCallback;[LDAP: error code 1 - 00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece]; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece]; remaining name ''
Caused by: javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece]; remaining name ''
Svenson
 
Posts: 6
Joined: Mon Oct 16, 2006 12:15 am

Postby sindre_mehus » Tue Apr 08, 2008 7:08 pm

Svenson,

Yeah, I'll add that in the next 3.4 release.

Thanks for pointing it out!
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway

Postby sindre_mehus » Wed Apr 09, 2008 12:13 pm

Can someone pls let me know if authentication in Active Directory works? I don't have an AD available for testing.

Cheers,
Sindre
User avatar
sindre_mehus
 
Posts: 1955
Joined: Tue Nov 29, 2005 6:19 pm
Location: Oslo, Norway

Postby Svenson » Wed Apr 09, 2008 3:09 pm

It is at least not working for me ;-)
See the error in previous post.
Svenson
 
Posts: 6
Joined: Mon Oct 16, 2006 12:15 am

Thank you it works with AD

Postby thofmann » Mon May 26, 2008 7:55 pm

Hi Sindre,

thanks a lot for integrating LDAP authentication. I had no problems with my AD.

Well, almost no problems.

If I try to authenticate through the WAP interface only without having a session the authentication fails.

If I log on to the normal UI and then switch to the WAP UI it works.

Regards,

Thomas
thofmann
 
Posts: 3
Joined: Mon Nov 26, 2007 8:42 am


Return to Feature Requests

Who is online

Users browsing this forum: No registered users and 5 guests