Solved business problem / scope
Web developers regularly receive orders for the creation of corporate portals. Portals in this case are internal sites of enterprises that provide information and services for their own employees and the closest partners.
The overwhelming majority of large enterprises are already actively using unified authorization based on directory services accessed via the
Lightweight Directory Access Protocol (LDAP) .
It is quite natural that customers are interested in integrating the portal being developed 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 series of boxed products of the Information Management System class, developers nevertheless have to solve various technical and organizational issues.
Brief description of the project
The project, which was implemented by our company in early 2008, is a functionally rich corporate information portal of the holding, which includes several geographically distributed companies. The holding divisions are mostly united by the
Microsoft Active Directory (AD) directory service.
')
Platform for project implementation: Linux, Apache, PHP, MySQL,
Cetera CMSThe main reasons for using AD-based authorization in this project are:
- Providing a single user management center (actually, AD) for the company's system administrators.
- Simplifying access to the portal for company employees, for whom the need to enter an extra password could be critical to start using the portal.
- A large number of company employees (several thousand people), which makes it almost impossible to enter a list of employees in the portal database and allocate staff for companies and departments and a telephone directory implemented within the portal.
Used technologies
The two main tasks are to import data from AD and further authorize users who view portal pages.
Data import from AD is done through LDAP. LDAP allows access to domain information — a list of users, groups, domain computers, etc.
User
authentication is done using Apache tools, or rather, his
mod_ntlm module (available for Apache versions 1.3.x, for 2.2.x the mod_auth_sspi module is used). Mod_ntlm authorizes the user at the stage of accessing the page, and if the user is authenticated, his data (domain and user names) are transmitted in server variables (for PHP it is $ _SERVER)
AD fields description
As part of this project, it was required to obtain the following user information from AD:
- full name (last name, first name)
- Domain name
- email
- position
- belonging to a company / department (relative to the customer’s corporate structure)
The username 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.
Employee import
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.
in the following way:
“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 Name Attribute = value. At the same directory level, two entries with the same relative unique names cannot exist. Because of this structure, the name of an entry in an LDAP directory can easily be represented as a tree.
To search 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 consisting of listing attribute names of the record and their values ​​in the format Name Attribute = Value.
Suppose you want to import employees of the COMPANY.RU domain. For this, the search path will be, for example:
cn = Users, dc = COMPANY, dc = RU
cn = Users indicates a so-called. container called Users.
When performing such a search without additional filtering, other elements besides the users themselves may be present in the results. For example, data about groups. To get only user data in the search results, we will 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.
Such a path implies that account data is located in the Organizational Unit called Users-and-computers.
During the import process, it may be necessary to determine the activity of a user account. When importing, the
UserAccountControl account attribute may be interesting, in which various properties of the account are stored in binary form. An interesting feature might be
ACCOUNTDISABLE (0x0002) . If this flag is set in the UserAccountControl attribute, the account is considered blocked.
To search for all active users you will 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 are 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 is not present in the UserAccountControl attribute (0x0002)
Sample PHP Code
<?
/**
* 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";
}
?>
Additional information on working with LDAP in PHP can be found in the
documentation.Problems and Solutions
The lack of employee information in the directory service that is sufficient for displaying on the portal (full names, email addresses, division names, hobbies, corporate social network fields, etc.).
Almost always, the directory service does not contain all the information necessary for the operation of the portal. There may be no “banal” data, for example, a phone number, or information that is typical for a directory service such as “list of places of previous work for the needs of a corporate social network”. At the same time the need for this data for the portal is difficult to underestimate.
Our solution is to store accounts in the directory service, and extended information - in the open database of the portal. It is assumed that the list and user roles are managed in the directory service, and everything else is portal tasks.
The disadvantage of the solution is the need to link and synchronize the lists of users in the directory service and in the portal database.
Key benefits:
- enabling users to independently supplement information about themselves in the portal database with subsequent moderated uploading of this information to the directory service;
- the ability to quickly customize the set of fields in the portal user profile without affecting the directory service.
Lack of reliable information in the directory service on the employee’s belonging to a particular holding company or department
The de facto standard for corporate portals is to display a tree of holding companies and departments with automatic linkage to employees. At the same time, often in the directory service, employees are stored in a single flat list indicating the companies and departments in any properties of the directory service users.
Our solution:
- Create a tree of companies and departments on the portal using the content management system tools, using data on the organizational structure provided by the customer.
- Import employees from the directory service with verification of the names of the elements of the tree entered into the portal database with the contents of the directory service users cards.
- Users for whom it was not possible to determine the position in the tree could be imported into a temporary directory.
- As a result of the import, display the protocol with notification of the portal administrators and the directory service about the import deficiencies and poor-quality entries in the directory service.