我的应用程序的某些用户将附加allowedIPs
数组。验证Voter
有guide用于将IP列入黑名单,我可以根据谁进行身份验证来修改用户IP的白名单。
我在这里看到的问题是用户在一个允许的网络中进行身份验证的情况,然后切换到另一个不允许用户连接的网络。
我认为解决方案是拥有kernel.request
事件的订阅者,如果不允许IP,我将取消对用户的授权。
这种IP检查对每个请求都是一种愚蠢的方法吗?如果不是,我如何在事件订阅者中获得经过身份验证的用户? GetResponseEvent
(api docs)似乎没有提供任何方法来获取经过身份验证的用户(如果存在)。
编辑:正如Cerad建议的那样,我选了一个选民。
选民班级
<?php
namespace My\UserBundle\Security;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Psr\Log\LoggerInterface;
use My\UserBundle\Entity\User;
class ValidClientIpVoter extends AuthenticatedVoter
{
private $container;
private $logger;
public function __construct(ContainerInterface $container, LoggerInterface $logger)
{
$this->container = $container;
$this->logger = $logger;
}
public function vote(TokenInterface $token, $object, array $attributes)
{
$request = $this->container->get('request');
$user = $token->getUser();
// vote on instances of our User class
if($user instanceof User) {
$allowed_ips = $user->getAllowedIps();
// only vote if there actually are limitations
if(is_array($allowed_ips) && count($allowed_ips)) {
$this->logger->debug(sprintf('ValidClientIpVoter: Validating allowed IPs for user #%d', $user->getId()));
// deny access if current request's IP is not allowed for the user
if(!in_array($request->getClientIp(), $allowed_ips)) {
$this->logger->notice(sprintf('ValidClientIpVoter: Invalid client IP for user #%d', $user->getId()));
return VoterInterface::ACCESS_DENIED;
}
}
}
return VoterInterface::ACCESS_ABSTAIN;
}
}
更改为security.yml
以使投票一致
security:
access_decision_manager:
strategy: unanimous
最后是服务定义
services:
valid_client_ip_voter:
class: My\UserBundle\Security\ValidClientIpVoter
arguments: [@service_container, @monolog.logger]
public: false
tags:
- { name: security.voter }
答案 0 :(得分:0)
要获取当前用户,请将security.token_storage服务注入您的侦听器:http://symfony.com/doc/current/book/security.html#retrieving-the-user-object
我实际上会听kernel.controller只是为了确保用户可用。
另一方面,选民在每次访问资源时都会被调用,所以我不清楚为什么即使ip发生变化,你现有的方法也不会起作用。