LDAP authenticatie
Ik ben bezig met LDAP authenticatie en het scriptje werkt. Alleen nu wil ik dat alleen een bepaalde groep toegang krijgt. Hoe los ik dit op?
Dit heb ik nu:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
session_start();
$succes = TRUE;
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$naam = ("OFFICE\\");
$naam.= $_POST['gebruikersnaam'];
if ( isset($_POST['gebruikersnaam']) && isset($_POST['wachtwoord']))
{
/* aanmelden via LDAP */
$ds=ldap_connect("172.16.10.4");
if(!$ds)
{
$succes = FALSE;
$foutmelding = 'Geen verbinding met Active Directory';
}
if($succes === TRUE)
{
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$r=ldap_bind($ds, $naam, $_POST['wachtwoord']);
if($r)
{
$_SESSION['gebruiker_id'] = $row['GEBRUIKERID'];
$_SESSION['aangemeld'] = TRUE;
header("Location: home.php");
}
else
{
$succes = FALSE;
$foutmelding = 'Inloggen is niet gelukt door ongeldige combinatie gebruikersnaam/wachtwoord.<br/>';
}
ldap_close($ds);
}
}
else
{
$error = 'Vul zowel gebruikersnaam als wachtwoord in om in te loggen.';
}
}
?>
session_start();
$succes = TRUE;
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$naam = ("OFFICE\\");
$naam.= $_POST['gebruikersnaam'];
if ( isset($_POST['gebruikersnaam']) && isset($_POST['wachtwoord']))
{
/* aanmelden via LDAP */
$ds=ldap_connect("172.16.10.4");
if(!$ds)
{
$succes = FALSE;
$foutmelding = 'Geen verbinding met Active Directory';
}
if($succes === TRUE)
{
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$r=ldap_bind($ds, $naam, $_POST['wachtwoord']);
if($r)
{
$_SESSION['gebruiker_id'] = $row['GEBRUIKERID'];
$_SESSION['aangemeld'] = TRUE;
header("Location: home.php");
}
else
{
$succes = FALSE;
$foutmelding = 'Inloggen is niet gelukt door ongeldige combinatie gebruikersnaam/wachtwoord.<br/>';
}
ldap_close($ds);
}
}
else
{
$error = 'Vul zowel gebruikersnaam als wachtwoord in om in te loggen.';
}
}
?>
Hmm volgens mij weet niemand hoe dit moet:(
in je database aan die bepaalde groep een extra rij meegeven en daar ook op controleren lijkt mij?
Ja in mij Active Directory is een groep aangemaakt. Maar ik zou niet weten waar ik dat in mijn script moet aangeven dat alleen die mensen uit de groep erbij mogen
http://adldap.sourceforge.net/ gedaan. Was simpel met de voorbeelden erbij.
Features:
User authentication
Group management
User management
Contact management
Exchange mailbox creation
Het is niet zelf gemaakt of een oplossing voor je eigenscript, maar wat je wilt heb ik met success met Features:
User authentication
Group management
User management
Contact management
Exchange mailbox creation
Maar ik ben er zelf ook mee bezig maar kijk anders eens hier voor de tuts,
voor alvast wat extra info en stuff.
TuTs AD
Greets
Gewijzigd op 14/03/2012 18:20:44 door Marco PHPJunky
Ik zal is gaan rondkijken alvast bedankt!
En al wat verder gekomen ?
Dit topic is mij ontschoten, excuses!
Kan je mij uitleggen wat je nu precies in Active Directory hebt ingesteld? Kortom, kan je de situatie beschrijven?
Niels
De situatie is als het volgt:
Ik ben met een simpel systeempje bezig waar ik authenticatie voor nodig heb. Ik wilde de active directory gebruiken zodat de gebruikers niet aparte wachtwoorden en gebruikersnamen nodig hebben.
Het script wat ik geplaatst heb werk perfect met de gebruikersnamen en wachtwoorden uit de Active Directory. Het enige probleem is dat het script nu iedereen doorlaat die in de active directory bekend is. Ik wil dat alleen specifieke groep uit de active directory rechten heeft binnen het systeem. Maar ik heb helaas geen idee waaar ik dit moet aangeven binnen het script.
Zowel blijf je op de pagina?
Dem Ian op 17/03/2012 15:52:14:
Op elke pagina kijk je of er een sessie is, zonee ga je naar de login.
Zowel blijf je op de pagina?
Zowel blijf je op de pagina?
Ja een sessie starten op iedere pagina moet zowiezo. Maar je zult in het login script toch moeten aangeven welke groep wel rechten heeft.
Wil je anders eens de werking van je script beschrijven?
Ik snap volkomen wat je bedoeld. Voordat ik je ga uitleggen hoe het allemaal werkt even een vraag. Is het niet veel mooier als je een Single Sign On creëert? Ik heb dit zelf nog nooit gedaan, maar ik weet dat dit met het Kerberos protocol kan. Heb ik altijd al in willen duiken, maar ik heb zo weinig tijd ;-)
Terugkomend op jouw vraag, heel even de werkwijze neergezet:
1: Het authenticeren van een gebruiker.
2: Controleren of de gebruiker een de juiste groep zit.
Het authenticeren van een gebruiker:
Ik heb wat opmerkingen op de manier hoe jij een gebruiker in laat loggen.
Ik mis de (juiste) foutafhandeling van diversen onderdelen en ik mis de instelling van de versie van LDAP. Wanneer je eventueel de authenticatie over SSL wilt laten verlopen moet je gebruik maken van LDAP versie 3.
Marco heeft je reeds een link gestuurd naar de reeks met artikelen over Active Directory en PHP.
In het 5e artikel wordt uitgelegd hoe je op de juiste manier een gebruiker kunt authenticeren. In het 4e artikel wordt uitgelegd hoe je precies de versie van LDAP instelt.
Controleren of de gebruiker een de juiste groep zit:
Dit wordt een wat lastiger punt (phoe). Ik heb iets gemaakt, en ik denk het doet wat jij wil. Ik heb op dit moment niet de mogelijkheid om het (goed) te testen, dus dat moet je zelf even doen :-)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['username']) && isset($_POST['password'])) {
$dn = 'OFFICE\\';
$connection = ldap_connect('172.16.10.4', 389);
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($connection, $dn.$_POST['username']), $_POST['password']);
$filter = 'samaccountname='.$_POST['username'];
$search = ldap_search($connection, $dn, $filter, array('memberof', 'primarygroupid'));
$entries = ldap_get_entries($connection, $search);
if ($entries[0]['count'] > 0) {
// Active Directory retourneert niet de primary groep.
// Ik neem aan dat je die wilt hebben
if (isset($entries[0]['primarygroupid'][0]) && isset($entries[0]['objectsid'][0])) {
$userId = $entries[0]['objectsid'][0];
$groupId = $entries[0]['primarygroupid'][0];
$id = substr_replace($userId, pack('V', $groupId), strlen($userId)-4, 4);
// ID is nu binair. ldap_search kan daar niet mee omgaan, dus 'even' converteren
$hexId = bin2hex($id);
$count = hexdec(substr($hexId, 2, 2));
$result = hexdec(substr($hexId, 0, 2)) - hexdec(substr($hexId, 4, 12));
for ($i = 0; $i < $count; $i++) {
// Conversie little-endian hex naar normale hex (anders kan hexdec er niet mee omgaan)
$conv = '';
for ($x = strlen(substr($hexId, 16 + ($i * 8), 8)) - 2; $x >= 0; $x = $x -2) {
$conv .= substr(substr($hexId, 16 + ($i * 8), 8), $x, 2);
}
// Samensmelten
$subs = array();
$subs[$i] = hexdec($conv);
$result .= '-'.$subs[$i];
}
// Uiteindelijke resultaat
$result = 'S-'.$result;
$filter = '(objectsid=)'.$result;
$search = ldap_search($connection, $dn, $filter, array('samaccountname', 'distinguishedname'));
$secondEntries = ldap_get_entries($connection, $search);
// De bovenliggende entries vullen
$entries[0]['memberof'][] = $secondEntries[0]['distinguishedname'][0];
}
else {
$entries[0]['memberof'][] = 'CN=Domain Users,CN=Users,'.$dn;
}
}
$userInfo = ++$entries[0]['memberof']['count'];
// Groepen filteren. (Active directory zet standaard diversen pre / suffixen)
$info[0]["memberof"];
$groups = array();
for ($i = 0; $i < $info[0]['memberof']['count']; $i++) {
$group = $info[0]['memberof'][$i];
if (strlen($group) > 0) {
// Alle rotzooi eruit filteren
$bits = explode(',', $group);
$groups[] = substr($bits[0], 3, (strlen($bits[0]) - 3));
}
}
if (in_array('naamvandegroep', $groups)) {
echo 'Phoe, eindelijk ingelogd! :-)';
}
}
}
?>
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['username']) && isset($_POST['password'])) {
$dn = 'OFFICE\\';
$connection = ldap_connect('172.16.10.4', 389);
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($connection, $dn.$_POST['username']), $_POST['password']);
$filter = 'samaccountname='.$_POST['username'];
$search = ldap_search($connection, $dn, $filter, array('memberof', 'primarygroupid'));
$entries = ldap_get_entries($connection, $search);
if ($entries[0]['count'] > 0) {
// Active Directory retourneert niet de primary groep.
// Ik neem aan dat je die wilt hebben
if (isset($entries[0]['primarygroupid'][0]) && isset($entries[0]['objectsid'][0])) {
$userId = $entries[0]['objectsid'][0];
$groupId = $entries[0]['primarygroupid'][0];
$id = substr_replace($userId, pack('V', $groupId), strlen($userId)-4, 4);
// ID is nu binair. ldap_search kan daar niet mee omgaan, dus 'even' converteren
$hexId = bin2hex($id);
$count = hexdec(substr($hexId, 2, 2));
$result = hexdec(substr($hexId, 0, 2)) - hexdec(substr($hexId, 4, 12));
for ($i = 0; $i < $count; $i++) {
// Conversie little-endian hex naar normale hex (anders kan hexdec er niet mee omgaan)
$conv = '';
for ($x = strlen(substr($hexId, 16 + ($i * 8), 8)) - 2; $x >= 0; $x = $x -2) {
$conv .= substr(substr($hexId, 16 + ($i * 8), 8), $x, 2);
}
// Samensmelten
$subs = array();
$subs[$i] = hexdec($conv);
$result .= '-'.$subs[$i];
}
// Uiteindelijke resultaat
$result = 'S-'.$result;
$filter = '(objectsid=)'.$result;
$search = ldap_search($connection, $dn, $filter, array('samaccountname', 'distinguishedname'));
$secondEntries = ldap_get_entries($connection, $search);
// De bovenliggende entries vullen
$entries[0]['memberof'][] = $secondEntries[0]['distinguishedname'][0];
}
else {
$entries[0]['memberof'][] = 'CN=Domain Users,CN=Users,'.$dn;
}
}
$userInfo = ++$entries[0]['memberof']['count'];
// Groepen filteren. (Active directory zet standaard diversen pre / suffixen)
$info[0]["memberof"];
$groups = array();
for ($i = 0; $i < $info[0]['memberof']['count']; $i++) {
$group = $info[0]['memberof'][$i];
if (strlen($group) > 0) {
// Alle rotzooi eruit filteren
$bits = explode(',', $group);
$groups[] = substr($bits[0], 3, (strlen($bits[0]) - 3));
}
}
if (in_array('naamvandegroep', $groups)) {
echo 'Phoe, eindelijk ingelogd! :-)';
}
}
}
?>
Ik ben benieuwd of je een beetje snapt wat er allemaal gebeurd. Je moet wel zelf even de foutafhandeling toevoegen. Als ik dat allemaal had gedaan was het script wel een stukje langer :-)
De uitdaging voor mij is de groepen nog recursief in de array pompen. Ik zal eens kijken of ik dat voor elkaar krijg.
Niels
Gewijzigd op 17/03/2012 19:42:51 door Niels K
Niels bedankt voor je hulp! Ik zal het binnenkort als ik er weer mee bezig ben uittesten!
Is het gelukt?
We hebben het volgende script nu gebruikt:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
session_start();
$username = $_POST['gebruikersnaam'];
$password = $_POST['wachtwoord'];
$domeinserver = "xx";
$domein = "office";
$usergroep = "CN=shared_resources,OU=Access Control Groups,DC=xxx,DC=xx,DC=xx";
$ds=ldap_connect($domeinserver);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$r = @ldap_bind($ds, $domein."\\".$username, $password);
if ($r) {
$sr= ldap_search($ds, $usergroep, "CN=*");
$info = ldap_get_entries($ds, $sr);
for ($i=0; $i<$info["count"]; $i++) {
for ($b=0; $b<count($info[0]["member"])-1; $b++) {
$zoek = $info[0]["member"][$b];
$nr=ldap_search($ds, $zoek, "CN=*");
$ninfo = ldap_get_entries($ds, $nr);
$userstring = $ninfo[0][userprincipalname][0];
list($loginnaam, $achterstuk) = split('[@]', $userstring);
$ingroep = ((strtolower($username) == strtolower($loginnaam)) ? 1 : 0);
switch($ingroep){
case 1: $_SESSION['inlognaam'] = $username;
$_SESSION['aangemeld'] = TRUE;
header("Location: home.php");
}
}
}
} else { echo "Uw gebruikesnaam of wachtwoord is incorrect..." ; }
ldap_close($ds);
?>
session_start();
$username = $_POST['gebruikersnaam'];
$password = $_POST['wachtwoord'];
$domeinserver = "xx";
$domein = "office";
$usergroep = "CN=shared_resources,OU=Access Control Groups,DC=xxx,DC=xx,DC=xx";
$ds=ldap_connect($domeinserver);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$r = @ldap_bind($ds, $domein."\\".$username, $password);
if ($r) {
$sr= ldap_search($ds, $usergroep, "CN=*");
$info = ldap_get_entries($ds, $sr);
for ($i=0; $i<$info["count"]; $i++) {
for ($b=0; $b<count($info[0]["member"])-1; $b++) {
$zoek = $info[0]["member"][$b];
$nr=ldap_search($ds, $zoek, "CN=*");
$ninfo = ldap_get_entries($ds, $nr);
$userstring = $ninfo[0][userprincipalname][0];
list($loginnaam, $achterstuk) = split('[@]', $userstring);
$ingroep = ((strtolower($username) == strtolower($loginnaam)) ? 1 : 0);
switch($ingroep){
case 1: $_SESSION['inlognaam'] = $username;
$_SESSION['aangemeld'] = TRUE;
header("Location: home.php");
}
}
}
} else { echo "Uw gebruikesnaam of wachtwoord is incorrect..." ; }
ldap_close($ds);
?>
Toevoeging op 22/03/2012 14:48:54:
Maar zit ik weer met het volgende probleem :( ik vind ldap toch niet zo leuk meer.. XD Ik moet nog een lijst hebben van alle users van de AD die in een dropdown box komt. Misschien ideeen?
Op deze manier kan het ook. Alleen kijkt hij op dit moment niet naar subs.
Stel je hebt de volgende mappenstructuur:
- Hoofdmap
- Submap
Nu wil je weten of je user in de groep Submap zit. Naar mijn weten controleert jouw script dat niet.
Daarnaast, moet jij een hele LDAP search string invoeren: 'CN=shared_resources,OU=Access Control Groups,DC=xxx,DC=xx,DC=xx'. Met mijn script hoef je alleen de naam in te voeren.
Maar het doet zover ik zie wel wat jij wil ;-)
Mooi dat je het hebt opgelost.
Niels