.. You may want to use the usual include line. Uncomment and adjust the path. .. include:: ../Includes.txt ============================== EXT: LDAP Server Configuration ============================== :Author: Kasper Skårhøj :Created: 2002-11-01T00:32:00 :Changed: 2005-11-01T14:15:38 :Author: Daniel Thomas :Email: dt@dpool.net :Info 3: :Info 4: .. _EXT-LDAP-Server-Configuration: EXT: LDAP Server Configuration ============================== Extension Key: **ldap\_server** Copyright 2000-2005, Daniel Thomas, This document is published under the Open Content License available from http://www.opencontent.org/opl.shtml The content of this document is related to TYPO3 \- a GNU/GPL CMS/Framework available from www.typo3.com .. _Table-of-Contents: Table of Contents ----------------- **EXT: LDAP Server Configuration 1** **Introduction 1** What does it do? 1 **Installation 1** **Administration 2** **Configuration 2** The LDAP server record 2 Reference for TS in the configuration field 4 **Tutorial 8** **Known problems 8** **To-Do list 8** **Changelog 9** .. _Introduction: Introduction ------------ .. _What-does-it-do: What does it do? ^^^^^^^^^^^^^^^^ This extension provides the backend interface for entering LDAP configuration data and the API used in extensions like ldap\_auth and ldap\_sync. The actual LDAP connectivity provided by the API is realised by using the LDAP connection object provided in tx\_ldaplib of the ldap\_lib extension. The idea of this extension is to provide an application and configuration interface for other extensions to perform LDAP-related tasks such as authenticating, searching, retrieving data, entering data into TYPO3 database tables. For example, in connection with the ldap\_auth, ldap\_sync and ldap\_sync\_cli extensions this extension gives you the opportunity to define all datamapping processes in conncection with authentification and use the same definition for synchronisation of user records from the LDAP directory into a user table through a backend module or a cronjob. Configuration for data mapping and application details is done in TypoScirpt syntax with a number of simple objects and directives. .. _Installation: Installation ------------ Just go to the extension manager, download the extension and install it. You must have the extension ldap\_lib installed. Figure 1 shows you the screen with which the extension manager asks to alter the database when installing the extension. You will have to create the tx\_ldapserver table which will contain records for LDAP server configuration. Additionally, the extension adds the field tx\_ldapserver\_dn to the tables fe\_users, fe\_groups, be\_users and be\_groups. These are not necessary yet they provide you with a separate field for synchronising the distinguished Name attribute of LDAP records going into these tables. |img-1| .. _Administration: Administration -------------- Access to database table records in the backend can be set standardconform in the access schemes for backend usergroups. Every standard TYPO3 installation of version 3.7.0 contains a module Help->Manual which contains information about how to administrate backend user rights. .. _Configuration: Configuration ------------- Please keep in mind that the configuration done in the LDAP server records does not do anything in itsself. With this configuration you govern the way applications work using them. .. _The-LDAP-server-record: The LDAP server record ^^^^^^^^^^^^^^^^^^^^^^ |img-2| .. ### BEGIN~OF~TABLE ### .. _Hide: Hide """" .. container:: table-row a Hide b With this you can enable or disable the LDAP server record for use. The ldap\_server extension allows you to enter more than one record in a give folder. The system will try to connect to the first LDAP record entry found on the page and use it if the connection is successful. If not it will try the next one ... and so forth. .. _Enable-for-backend: Enable for backend """""""""""""""""" .. container:: table-row a Enable for backend b **ONLY NECESSARY IF YOU WANT TO USE THE ldap\_auth service!!** If you check this this LDAP record can be used for authentification in the backend. Whether or not backend authentification against LDAP will happen depends on how the ldap\_auth service is configured. .. _Servername: Servername """""""""" .. container:: table-row a Servername b Here you type in the server address and the port under which your LDAP directory is found. .. _Servertype: Servertype """""""""" .. container:: table-row a Servertype b **ONLY NECESSARY IF YOU WANT TO USE THE ldap\_auth service!!** Currently, the service differentiates between Active Directory, NT server, Novell Directory and Open LDAP directory. Our system needs the information about the directory type because the differ fundamently in the username they expect for authentification. Some examples: ADS username@domain dpool@office.dpool.net NT server domain\username office.dpool.net\dpool NDS distinguished name dn=dpool, ou=users, dc=office, dc=dpool, dc=net Open LDAP distinguished name dn=dpool, ou=users, dc=office, dc=dpool, dc=net The first two servers need a combination of the domain within which the directory handles authentification and the username for authentification. The second two servers need the full LDAP root path for the user to be able to authenticate them. As we want a situation in which our user “dpool” wants to just his username “dpool” in the form to authenticate we need to give our system at least the additional information of what server type we want to connect to and – if the server be an ADS or NT machine – the domain the server handles. On the basis of that information the system makes sure that the username is given in the right format in order to check whether the given password is correct. .. _LDAP-protocol-version: LDAP protocol version """"""""""""""""""""" .. container:: table-row a LDAP protocol version b .. _BaseDN: BaseDN """""" .. container:: table-row a BaseDN b **ONLY NECESSARY IF YOU WANT TO USE THE ldap\_auth service!!** This defines a kind of enty point for every operation based on this LDAP server configuration. For example, only users which are located underneath this point in the LDAP tree of the server will be able to authenticate. .. _Filter-for-persons: Filter for persons """""""""""""""""" .. container:: table-row a Filter for persons b **ONLY NECESSARY IF YOU WANT TO USE THE ldap\_auth service!!** Every search in an LDAP directory is defined by a so-called filter. It is comparable to the WHERE part in an SQL statement. The example seen in the screenshot would result in a search for an LDAP entry which has “person” as value of the attribute “objectClass” and “###USERNAME###” as value of the attribute “samaccountname”. In finding a userrecord to authenticate against in the LDAP directory the auth service will take the string you provide in this field and replace the substring “###USERNAME###” with the username given by the user in the loginform. Staying with the above example the service would try to find a record where objectClass has the value “person” and samaccountname has the value “dpool”. Depending on the schema your LDAP server is using you will need to define the actual rule for identifying the user records here. The “###USERNAME###”-string however is obligatory. Otherwise, authentification will not work. .. _Charset: Charset """"""" .. container:: table-row a Charset b Define the charset used in the LDAP directory. The system uses the TYPO3 charset conversation classes. .. _Domain: Domain """""" .. container:: table-row a Domain b **ONLY NECESSARY IF YOU WANT TO USE THE ldap\_auth service!!** See above. Only necessary if servertype is ADS or NT .. _Username: Username """""""" .. container:: table-row a Username b This is a user in the LDAP directory who is able to bind to and search the part of the directory defined in BaseDN. .. _Password: Password """""""" .. container:: table-row a Password b Password of the default user. .. ###### END~OF~TABLE ###### .. _Reference-for-TS-in-the-configuration-field: Reference for TS in the configuration field ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _generated: ((generated)) """"""""""""" .. _LDAP-SYNC: LDAP\_SYNC ~~~~~~~~~~ .. ### BEGIN~OF~TABLE ### .. _enable: enable '''''' .. container:: table-row Property enable Data type boolean Description This enables the object for use. The ldap\_server class contains a API function which can be used by other applications to have a configuration array returned on the basis of a string input of TypoScript. The function will only return those TS objects which are enabled by this parameter. See tx\_ldap\_server->getConf Default 0 .. _table: table ''''' .. container:: table-row Property table Data type string Description Name of table for which the object should be used. As the LDAP\_SYNC object is not only used in authentification you can choose any TYPO3 database table as target for synchronisation. Default .. _basedn: basedn '''''' .. container:: table-row Property basedn Data type string Description Here you need to enter a path within your LDAP directory which delimits the area in which the LDAP\_SYNC object should search for records to transfer to the database table. Example: OU=munich, DC=office, DC=dpool, DC=net Default .. _handleNotFound: handleNotFound '''''''''''''' .. container:: table-row Property handleNotFound Data type boolean Description Basicly, the LDAP\_SYNC object is there to make sure that every record in the LDAP directory falling under a certain definition is also represented in the TYPO3 database table. This does not include any processing of records which are found only in TYPO3 but not (any longer) in the LDAP directory (i.e. users which have been imported once but have been deleted in the directory). That's what you use the handleNotFound option for. If you enable it you can finetune the way the system deals with records only found in TYPO3 by the following subdirectives: . **markHidden** : boolean. Sets value of field defined in .hiddenField to 1 . **hiddenField** : string. Fieldname of field with which to set a record to hidden . **markDeleted** : boolean Sets value of field defined in .deletedField to 1 . **deletedField** : string. Fieldname of field with which to set a record to deleted . **delete** : boolean. Deletes record from database . **identField** :string. Fieldname of an addtional database field you want to display in statistical output. Default 0 .. _pid: pid ''' .. container:: table-row Property pid Data type INT Description Defines the page UID on which the LDAP\_SYNC object should insert its records. **If you set this to 'root' the records will be entered in the rootline of your installation.** Default .. _filter: filter '''''' .. container:: table-row Property filter Data type string Description LDAP filter syntax. This defines which LDAP records should be synchronised with the directory. Default .. _uniqueField: uniqueField ''''''''''' .. container:: table-row Property uniqueField Data type string Description Name of database field. In order for synchronisation to work the LDAP\_SYNC object must be able to check whether a specific LDAP record already exists in the TYPO3 database. This is done by comparing the values of the field given in this directive with whatever value is got by the MAP\_OBJECT corresponding to that field. See below fot the MAP\_OBJECT. Default .. _fields: fields. ''''''' .. container:: table-row Property fields. Data type Array of ->MAP\_OBJECTS Description This part of the configuration holds a series of MAP\_OBJECTs each identifying a database table field. Default .. _requireGroupMemberShip: requireGroupMemberShip '''''''''''''''''''''' .. container:: table-row Property requireGroupMemberShip Data type Boolean Description If you set this parameter the system will only transfer records which have a valid entry in the “usergroup” - field. That's why you will probably only use this with the fe\_users or be\_users table. NOTICE: This will affect the functionality of the ldap\_auth service if you are usinig it. Default .. ###### END~OF~TABLE ###### .. _MAP-OBJECT: MAP\_OBJECT ~~~~~~~~~~~ Other than with content objects in standard TypoScript you are not free to choose any given name for your MAP\_OBJECTS. The name of the object must be a valid field name of the database table you want to sync to. **In order for the LDAP\_SYNC object to work you must at least provide one MAP\_OBJECT corresponding to the field defined in the uniqueField parameter.** Example: :: FEusers = LDAP_SYNC FEusers { .... uniqueField = username fields { username = MAP_OBJECT username { attribute = sAMAccountName } } ... } .. ### BEGIN~OF~TABLE ### .. _attribute: attribute ''''''''' .. container:: table-row Property attribute Data type string Description This defines the name of the LDAP attribute holding the value you want to insert into the field defined by the MAP\_OBJECT's name. Attribute names are case sensitive. Default .. _userFunc: userFunc '''''''' .. container:: table-row Property userFunc Data type string Description Here you define a function or class method which should process the current value of the LDAP attribute before submitting it to the database. The current value is submitted as first parameter to the function any properties of the userFunc directive are submitted as array into the second parameter of the function. See t3lib\_div::callUserFunction See tx\_ldap\_server::getSingleValue See tx\_ldap\_server::getDefaultValue See tx\_ldap\_server::getFEGroups See tx\_ldap\_server::getBEGroups The userFunc is necessary as the form in which the LDAP attribute usually holds its data does not allow us to transfer it directly to the database. An exmaple: In a standard Active Directory installation you will get the following result when you query the directory for a record's (say our dpool's) samaccountname: array( 'count' => '1', '0' => 'dpool' ) Other attibutes might have a different strukture. For example the 'memberOf' attribute: array( 'count' => '3', '0' => 'distinguished name of usergroup one' '1' => 'distinguished name of usergroup two' '2' => 'distinguished name of usergroup three' ) Obviously, you will need differing strategies to get data from these two sources. This is what happens in the respective userFunc parameters of the username and the usergroup object. The function ldap\_server->getSingleValue takes the first array as parameter $data and return the value $data[0]. The function ldap\_server->getFEGroups is slightly more complicated. It checks for every numerical key of the second array whether there is a fe\_groups entry in the database and – if so – sets the UID of such an entry in the groupmembership field of the fe\_user. NOTICE: The former parameter include is no longer supported. Please specify the class file directly in the userFunc parameter if you need to include a library. You can use standard TYPO3 file references. Default tx\_ldapserver->getSingleValue .. _special: special ''''''' .. container:: table-row Property special Data type string Description Right now there is only one possible value for the special directive: “DN” If you set this the system ignores any user functions or attribute definitions an inserts the distinguished name of the LDAP record into the field. Default .. _pid: pid ''' .. container:: table-row Property pid Data type INT Description Defines the page UID on which the LDAP\_SYNC object should insert its records. Default .. ###### END~OF~TABLE ###### .. _LDAP-AUTH: LDAP\_AUTH ~~~~~~~~~~ The LDAP\_AUTH object is needed by the ldap\_auth extension to configure backend or frontend authentification .. ### BEGIN~OF~TABLE ### .. _enable: enable '''''' .. container:: table-row Property enable Data type boolean Description This enables the object for use. The ldap\_server class contains a API function which can be used by other applications to have a configuration array returned on the basis of a string input of TypoScript. The function will only return those TS objects which are enabled by this parameter. See tx\_ldapserver->getConf Default 0 .. _table: table ''''' .. container:: table-row Property table Data type string Description Only fe\_users and be\_users as values will have any effect. Default .. _SSO: SSO ''' .. container:: table-row Property SSO Data type boolean Description This enables the possiblility of a single sign on scenario. The SSO directive has the a numerical array of subobjects as parameters which have the following parameters: 10.userFunc 20.userFunc ... with which you define the function or method which should handle the single sign on and are able to include a resource if needed. Please see the section **Single Sign On** below for details. Default 0 .. _sync: sync '''' .. container:: table-row Property sync Data type ->LDAP\_SYNC Description The directive sync must be a valid LDAP\_SYNC object. Default .. ###### END~OF~TABLE ###### .. _An-example: An example """""""""" Have a look at the following example which provides configuration for frontend and backend user configuration for data synchronisation and authentification. :: FEusers = LDAP_SYNC FEusers { enable = 1 table = fe_users basedn = OU=globalcorp, DC=office, DC=dpool, DC=net handleNotFound = 1 handleNotFound { markHidden = 1 hiddenField = disable markDeleted = 0 deletedField = deleted delete = 0 identField = username } pid = 11 filter = (&(objectClass=person)) uniqueField = tx_ldapserver_dn fields { username = MAP_OBJECT username.attribute = sAMAccountName username.userFunc = tx_ldapserver->getSingleValue tx_ldapserver_dn = MAP_OBJECT tx_ldapserver_dn.special = DN usergroup = MAP_OBJECT usergroup { attribute = memberOf userFunc = tx_ldapserver->getFEGroups userFunc.pid = 11 } } } FEgroups < FEusers FEgroups { table = fe_groups handleNotFound = 0 filter = (&(objectClass=group)) fields { username > usergroup > title = MAP_OBJECT title.attribute = cn title.userFunc = tx_ldapserver->getSingleValue } } BEusers < FEusers BEusers { table = be_users pid = root handleNotFound = 0 filter = (&(objectClass=person)(description=BE_USER)) fields.usergroup.userFunc = tx_ldapserver->getBEGroups } BEgroups < FEgroups BEgroups { table = be_groups pid = root filter = (&(objectClass=group)(description=BE_GROUP)) } FEauth = LDAP_AUTH FEauth { enable = 1 table = fe_users SSO = 1 SSO.10.userFunc = tx_ldapauth_sv1->authFromGet sync < FEusers } BEauth < FEauth BEauth { table = be_users sync < BEusers } .. _Single-Sign-On-SSO: Single-Sign-On (SSO) ~~~~~~~~~~~~~~~~~~~~ Often the application context in which authentification against a LDAP directory is needed is one where so-called Single-Sign-On functionality is wanted as well – in an intranet for example. The connection of TYPO3 to a LDAP user directory for authentification is usually driven by a wish for having a single source where user data like passwords etc.. are being kept. A single source strategy does not entail a single-sign-on strategy. It just means that different systems (i.e. a workstation, TYPO3, ...) authenticate against the same source. SSO takes the thing one step further by trying to let one system participate in the actual login the user has done in the context of another system to spare her or him another loginform. For a webapplication like TYPO3 this typically means that it tries to participate in the login the user has done on the workstation he or she is accessing the webapplication from. Of course, there are certain limitation to that participation. A PHP application – or any other application for that part – can not just ask the workstation for the username and password the user has entered ealier and use that to authenticate the user once more. There should be no way for the webapplication to get the password. However, depending on the context there are numerous ways for the webapplication to gain access to the username under which the user has done a successful login on the machine. If the webapplication is provided with a username from a trusted source it can then go on to instantiate a user session for that username under the assumption that this user is already authenticated. Let's have a look at some scenarios: **Active Directory** Prerequisites: - Apache 1.3 with Kerberos module integrated into ADS Kerberos environment - Internet Explorer as agent with special intranet security settings Result: The Apache Kerberos module sets the PHP variable $\_SERVER['REMOTE\_USER'] with the login username of the user authenticated on the requesting workstation. **NetBios** There are simple libraries for PHP which are able to retrieve the username of the active login on a workstation if the NetBios protocol is enabled. **Novell eDirectory** Some versions of the Novell eDirectory save the IP of a user's workstation with the user record within the LDAP directory. It is therefore possible to write a function which queries the LDAP directory for the IP and retrieve the username on this basis. All three scenarios have the result for the webapplication wanting to implement SSO functionality. They provide the webapplication with a way to access the username. In the context ot the authentification service this leads us to the following requirement for the service application: - The service must be active even if there is no username or password given - There must be a way to “ask” trusted sources for a username. - As there are many possible ways to get to a username the system must provide a simple API for various methods of username retrieval. - There must at least be two ways of authenticating a username. With password and without password. **How are these requirements met by the ldap\_auth – ldap\_server application system?** The ldap\_auth extension gives you the possibility to configure the authentification mother class to always include authentification services if there is no valid user session found. Please have a look at the documentation of auth services found in the extension cc\_sv\_auth for details and the extension ldap\_auth for a working example. This means that the service is included even if there is no username and password explicitly given through form input. The configuration of the LDAP\_AUTH object provides you with an interface to define your custom functions or class methods for retrieving a username. Use the LDAP\_AUTH parameter SSO for this purpose. SSO can contain a numerical array which holds one or more definitions for functions which should retrieve username data. Example: :: SSO = 1 SSO.10.userFunc = PATH_TO_FILE:CLASSNAME->METHODNAME SSO.20.userFunc = PATH_TO_OTHER_FILE:OTHER_CLASSNAME->OTHER_METHODNAME What you do inside your method is of no importance to the authentification service. The method could just be an interface for an elaborate external application reinventing the wheel – it really does not matter. What matters though, is that the methods returns an array as seen below : :: array ( 'username' => 'THE USERNAME YOUR METHODS HAVE FOUND', 'authenticated' => '1' ) Of course, your application should only return this array if it is sure that whatever username was found is thoroughly authenticated. The only other requirement for the service being able to instantiate a user session for under this username is that this username is actually found in the LDAP directory. .. _Tutorial: Tutorial -------- .. _Known-problems: Known problems -------------- .. _To-Do-list: To-Do list ---------- .. _Changelog: Changelog --------- .. ### BEGIN~OF~TABLE ### .. _0-0-1: 0.0.1 ^^^^^ .. container:: table-row a 0.0.1 b Beta version given to developers for testing .. _0-1-0: 0.1.0 ^^^^^ .. container:: table-row a 0.1.0 b First public version .. _0-2-0: 0.2.0 ^^^^^ .. container:: table-row a 0.2.0 b The tx\_ldapserver class now provides a global Object which handles all operations with the ldap server. There have been some changes to the TCA. Type field Servertype, Password field password. The class tslib\_cObj is now called via the Extension Manager API, which eliminates the problems some people had with differing paths in the FE and BE. At one place in the code and several places in the documentation it said ldap\_server instead of tx\_ldapserver for the class name, which made some people freak out. Sorry for that. Changes made. .. _0-2-1: 0.2.1 ^^^^^ .. container:: table-row a 0.2.1 b - Added utitlity function tx\_ldapserver->getDefaultValue. - Added parameter requireGroupMemberShip for the LDAP\_SYNC object. With that you can disable login and synchronisation for records which have no groupmembership. - Added utitlity functions tx\_ldapserver->getStaticGroups and tx\_ldapserver->getDynamicGroups to accommodate for the most common groupmembership-models. - Changed all misconceived calls to tslib\_content::callUserFunction to t3lib\_div::callUserFunction. Please note the you can no longer use the include parameter in MAP\_OBJECTS. You must specify a class file in the userFunc parameter. .. _Unknown-Property: ((Unknown Property)) ^^^^^^^^^^^^^^^^^^^^ .. container:: table-row a b .. ###### END~OF~TABLE ###### |img-3| EXT: LDAP Server Configuration - 10 .. ######CUTTER_MARK_IMAGES###### .. |img-1| image:: img-1.png .. :align: left .. :border: 0 .. :height: 407 .. :id: Grafik2 .. :name: Grafik2 .. :width: 348 .. |img-2| image:: img-2.png .. :align: left .. :border: 0 .. :height: 557 .. :id: Grafik1 .. :name: Grafik1 .. :width: 423 .. |img-3| image:: img-3.png .. :align: left .. :border: 0 .. :height: 32 .. :id: Graphic1 .. :name: Graphic1 .. :width: 102