Integration with directory services when developing enterprise portals on the LAMP platform
Solved business task / scope
Web developers with enviable regularity receive orders for the creation of corporate portals. Portals in this case are understood as internal sites of enterprises that provide information and services for their own employees and closest partners.
The vast majority of large enterprises are already actively using a single authorization based on directory services accessed through the Lightweight Directory Access Protocol (LDAP) .
It is natural that customers are interested in integrating the portal under development with directory services, and it is beneficial for developers to use an external authorization system in terms of reducing the amount of work in the project. And although integration with directory services is built into a number of boxed products of the “Information Management System” class, developers nevertheless have to solve various technical and organizational issues.
Brief Project Description
The project, which was implemented by our company at the beginning of 2008, is a functionally rich corporate information portal of the holding, which includes several geographically distributed companies. The divisions of the holding are mostly integrated by the Microsoft Active Directory (AD) directory service .
Platform for implementing the project: Linux, Apache, PHP, MySQL, Cetera CMS
The main reasons for using authorization based on AD in this project:
- Providing a single user management center (actually AD) for the company's system administrators.
- Simplification of access to the portal of company employees, for whom the need to enter an extra password could become critical to start using the portal.
- A large number of company employees (several thousand people), which makes it almost impossible to enter the list of employees in the portal database and distribute personnel in the tree of companies and departments and the telephone directory implemented within the portal.
Used technologies
Two main tasks are importing data from AD and further authorizing users browsing portal pages.
Data is imported from AD through LDAP. LDAP allows you to access domain information - a list of users, groups, domain computers, etc.
User authorization is performed using Apache, or rather its mod_ntlm module (available for versions Apache 1.3.x, for 2.2.x the module mod_auth_sspi is used). Mod_ntlm authorizes the user at the stage of accessing the page, and if the user is authorized, his data (domain and user names) are transferred in the server variables (for PHP this is $ _SERVER)
Description of AD fields
As part of this project, it was required to obtain the following user information from AD:
- full name (last name, first name, patronymic)
- Domain name
- position
- affiliation to the company / department (regarding the corporate structure of the customer)
The user name in the domain (his login) is stored in the SAMAccountName field. Title, Department and Company describe the position, department and company. Email is stored in the Mail field, the full username is in the Name field.
Import Employees
Each entry in the LDAP directory consists of one or more attributes and has a unique name (DN - English Distinguished Name). The name may look, for example, as
follows:
"Cn = Ivan Petrov, ou = Employees, dc = example, dc = com."
A unique name consists of one or more relative unique names (RDN - English Relative Distinguished Name), separated by a comma. The relative unique name has the form AttributeName = value. At one directory level, two entries with the same relative unique names cannot exist. Due to this structure, the name of an entry in an LDAP directory can easily be represented as a tree.
To perform a search on the directory service structure, you must specify the path to the root element, relative to which the search will be performed. You can also specify a filter that consists of listing the names of the attributes of the record and their values in the format AttributeName = Value.
Suppose that you want to import company.RU domain employees. For this, the search path will be, for example, like this:
cn = Users, dc = COMPANY, dc = RU
cn = Users points to the so-called a container called Users.
When performing such a search without additional filtering, the results may contain other elements besides the users themselves. For example, data about groups. To get only user data in the search results, specify a filter:
ObjectCategory = Person.
In some cases, users in AD may be located in the so-called. Organizational Units. In this case, use the search path:
ou = Users-and-computers, dc = COMPANY, dc = RU.
This path implies that account information is located in the Organizational Unit called Users-and-computers.
During the import process, you may need to determine the activity of the user account. When importing , the UserAccountControl account attribute may be of interest , in which various account properties are stored in binary form. The sign ACCOUNTDISABLE (0x0002) may be interesting . If this flag is set in the UserAccountControl attribute, the account is considered blocked.
To search for all active users, you need to modify the filter. It will be like this:
(& (objectcategory = Person) (! (UserAccountControl: 1.2.840.113556.1.4.804: = 2)))
1.2.840.113556.1.4.804 - the so-called OID (Object IDentifier), this OID is used to select objects whose selected attribute contains either all or any of the bits specified in the filter. The above OID recognizes a match if any of the specified bits is present in the attribute. 2 is the value of the ACCOUNTDISABLE flag. This entire filter can be decrypted as follows: The objectcategory attribute is Person and bit 2 (0x0002) is not present in the UserAccountControl attribute.
Example PHP code Additional information on working with LDAP in PHP can be obtained in the documentation
/**
* Данный код подключается к AD и получает список всех незаблокированных сотрудников
* контейнера Users из домена СOMPANY.RU
* Выводится имя сотрудника, его email, компания, отдел и должность в соответствии с данными,
* полученными из AD
*/
$ds=ldap_connect("1.2.3.4");
if ($ds) {
$r=ldap_bind($ds,'COMPANY\\admin','adminPassword');
$sr=ldap_search($ds,
"cn=Users, dc=COMPANY, dc=RU",
'(&(objectcategory=Person)(!(UserAccountControl:1.2.840.113556.1.4.804:=2)))');
echo "Number of entires returned is " . ldap_count_entries($ds, $sr) . "
";
$info = ldap_get_entries($ds, $sr);
// $info содержит результаты запроса...
for ($i=0; $i<$info["count"]; $i++) {
echo "Name: {$info[$i]['name'][0]}
\n";
echo "Email: {$info[$i]['mail'][0]}
\n";
echo "Company: {$info[$i]['company'][0]}
\n";
echo "Department: {$info[$i]['department'][0]}
\n";
echo "Title: {$info[$i]['title'][0]}
\n";
}
ldap_close($ds);
} else {
echo "Unable to connect to LDAP server";
}
?>
Problems and Solutions
The lack of information about the employees in the directory service that is sufficient for displaying on the portal (full names, Email addresses, unit names, hobbies, fields of the corporate social network, etc.).
Almost always, the directory service does not contain all the information necessary for the operation of the portal. Both “trivial” data, for example, phone number, and information atypical for a directory service such as “a list of previous work places for the needs of a corporate social network” may be missing. Moreover, the need for this data for the portal is difficult to underestimate.
Our solution to the problem is to store accounts in a directory service, and extended information in an open portal database. It is assumed that the list and user roles are managed in the directory service, and everything else is the portal’s tasks.
The disadvantage of this solution is the need to link and synchronize user lists in the directory service and in the portal database.
The most important advantages:
- providing users with the opportunity to independently supplement information about themselves in the portal database with the subsequent moderated loading of this information into the directory service;
- the ability to quickly configure a set of fields in the portal user profile without affecting the operation of the directory service.
Lack of reliable information about the employee’s affiliation with a particular holding company or department in the directory service
The de facto standard for corporate portals is to display the tree of holding companies and departments with automatic binding to the employees tree. Moreover, often in the directory service, employees are stored in a single flat list indicating the companies and departments in any properties of users of the directory service.
Our solution:
- Create a tree of companies and departments on the portal using the content management system using data on the organizational structure provided by the customer.
- Import employees from the directory service with a reconciliation of the names of tree elements wound up in the portal database with the contents of the cards of the directory service users.
- Users for whom it was not possible to determine the position in the tree should be imported into a temporary directory.
- Based on the results of the import, display the protocol with the notification of the portal and directory service administrators about import deficiencies and poor-quality entries in the directory service.