Разобрался с работой с AD из PHP… – Моя работа – понимать… — ЖЖ

Browser

Your browser needs to be setup to forward authentication info to the Webserver.

Firewall adjustments

If you intend to work with a directory server residing outside of your local network, some firewall adjustments may be required. By default, LDAP connections take place over port 389; if your directory server supports secure connections (LDAPS), you’ll need to open port 636. Therefore, you’ll need to adjust your firewall to allow for access via at least these two ports, if not already enabled.

Key php functions

The first four functions introduced in this section are practically omnipresent whenever communicating with LDAP via PHP. These functions include ldap_connect(), ldap_set_option(), ldap_bind(), and ldap_unbind(), and they’re responsible for connecting, setting configuration parameters, binding to, and closing the directory server connection. Each is introduced in this section.

Ldap_bind()

boolean ldap_bind(resource link_id [, string bind_rdn [, string bind_pswd]])

Entering a restricted area doesn’t imply that you have free reign over its secrets. Exactly what material you can access, and whether you can add, modify, or destroy the contents is dependent upon your furnishable credentials. Directory Services’ security model is based on the same concept.

Ldap_connect()

resource ldap_connect([string hostname [, integer port]])

Prior to doing anything with an LDAP server, a connection must be established. You can do so with ldap_connect(), passing in an optional hostname and port if the connection isn’t local. An example follows:

Ldap_delete()

boolean ldap_delete(resource link_id, string dn)

Ldap_mod_add()

boolean ldap_mod_add(resource link_id, string dn, array entry)

Adding entries to the directory server is accomplished via the ldap_mod_add() function. A new entry is added simply by creating an array consisting of the attribute/value mappings intended to comprise the new row. This process is perhaps best explained with an example:

Ldap_mod_replace()

boolean ldap_mod_replace(resource link_id, string dn, array entry)

Ldap_search()

resource ldap_search ( resource link_identifier, string base_dn, string filter [, array attributes [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])

The ldap_search() function offers a powerful means for searching the directory server pointed to by link_identifier. It will search to a depth of LDAP_SCOPE_SUBTREE, a value that can be set via the previously introduced function ldap_set_option(). By default, this value is set to search to an infinite depth, or through the entire scope of the tree as defined by the base_dn.

The search filter, equivalent to a relational database query, is passed in via the filter parameter. Finally, you can specify exactly which attributes should be returned within the search results via the attributes parameter. The remaining four parameters are optional, and therefore in the interests of space, I’ll leave it as an exercise to you to learn more about them. Let’s consider an example:

Ldap_set_option()

boolean ldap_set_option(resource link_id, int option, mixed newval)

Unlike Perl, PHP’s LDAP connection function does not offer a means for declaring the intended protocol version within the connection function. Therefore, after successfully establishing a connection, you’ll likely need to declare this version by setting PHP’s constant LDAP_OPT_PROTOCOL_VERSION.

Ldap_unbind()

boolean ldap_unbind(resource link_id)

Once all directory server-specific tasks have been completed, the connection should be closed. This is accomplished by using the ldap_unbind() function. An example follows:

Php configuration

PHP’s LDAP support is not enabled by default. If you haven’t already done so, you’ll have to rebuild PHP, this time including the LDAP extension. This is done by passing the—with-ldap flag during the configuration phase of the build process.

%>./configure --with-ldap [OTHER OPTIONS]

If you’re building PHP as a shared module, remember that you won’t need to rebuild Apache after making these changes! If you don’t know what I’m talking about, and are wondering how such a convenience could be afforded to you, see the PHP manual for complete installation and configuration instructions.

Php: ldap_connect – manual

To be able to make modifications to Active Directory via the LDAP connector you must bind to the LDAP service over SSL. Otherwise Active Directory provides a mostly readonly connection. You cannot add objects or modify certain properties without LDAPS, e.g. passwords can only be changed using LDAPS connections to Active Directory.

Therefore, for those wishing to securely connect to Active Directory, from a Unix host using PHP OpenLDAP OpenSSL I spent some time getting this going myself, and came across a few gotcha’s. Hope this proves fruitfull for others like me when you couldn’t find answers out there.

Make sure you compile OpenLDAP with OpenSSL support, and that you compile PHP with OpenLDAP and OpenSSL.

This provides PHP with what it needs to make use of ldaps:// connections.

Configure OpenSSL:

Extract your Root CA certificate from Active Directory, this is achived through the use of Certificate Services, a startard component of Windows 2000 Server, but may not be installed by default, (The usual Add/Remove Software method will work here). I extracted this in Base64 not DER format.

Place the extracted CAcert into the certs folder for openssl. (e.g. /usr/local/ssl/certs) and setup the hashed symlinks. This is easily done by simply running:

  /usr/local/ssl/bin/c_rehash

Once this is done you can test it is worked by running:

  /usr/local/ssl/bin/openssl verify -verbose -CApath /usr/local/ssl/certs /tmp/exported_cacert.pem

(Should return: OK).

Configure OpenLDAP:

Add the following to your ldap.conf file.

(found as /usr/local/openldap/etc/openldap/ldap.conf)

  #–begin–

  # Instruct client to NOT request a server’s cert.

#

# WARNING: This will open up the server vor Man-in-the-middle

# attacs and should *not* be used on production systems or outside

# of test-scenarios!

#

# If you use this setting you will not need any other settings as

# no certificate is requested and therefore will not be validated

#

# For a proper solution check out https://andreas.heigl.org/2020/01/31/handle-self-signed-certificates-with-phps-ldap-extension/
TLS_REQCERT never

  # Define location of CA Cert

TLS_CACERT /usr/local/ssl/certs/AD_CA_CERT.pem

TLS_CACERTDIR /usr/local/ssl/certs

  #–end–

You also need to place those same settings in a file within the Apache Web user homedir called .ldaprc

  e.g.:

cp /usr/local/openldap/etc/openldap/ldap.conf ~www/.ldaprc )

You can then test that you’re able to establish a LDAPS connection to Active Directory from the OpenLDAP command tools:

  /usr/local/openldap/bin/ldapsearch -H “ldaps://adserver.ad.com”

This should return some output in extended LDIF format and will indicate no matching objects, but it proves the connection works.

The name of the server you’re connecting to is important. If they server name you specify in the “ldaps://” URI does not match the name of the server in it’s certificate, it will complain like so:

  ldap_bind: Can’t contact LDAP server (81)

additional info: TLS: hostname does not match CN in peer certificate

Once you’ve gotten the ldapsearch tool working correctly PHP should work also.

One important gotcha however is that the Web user must be able to locate it’s HOME folder. You must check that Apache is providing a HOME variable set to the Web users home directory, so that php can locate the .ldaprc file and the settings contained within. This may well be different between Unix variants but it is such a simple and stupid thing if you miss it and it causes you grief. Simply use a SetEnv directive in Apache’s httpd.conf:

  SetEnv HOME /usr/local/www

With all that done, you can now code up a simple connect function:

  function connect_AD()

{

$ldap_server = “ldaps://adserver.ad.com” ;

$ldap_user   = “CN=web service account,OU=Service Accounts,DC=ad,DC=com” ;

$ldap_pass   = “password” ;

    $ad = ldap_connect($ldap_server) ;

ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3) ;

$bound = ldap_bind($ad, $ldap_user, $ldap_pass);

    return $ad ;

}

Optionally you can avoid the URI style server string and use something like ldap_connect(“adserver.ad.com”, 636) ;  But work fine with Active Directory servers.

Hope this proves usefull.

Prerequisites

Prior to executing any of the examples offered in this article, you’ll need to make sure that a few prerequisite tasks are accomplished. Each of these tasks are outlined in this section.

Searching active directory via the web

I always like to round out a tutorial with an applicable example that readers can immediately adapt to their own needs. In this tutorial, I’ll show you how to create a search interface capable of searching by name, location, or phone number. All you’ll need to do is modify the connection variables and base DN. To begin, let’s create the search interface, which will be saved as “search.html”:

Figure 1 offers an example of what this search form would look like in the browser.

Figure 1. The Active Directory Search Form

Next, we’ll need to create the logic that effects the search. This short bit of code is shown here:

Searching and manipulating active directory data

In this section, you’ll learn how to search and retrieve data from the directory server, as well as add, modify, and delete entries.

Как работает ldap авторизация на php?

Здравствуйте !

Я начинающий разработчик на php. Недавно столкнулся с технологией ldap , о котором , кстати, я ничего не знал. Поискав в интернете инфу и применив те коды , понял что я окончательно запутался. Вот один из примеров. Тестовый сервер на windows 7, на сайт захожу набрав на браузере testsuper

ФАЙЛ ldap.php

<?php
$ldaphost = "127.0.0.1";
$ldapport = "389";
$memberof = "cn=allow_ppl,ou=users_IT,ou=IT,ou=Kyiv,ou=corp,dc=eddnet,dc=org";
$base = "ou=corp,dc=eddnet,dc=org";
$filter = "sAMAccountName=";
$domain = "@testsuper";
?>

ФАЙЛ index.php
=============

<?php

include_once ("auth.php");
?>
 
  
<head>
<meta charset=utf8 />
<title>Postfix ?????????</title>
</head>
 
<?php
// ????? ??? ????? ?????? ? ?????? 
print '
<form action="index.php" method="post">
<table>
      <tr>
            <td>Log:</td>
            <td><input type="text" name="login" /></td>
      </tr>
      <tr>
            <td>Password:</td>
            <td><input type="password" name="password" /></td>
      </tr>
      <tr>
            <td></td>
            <td><input type="submit" value="Authorization" /></td>
      </tr>
</table>
</form>
';
?>

=============

ФАЙЛ auth.php

<?php
//???????? ??????
session_start();
//?????????? ???????????????? ????
include_once ("ldap.php");
 
// Logout
if (isset($_GET['logout']))
{
      if (isset($_SESSION['user_id']))
            {
            unset($_SESSION['user_id']);  
            setcookie('login', '', 0, "/");
            setcookie('password', '', 0, "/");
            header('Location: index.php');
            exit;
      }
}
 
//???? ???????????? ??? ????????????????, ?? ??????????? ??? ?? ???????? main.php
if (isset($_SESSION['user_id']))
      {
	  echo "<script>alert('Success')</script>";
      header('Location: main.php');
      exit;
}
 
//???? ???????????? ?? ????????????????, ?? ????????? ??? ????????? LDAP
if (isset($_POST['login']) && isset($_POST['password']))
      {
      $username = $_POST['login'];
      $login = $_POST['login'].$domain;
      $password = $_POST['password'];
      //?????????????? ? LDAP ???????
      $ldap = ldap_connect($ldaphost,$ldapport) or die("Cant connect to LDAP Server");
      //???????? LDAP ???????? ?????? 3
      ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
 
      if ($ldap)
            {
            // ???????? ????? ? LDAP ??? ?????? ????????? ?????? ? ??????
            $bind = ldap_bind($ldap,$login,$password);
 
            if ($bind)
                  {
                  // ????????, ???????? ?? ???????????? ?????? ????????? ??????.
                  $result = ldap_search($ldap,$base,"(&(memberOf=".$memberof.")(".$filter.$username."))");
                  // ???????? ?????????? ??????????? ?????????? ????????
                  $result_ent = ldap_get_entries($ldap,$result);
            }
            else
                  {
				  echo "<pre>";
				  print_r($_SESSION);
				  echo "</pre>";
                  die('You entered wrong password or id. Try it now<br /> <a href="index.php">to back</a>');
            }
      }
      // ???? ???????????? ??????, ?? ?????????? ??? ?????? ? ????????????? ?? main.php
      if ($result_ent['count'] != 0)
            {
            $_SESSION['user_id'] = $login;
            header('Location: main.php');
            exit;
      }
      else
            {
            die('Access denied! <br /> <a href="index.php">to Back</a>');
      }
}
?>

Меня волнует следующие вопросы:
1) как работает ldap?
2) где оно то есть ldap хранит данные и вообще как проводится авторизация если до этого никаких юзеров не было? (это самое интересное так как я выводил и $_SERVER и.т.п)
3) что мне прочитать чтобы побыстрее вникнуть в ldap?
4) не проще ли хранить данные в БД и проверять данные оттуда(то есть login pass)?

С Уважением,
Алмик

Настройка

Во избежании потери данных при перезаписи их менеджером настройки рекомендуется все настройки производить в файле conf/local.protected.php.

Возможно потребуется установить как минимум следующие опции:

<?php// общие настройки DokuWiki$conf['useacl']=1;$conf['disableactions']='register';$conf['authtype']='ad';
 
  // настройки Active Directory$conf['auth']['ad']['account_suffix']='@my.domain.org';$conf['auth']['ad']['base_dn']='DC=my,DC=domain,DC=org';$conf['auth']['ad']['domain_controllers']='srv1.domain.org, srv2.domain.org';//через запятую можно перечислить //несколько контроллеров домена

Можно указать дополнительные параметры:

$conf['auth']['ad']['ad_username']='root';$conf['auth']['ad']['ad_password']='pass';$conf['auth']['ad']['sso']=1;$conf['auth']['ad']['real_primarygroup']=1;$conf['auth']['ad']['use_ssl']=1;$conf['auth']['ad']['use_tls']=1;$conf['auth']['ad']['debug']=1;$conf['auth']['ad']['recursive_groups']=1;// Если в AD содержится много групп, переключение этого параметра // в 0 улучшит скорость работы, но неявное членство в группах перестанет работать

ad_username и ad_password необходимы для реализации подписки на изменения. Этот аккаунт используется для запроса информации о пользователе из AD.

Для установки прав суперпользователя можно использовать следующую конструкцию:

$conf['manager']='@LDAPGROUPNAME';$conf['superuser']='@LDAPGROUPNAME';

Любые другие настройки, указанные в $conf[‘auth’][‘ad’], напрямую передаются в библиотеку adldap. Детальное описание этих настроек можно получить в документации по adLDAP.

В комбинации с аутентификацией Single-Sign-On также можно добавить настройки домена Windows. То есть проводить аутентификацию на разных AD в зависимости от домена NTLM или Kerberos конкретного пользователя. Для этого надо использовать название домена (в нижнем регистре) как подключ в $conf['auth']['ad']. Т.е. для того, чтобы идентифицировать всех пользователей, пришедших из домена Windows Foobar через сервер AD, отличный от сервера по умолчанию, нужно добавить следующие строчки в конфигурационный файл:

$conf['auth']['ad']['foobar']['account_suffix']='@foobar.domain.org';$conf['auth']['ad']['foobar']['base_dn']='DC=foobar,DC=domain,DC=org';$conf['auth']['ad']['foobar']['domain_controllers']='otherad.domain.org';$conf['auth']['ad']['foobar']['ad_username']='otherroot';$conf['auth']['ad']['foobar']['ad_password']='otherpass';

Если в организации используется система из нескольких контроллеров домена с единым родительским контроллером, может потребоваться указать порт 3268, вместо порта по умолчанию 389. В противном случае DokuWiki может не получить информации о группах пользователей дочернего домена. Самый простой способ сделать это – исправить исходники adLDAP.php, так как все вызовы к ldap_connect содержат порт в качестве отдельного аргумента функции.
5

Подключиться к active directory c помощью php

//Первый вариант

///Подключаемся к АД

$ldap_host=“192.168.1.10”;//ip контроллера домена

$ldap_port=“389”;//Порт

$ldap_user=[email protected];// AD-user

$ldap_pass=“Password”;//AD-user’s password

/* Открываем соединение */

$connect=ldap_connect($ldap_host,$ldap_port)ordie(“Could not connect to LDAP server.”);

ldap_set_option($connect,LDAP_OPT_PROTOCOL_VERSION,3);

ldap_set_option($connect,LDAP_OPT_REFERRALS,0);

$bind=ldap_bind($connect,$ldap_user,$ldap_pass)  ordie(“LDAP bind failed…”);

$domain1=“yourdomain”;

$domain2=“com”;

$base_dn=“DC=$domain1, DC=$domain2”;

$filter=“(&(objectClass=user)(objectCategory=person)(|(name=*)(displayname=*)(cn=*)))”;

$search=ldap_search($connect,$base_dn,$filter);

$info=ldap_get_entries($connect,$search);

$infoЭтомассивсвыборкойвсехучетныхзаписей,егоужеможноперебрать,ивытянутьнеобходимыеполя.

//Второй  вариант с перебором полученного массива

//На базе переменной $bind, можно сделать авторизацию в AD.

$ldap_user=[email protected];// AD-user

$ldap_pass=“Password”;//AD-user’s password

$adServer=“ldap:// yourdomain.com”;

$ldap=ldap_connect($adServer);

$ldaprdn=‘yourdomain’.“\”.$ldap_user;

ldap_set_option($ldap,LDAP_OPT_PROTOCOL_VERSION,3);

ldap_set_option($ldap,LDAP_OPT_REFERRALS,0);

$bind=@ldap_bind($ldap,$ldaprdn,$ldap_pass);

if($bind)

{

      $users=array();

      $filter=“(&(objectClass=user)(objectCategory=person)(|(name=*)(displayname=*)(cn=*)))”;

      $result=ldap_search($ldap,“dc= yourdomain,dc=COM”,$filter);

      @ldap_sort($ldap,$result,“sn”);

      $info=ldap_get_entries($ldap,$result);

      for($i=0;$i<$info[“count”];$i ){

         $user[“fio”]=$info[$i][“name”][0];

         $user[“login”]=$info[$i][“samaccountname”][0];

         $users[]=$user;              

      }

}

else

{

      echo“Неверный логин или пароль”;

}

@ldap_close($ldap);

Разобрался с работой с ad из php…

В PHP требуется только модуль

php_ldap.dll

, поcмотрите, он входит в состав полной версии PHP.

Поключаете его в

php.ini

и далее можете пользоваться ldap-функциями. Привожу простой пример, с которого я сам начал:

<?// Работа с Active Directory// Изменение кодировки из UTF-8 в Windows-1251functionutf2win( $mes ){return mb_convert_encoding($mes,"WINDOWS-1251","UTF-8");};// Получение пользователей из Active Directoryfunctionget_AD_users(){  $ldap_user   ="Administrator";// username  $ldap_pass   ="пароль_админа";// associated password  $domain_name ="mydomain.com";// Имя домена  $domain1     ="mydomain";  $domain2     ="com";// Служебные пользователи, которых не надо показывать  $ignore_list =array("Guest","IWAM_SERVER","IUSR_SERVER","USER1CV8SERVER","Administrator");// Connect to LDAP server  $ldap_con =ldap_connect($domain_name)    or die("Could not connect to LDAP server.");// Fix for Windows 2003 AD  ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION,3);  ldap_set_option($ldap_con, LDAP_OPT_REFERRALS,0);// binding to LDAP server  $ldapbind =ldap_bind($ldap_con, $ldap_user, $ldap_pass)    or die("LDAP bind failed...");  $base_dn ="DC=$domain1, DC=$domain2";  $filter ="(&(objectClass=user)(objectCategory=person)(|(name=*)(displayname=*)(cn=*)))";  $search=ldap_search($ldap_con, $base_dn, $filter);  $number_returned =ldap_count_entries($ldap_con,$search);// Количество пользователей  $info =ldap_get_entries($ldap_con, $search);// Результирующий массив с пользователями из AD  $users =array();for($i=0; $i<$info["count"]; $i  ){    $user =array();    $user["login"]= utf2win($info[$i]["samaccountname"][0]);    $user["fio"]= utf2win($info[$i]["name"][0]);    $tmp =explode(" ",$user["fio"]);    $user["last"]=trim($tmp[0]);// Фамилия    $user["first"]= @trim($tmp[1]);// Имя    $user["second"]= @trim($tmp[2]);// Отчествоif(!in_array($user["login"],$ignore_list)){      $users[$user["login"]]= $user;};}return $users;};?>
Похожее:  PHP Login System with PDO Connection.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *