- 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/
我们正在构建一个新的库,它需要对我们的主要身份管理 LDAP 系统进行读/写。 我们正在考虑使用 Spring LDAP ( http://projects.spring.io/spring-ldap
在 LDAP 身份验证的情况下, 是什么?参数 一般用于身份验证 .我想对于通过 ldap 登录的用户来说,使用 DN 会很头疼,因为它太大而无法记住。 使用 uid 或 sAMAccountName
我知道 LDAP 用于提供一些信息并帮助促进授权。 但是 LDAP 的其他用途是什么? 最佳答案 我将重点讨论为什么使用 LDAP,而不是 LDAP 是什么。 使用模型类似于人们使用借书卡或电话簿的方
我正在尝试查询 LDAP 服务器以获取使用 ruby 的 net-ldap 库的任何组的详细信息 require 'rubygems' require 'net/ldap' username =
在使用 spring ldap 模板的 Ldap 搜索中,我返回一个 User 对象,该对象具有保存另一个用户的 dn 的属性之一。并且,User 对象有一些属性需要使用其他用户的 ldap 条目获取
我正在尝试使用例如search_s函数根据对象的完整可分辨名称搜索对象,但我觉得这并不方便。例如, search_s('DC=example, DC=com', ldap.SCOPE_SUBTREE,
LDAP 查询如何工作:-(我)。 Windows Powershell(二). Java JNDI(三)。 SpringLDAP 上述 3 种方法中的 LDAP 筛选器查询是否仅搜索前 1000 条
我们正在使用 spring security 在我们的应用程序中对来自 LDAP 的用户进行身份验证。认证部分工作正常,但授权部分不工作。 我们无法从 LDAP 中检索用户的角色。 来自本书 《 Sp
这个问题在这里已经有了答案: Does the LDAP protocol limit the length of a DN (3 个回答) 关闭8年前。 DN 是否有最大长度?如果我想将它们存储在数
我知道我的谷歌搜索技能让我失望了,因为那里有 必须是这样的:一个简单、易于使用的远程托管目录服务(更好的是,通过几个不同的接口(interface)和 SSO 公开用户目录)。 你知道一个和/或有一个
我有一个使用 JSF 2.1 和 JEE 6 设置的 Web 应用程序,该应用程序在 WebLogic 12.1.2 服务器上运行,并带有用于身份验证的 openLDAP。我一直注意到在应用程序中加载
我的应用程序每天执行一次 LDAP 查询并获取给定容器中的所有用户和组。获取后,我的应用程序将遍历组的用户列表,仅将新用户添加到我的应用程序数据库中(它仅添加用户名)。 如果有 50,000 个用户,
我正在尝试解决一个问题,即尝试通过 LDAP 设置用户密码失败,因为访问被拒绝错误 - 即使我正在使用管理员用户对 AD 进行身份验证。 在 stackoverflow 中找到的答案说,要么我必须以管
我有一个我没有完全权限的 LDAP 服务器和一个我是 root 的具有 LDAP 身份验证的 ubuntu 系统。是否可以将 LDAP 用户添加到本地组? (我不知道我的表述是否正确,但我想要的只是在
我有一个属性(groupIDNumber),我想让它作为自动递增数字工作? 我们如何定义该属性? 感谢您的帮助, -纳米 最佳答案 这不是 LDAP 协议(protocol)的一部分,也不是标准的做法
对“uid”属性执行不区分大小写匹配的语法是什么?如果属性定义很重要,那么它将如何更改?特别是我将 ApacheDS 用于我的 LDAP 存储。 最佳答案 (uid=miXedCaseUSer)将匹配
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我需要有关 LDAP 搜索过滤器的信息来提取嵌套组成员资格。基本上,我的想法是,例如,一个用户属于 5 个组 [A、B、C、D、E]我可以编写单个 LDAP 搜索查询来获取组 [A、B、C、D、E]
我关注了 installing ldap on centos 在我的服务器上设置 LDAP 服务器的指南,完成所有安装步骤后,我执行了 ldapsearch -x -b "dc=test,dc=com
我想编写一个 LDAP 查询来测试用户 (sAMAccountName) 是否是特定组的成员。是否可以这样做以便我获得 0 或 1 个结果记录? 我想我可以获取用户的所有组并测试每个组是否匹配,但我想
我是一名优秀的程序员,十分优秀!