php 使用 Active Directory 对 Intranet 站点上的用户进行身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17773643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using active directory to authenticate users on intranet site
提问by kallakafar
I have an 'intranet' site that I have built, which has a login system of its own (users register as new users, and use the username/password thereon to login to the site). However, now I want to extend it, and have the intranet site use the existing ActiveDirectory for authentication. This is what I am looking for, going forward -
我有一个我建立的“内联网”站点,它有自己的登录系统(用户注册为新用户,并使用其上的用户名/密码登录该站点)。但是,现在我想扩展它,并让 Intranet 站点使用现有的 ActiveDirectory 进行身份验证。这就是我正在寻找的,前进 -
When a user access this intranet site (http://intranetsite/mySite
), the user's domain credentials are validated against the active directory, and if the user's credentials match AD, the user is then presented the main page of the intranet site.
当用户访问此 Intranet 站点 ( http://intranetsite/mySite
) 时,将根据 Active Directory 验证用户的域凭据,如果用户凭据与 AD 匹配,则向用户显示 Intranet 站点的主页。
I am new to AD, and do not know how to go about this configuration. My intranet site is built around PHP and uses Apache on the application server; the AD is on a different IIS server.
我是 AD 新手,不知道如何进行此配置。我的内网站点是围绕 PHP 构建的,并在应用服务器上使用 Apache;AD 位于不同的 IIS 服务器上。
What information do I need, and where do I put this information (into my site? htaccess? anywhere else?) so that I can use AD authentication? Is just 'configuration' enough, or do I need to write explicit PHP code for this authentication?
我需要什么信息,我应该把这些信息放在哪里(到我的网站?htaccess?其他地方?)以便我可以使用 AD 身份验证?仅仅“配置”就足够了,还是我需要为这种身份验证编写显式的 PHP 代码?
Any pointers are much appreciated.
任何指针都非常感谢。
回答by Robert Rossmann
If you are looking only for authentication and nothing else, you may get away with only a few lines of code.
如果您只寻找身份验证而不是其他任何东西,那么您可能只需要几行代码就可以逃脱。
First, ensure you have ldap enabledin your php.
首先,确保您在php.ini 中启用了ldap。
Here's pure php implementation:
(note that when doing it this way you should ensure that you DO HAVE a username and a password from a user - anonymous binding will almost always return true for AD)
这是纯 php 实现:(
请注意,这样做时,您应该确保您确实拥有来自用户的用户名和密码 - 匿名绑定几乎总是为 AD 返回 true)
$link = ldap_connect('domain.com'); // Your domain or domain server
if(! $link) {
// Could not connect to server - handle error appropriately
}
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3); // Recommended for AD
// Now try to authenticate with credentials provided by user
if (! ldap_bind($link, '[email protected]', 'SomeSecret')) {
// Invalid credentials! Handle error appropriately
}
// Bind was successful - continue
If you expect to do more fun stuff with Active Directory like pulling some information about currently logged in user I strongly recommend using a framework to do the heavy lifting for you. As already mentioned, adLDAP is a good one and if you run PHP 5.4 I dare recommending the AD-Xlibrary which I actively develop (you can install it via Composer).
如果您希望使用 Active Directory 做更多有趣的事情,例如提取有关当前登录用户的一些信息,我强烈建议您使用框架来为您完成繁重的工作。如前所述,adLDAP 是一个不错的选择,如果您运行 PHP 5.4,我敢于推荐我积极开发的AD-X库(您可以通过 Composer 安装它)。
With the AD-X library, you can verify a user's credentials using this code:
使用 AD-X 库,您可以使用以下代码验证用户的凭据:
try {
$link = new ADX\Core\Link('domain.com'); // Establish connection to AD
$link->bind('[email protected]', 'SomeSecret'); // Authenticate user
}
catch (ADX\Core\ServerUnreachableException $e) {
// Unable to connect to server, handle error
}
catch (ADX\Core\InvalidCredentialsException $e) {
// Invalid credentials supplied
}
catch (Exception $e) {
// Something else happened, check the exception and handle appropriately
}
// Successfully authenticated if no exception has been thrown
Feel free to choose which suits you best. However, if you expect to do more than authenticate I strongly suggest you use a library for the ldap work - it will save you a lot of time and possibly frustration when things do not work as you would expect them to.
随意选择最适合您的。但是,如果您希望做的不仅仅是身份验证,我强烈建议您使用库进行 ldap 工作 - 当事情不像您期望的那样工作时,它会为您节省大量时间并可能会感到沮丧。
Also, if in doubt what information you can/should use to connect and to authenticate feel free to check my previous answeron this topic.
回答by jrm
Here is what I use:
这是我使用的:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');
define('DOMAIN_FQDN', 'mycompany.intra');
define('LDAP_SERVER', '192.168.0.1');
if (isset($_POST['submit']))
{
$user = strip_tags($_POST['username']) .'@'. DOMAIN_FQDN;
$pass = stripslashes($_POST['password']);
$conn = ldap_connect("ldap://". LDAP_SERVER ."/");
if (!$conn)
$err = 'Could not connect to LDAP server';
else
{
define('LDAP_OPT_DIAGNOSTIC_MESSAGE', 0x0032);
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($conn, LDAP_OPT_REFERRALS, 0);
$bind = @ldap_bind($conn, $user, $pass);
ldap_get_option($conn, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error);
if (!empty($extended_error))
{
$errno = explode(',', $extended_error);
$errno = $errno[2];
$errno = explode(' ', $errno);
$errno = $errno[2];
$errno = intval($errno);
if ($errno == 532)
$err = 'Unable to login: Password expired';
}
elseif ($bind)
{
$base_dn = array("CN=Users,DC=". join(',DC=', explode('.', DOMAIN_FQDN)),
"OU=Users,OU=People,DC=". join(',DC=', explode('.', DOMAIN_FQDN)));
$result = ldap_search(array($conn,$conn), $base_dn, "(cn=*)");
if (!count($result))
$err = 'Unable to login: '. ldap_error($conn);
else
{
foreach ($result as $res)
{
$info = ldap_get_entries($conn, $res);
for ($i = 0; $i < $info['count']; $i++)
{
if (isset($info[$i]['userprincipalname']) AND strtolower($info[$i]['userprincipalname'][0]) == strtolower($user))
{
session_start();
$username = explode('@', $user);
$_SESSION['foo'] = 'bar';
// set session variables...
break;
}
}
}
}
}
}
// session OK, redirect to home page
if (isset($_SESSION['foo']))
{
header('Location: /');
exit();
}
elseif (!isset($err)) $err = 'Unable to login: '. ldap_error($conn);
ldap_close($conn);
}
?>
<!DOCTYPE html><head><title>Login</title></head>
<style>
* { font-family: Calibri, Tahoma, Arial, sans-serif; }
.errmsg { color: red; }
#loginbox { font-size: 12px; }
</style>
<body>
<div align="center"><img id="imghdr" src="/img/logo.png" height="100" /><br><br><h2>Login</h2><br><br>
<div style="margin:10px 0;"></div>
<div title="Login" style="width:400px" id="loginbox">
<div style="padding:10px 0 10px 60px">
<form action="/login.php" id="login" method="post">
<table><?php if (isset($err)) echo '<tr><td colspan="2" class="errmsg">'. $err .'</td></tr>'; ?>
<tr>
<td>Login:</td>
<td><input type="text" name="username" style="border: 1px solid #ccc;" autocomplete="off"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" style="border: 1px solid #ccc;" autocomplete="off"/></td>
</tr>
</table>
<input class="button" type="submit" name="submit" value="Login" />
</form>
</div>
</div>
</div>
</body></html>