我正在尝试将我的security.yml中的access_control参数作为我的自定义服务中的数组。
就像获取role_hierarchy参数一样,我认为它可以使用以下代码:
$accessParameters = $this->container->getParameter('security.access_control');
不幸的是情况并非如此
有人能说出如何获取参数吗?
答案 0 :(得分:5)
无法从容器中获取access_control
参数
这是因为此参数为only used以创建request matchers,稍后会在AccessMap中将其注册为AccessListener,然后将其保留而不将其注册到容器中。
你可以尝试一些hacky来让这些匹配器变得像
一样$context = $this->get("security.firewall.map.context.main")->getContext();
$listener = $context[0][5];
// Do reflection on "map" private member
但这是一种丑陋的解决方案。
我可以看到如何获取它们的另一种方法是再次解析安全文件
use Symfony\Component\Yaml\Yaml;
$file = sprintf("%s/config/security.yml", $this->container->getParameter('kernel.root_dir'));
$parsed = Yaml::parse(file_get_contents($file));
$access = $parsed['security']['access_control'];
如果要将此配置注册到服务中,可以执行类似
的操作的 services.yml 强>
services:
acme.config_provider:
class: Acme\FooBundle\ConfigProvider
arguments:
- "%kernel.root_dir%"
acme.my_service:
class: Acme\FooBundle\MyService
arguments:
- "@acme.config_provider"
的的Acme \ FooBundle \ ConfigProvider 强>
use Symfony\Component\Yaml\Yaml;
class ConfigProvider
{
protected $rootDir;
public function __construct($rootDir)
{
$this->rootDir = $rootDir;
}
public function getConfiguration()
{
$file = sprintf(
"%s/config/security.yml",
$this->rootDir
);
$parsed = Yaml::parse(file_get_contents($file));
return $parsed['security']['access_control'];
}
}
的的Acme \ FooBundle \为MyService 强>
class MyService
{
protected $provider;
public function __construct(ConfigProvider $provider)
{
$this->provider = $provider;
}
public function doAction()
{
$access = $this->provider->getConfiguration();
foreach ($access as $line) {
// ...
}
}
}
答案 1 :(得分:0)
死灵,但仍然有意义。这是对Touki上面答案的一种改进,在此我们不重新解析access_control定义,而是使用已经配置的安全令牌,防火墙和访问映射来得出答案。
... / services.yml
...
My\Application\AuthenticationBundle\Security\AccessControlHelper:
class: My\Application\AuthenticationBundle\Security\AccessControlHelper
arguments:
$securityContext: "@security.context"
$firewall: '@security.firewall.map'
$accessDecisionManager: '@security.access.decision_manager'
$accessMap: '@security.access_map'
...
src /我/应用程序/AuthenticationBundle/Security/AccessControlHelper.php
declare(strict_types=1);
namespace My\Application\AuthenticationBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Http\Firewall\AccessListener;
use Symfony\Component\Security\Http\FirewallMapInterface;
class AccessControlHelper
{
/**
* @var SecurityContextInterface
*/
protected $securityContext;
/**
* @var FirewallMapInterface
*/
protected $firewallMap;
/**
* @var AccessDecisionManagerInterface
*/
protected $accessDecisionManager;
/**
* @var AccessMapInterface
*/
protected $accessMap;
public function __construct(
SecurityContextInterface $securityContext,
FirewallMapInterface $firewallMap,
AccessDecisionManagerInterface $accessDecisionManager,
AccessMapInterface $accessMap
)
{
$this->securityContext = $securityContext;
$this->firewallMap = $firewallMap;
$this->accessDecisionManager = $accessDecisionManager;
$this->accessMap = $accessMap;
}
public function isRequestAccessible(Request $request): bool
{
$token = $this->securityContext->getToken();
if (!$token || false == $token->isAuthenticated()) {
return false;
}
list($listeners) = $this->firewallMap->getListeners($request);
if ($listeners) {
foreach ($listeners as $listener) {
if ($listener instanceof AccessListener) {
/**
* Logic here is much inspired by the AccessListener->handle(...) method.
*/
list($attributes) = $this->accessMap->getPatterns($request);
if (null === $attributes) {
continue;
}
return boolval($this->accessDecisionManager->decide($token, $attributes, $request));
}
}
}
return true;
}
public function isUriAccessible(string $uri)
{
return $this->isRequestAccessible(Request::create($uri));
}
}
样品用量:
use My\Application\AuthenticationBundle\Security\AccessControlHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
$container = ...; // @var ContainerInterface
$accessControlHelper = $container->get(AccessControlHelper::class);
$accessControlHelper->isRequestAccessible(new Request("/foo"));
$accessControlHelper->isUriAccessible("/foo");