- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我努力让 LDAP 自定义身份验证在我的 Symfony2 项目上工作。我首先尝试使用 Fr3dLdapBundle 和其他软件,但它无法正常工作,而且它不支持安全组。
我终于可以使用这两个链接了:- https://groups.google.com/forum/#!topic/symfony2/RUyl15zaH8A- http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
但是现在我必须检查某人何时登录,例如他是否在安全组“AdminMyWebsite”中。如果他是,我必须将他的角色设置为 ROLE_ADMIN。但我不知道该怎么做。
Ldap 提供者:
<?php
namespace EspaceApprenti\UserBundle\Security\Authentication\Provider;
use EspaceApprenti\UserBundle\Security\Authentication\Token\LdapToken;
use Symfony\Component\Debug\Exception\ContextErrorException;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
class LdapProvider implements AuthenticationProviderInterface {
private $userProvider;
private $providerKey;
private $logger;
private $server;
private $port;
private $domaine;
private $dn;
public function __construct(UserProviderInterface $userProvider, $providerKey, $logger, $server, $port, $domaine, $dn) {
$this->userProvider = $userProvider;
$this->providerKey = $providerKey;
$this->logger = $logger;
$this->server = $server;
$this->port = $port;
$this->domaine = $domaine;
$this->dn = $dn;
}
public function authenticate(TokenInterface $token) {
if (!$this->supports($token)) {
return null;
}
$user = $this->userProvider->loadUserByUsername($token->getUsername());
$username = $token->getUsername();
$password = $token->getCredentials();
$this->logger->info(' -- LdapProvider -- ' . $username);
if ($password) {
if (!$this->ldapBind($username, $password)) {
throw new AuthenticationException('Authentication failed ! ');
}
}
$authenticatedToken = new LdapToken($user, $password, $this->providerKey, $user->getRoles());
$authenticatedToken->setAttributes($token->getAttributes());
return $authenticatedToken;
}
private function ldapBind($username, $password) {
// returns true or false
$this->logger->info(' -- LdapProvider -> ldapBind() Serveur -- ' . $this->server);
$this->logger->info(' -- LdapProvider -> ldapBind() Username -- ' . $username);
$ds = ldap_connect($this->server, $this->port);
if ($ds) {
try {
if (ldap_bind($ds, $this->domaine . '\\' . $username, $password)) {
return true;
} else {
return false;
}
} catch (ContextErrorException $e) {
$this->logger->error(' -- LdapProvider -> ldapBind() Unable to bind to server: Invalid credentials -- ' . $e->getMessage());
}
} else {
$this->logger->info(' -- LdapProvider -> ldapBind() Unable to connect to LAPP Server -- ' . $this->server);
}
}
public function supports(TokenInterface $token) {
return $token instanceof LdapToken;
}
}
Ldap工厂
<?php
namespace EspaceApprenti\UserBundle\DependencyInjection\Security\Factory;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;
class LdapFactory extends AbstractFactory
{
protected function getListenerId()
{
return 'security.authentication.listener.ldap';
}
protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId)
{
$providerId = 'security.authentication.provider.ldap.'.$id;
$container
->setDefinition($providerId, new DefinitionDecorator('security.authentication.provider.ldap'))
->replaceArgument(0, new Reference($userProviderId))
->replaceArgument(1, $id);
return $providerId;
}
protected function createEntryPoint($container, $id, $config, $defaultEntryPoint)
{
$entryPointId = 'security.authentication.ldap_entry_point.'.$id;
$container
->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.ldap_entry_point'))
->addArgument(new Reference('security.http_utils'))
->addArgument($config['login_path'])
->addArgument($config['use_forward'])
;
return $entryPointId;
}
public function getPosition()
{
return 'form';
}
public function getKey()
{
return 'ldap';
}
}
LdapListener
<?php
namespace EspaceApprenti\UserBundle\Security\Firewall;
use EspaceApprenti\UserBundle\Security\Authentication\Token\LdapToken;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
class LdapListener extends AbstractAuthenticationListener
{
private $csrfProvider;
protected $logger;
/**
* {@inheritdoc}
*/
public function __construct(SecurityContextInterface $securityContext,
AuthenticationManagerInterface $authenticationManager,
SessionAuthenticationStrategyInterface $sessionStrategy,
HttpUtils $httpUtils,
$providerKey,
AuthenticationSuccessHandlerInterface $successHandler,
AuthenticationFailureHandlerInterface $failureHandler,
array $options = array(),
LoggerInterface $logger = null,
EventDispatcherInterface $dispatcher = null,
CsrfProviderInterface $csrfProvider = null)
{
parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'intention' => 'authenticate',
'post_only' => true,
), $options), $logger, $dispatcher);
$this->csrfProvider = $csrfProvider;
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
protected function requiresAuthentication(Request $request)
{
if ($this->options['post_only'] && !$request->isMethod('POST')) {
return false;
}
return parent::requiresAuthentication($request);
}
/**
* {@inheritdoc}
*/
protected function attemptAuthentication(Request $request)
{
if (null !== $this->csrfProvider) {
$csrfToken = $request->get($this->options['csrf_parameter'], null, true);
if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'], $csrfToken)) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}
if ($this->options['post_only']) {
$username = trim($request->request->get($this->options['username_parameter'], null, true));
$password = $request->request->get($this->options['password_parameter'], null, true);
} else {
$username = trim($request->get($this->options['username_parameter'], null, true));
$password = $request->get($this->options['password_parameter'], null, true);
}
$this->logger->alert('LdapAuthenticationListener : '. $username);
$this->logger->alert('LdapAuthenticationListener : '. $this->providerKey);
$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);
return $this->authenticationManager->authenticate(new LdapToken($username, $password, $this->providerKey));
}
}
Ldap token
<?php
namespace EspaceApprenti\UserBundle\Security\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
class LdapToken extends AbstractToken {
private $credentials;
private $providerKey;
/**
* Constructor.
*
* @param string $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method.
* @param string $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param RoleInterface[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/
public function __construct($user, $credentials, $providerKey, array $roles = array())
{
parent::__construct($roles);
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
$this->setUser($user);
$this->credentials = $credentials;
$this->providerKey = $providerKey;
parent::setAuthenticated(count($roles) > 0);
}
/**
* {@inheritdoc}
*/
public function setAuthenticated($isAuthenticated)
{
if ($isAuthenticated) {
throw new \LogicException('Cannot set this token to trusted after instantiation.');
}
parent::setAuthenticated(false);
}
public function getCredentials()
{
return $this->credentials;
}
public function getProviderKey()
{
return $this->providerKey;
}
/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
parent::eraseCredentials();
$this->credentials = null;
}
/**
* {@inheritdoc}
*/
public function serialize()
{
return serialize(array($this->credentials, $this->providerKey, parent::serialize()));
}
/**
* {@inheritdoc}
*/
public function unserialize($serialized)
{
list($this->credentials, $this->providerKey, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
}
谁能帮我解决这个问题?
问候
最佳答案
我解决了我的问题。我在 ldap_bind 之后添加了一个 ldap_search 来检查用户是否是安全组的成员
$ds = ldap_connect($this->server, $this->port);
if ($ds) {
try {
if (ldap_bind($ds, $this->domaine . '\\' . $username, $password)){
$user = $this->m->getRepository('EspaceApprentiUserBundle:ApprenticeUser')->findOneBy(array('username' => $username));
$filter = "(&(objectCategory=person)(samAccountName=" . $username . "))";
$result = ldap_search($ds, $this->dn, $filter);
$entries = ldap_get_entries($ds, $result);
if (in_array($this->administrator,$entries[0]['memberof']))
{
$user->setRoles(array('ROLE_ADMIN'));
$this->m->persist($user);
$this->m->flush();
} else {
$user->setRoles(array('ROLE_USER'));
$this->m->persist($user);
$this->m->flush();
}
return true;
} else {
return false;
}
} catch (ContextErrorException $e) {
$this->logger->error(' -- LdapProvider -> ldapBind() Unable to bind to server: Invalid credentials -- ' . $e->getMessage());
}
} else {
$this->logger->info(' -- LdapProvider -> ldapBind() Unable to connect to LAPP Server -- ' . $this->server);
}
关于php - LDAP 安全组 Symfony 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22246551/
我在 JavaScript 文件中运行 PHP,例如...... var = '';). 我需要使用 JavaScript 来扫描字符串中的 PHP 定界符(打开和关闭 PHP 的 )。 我已经知道使
我希望能够做这样的事情: php --determine-oldest-supported-php-version test.php 并得到这个输出: 7.2 也就是说,php 二进制检查 test.
我正在开发一个目前不使用任何框架的大型 php 站点。我的大问题是,随着时间的推移慢慢尝试将框架融入应用程序是否可取,例如在创建的新部件和更新的旧部件中? 比如所有的页面都是直接通过url服务的,有几
下面是我的源代码,我想在同一页面顶部的另一个 php 脚本中使用位于底部 php 脚本的变量 $r1。我需要一个简单的解决方案来解决这个问题。我想在代码中存在的更新查询中使用该变量。 $name)
我正在制作一个网站,根据不同的情况进行大量 PHP 重定向。就像这样...... header("Location: somesite.com/redirectedpage.php"); 为了安全起见
我有一个旧网站,我的 php 标签从 因为短标签已经显示出安全问题,并且在未来的版本中将不被支持。 关于php - 如何避免在 php 文件中写入
我有一个用 PHP 编写的配置文件,如下所示, 所以我想用PHP开发一个接口(interface),它可以编辑文件值,如$WEBPATH , $ACCOUNTPATH和 const值(value)观
我试图制作一个登录页面来学习基本的PHP,首先我希望我的独立PHP文件存储HTML文件的输入(带有表单),但是当我按下按钮时(触发POST到PHP脚本) )我一直收到令人不愉快的错误。 我已经搜索了S
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is the max key size for an array in PHP? 正如标题所说,我想知道
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我在 MySQL 数据库中有一个表,其中存储餐厅在每个工作日和时段提供的菜单。 表结构如下: i_type i_name i_cost i_day i_start i_
我有两页。 test1.php 和 test2.php。 我想做的就是在 test1.php 上点击提交,并将 test2.php 显示在 div 中。这实际上工作正常,但我需要向 test2.php
我得到了这个代码。我想通过textarea更新mysql。我在textarea中回显我的MySQL,但我不知道如何更新它,我应该把所有东西都放进去吗,因为_GET模式没有给我任何东西,我也尝试_GET
首先,我是 php 的新手,所以我仍在努力学习。我在 Wordpress 上创建了一个表单,我想将值插入一个表(data_test 表,我已经管理了),然后从 data_test 表中获取所有列(id
我有以下函数可以清理用户或网址的输入: function SanitizeString($var) { $var=stripslashes($var); $va
我有一个 html 页面,它使用 php 文件查询数据库,然后让用户登录,否则拒绝访问。我遇到的问题是它只是重定向到 php 文件的 url,并且从不对发生的事情提供反馈。这是我第一次使用 html、
我有一个页面充满了指向 pdf 的链接,我想跟踪哪些链接被单击。我以为我可以做如下的事情,但遇到了问题: query($sql); if($result){
我正在使用 从外部文本文件加载 HTML/PHP 代码 $f = fopen($filename, "r"); while ($line = fgets($f, 4096)) { print $l
我是一名优秀的程序员,十分优秀!