303 lines
9.6 KiB
PHP
303 lines
9.6 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Bundle\SecurityBundle\DataCollector;
|
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
|
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
|
use Symfony\Component\Security\Core\Role\RoleInterface;
|
|
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
|
|
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
|
use Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager;
|
|
use Symfony\Component\VarDumper\Cloner\Data;
|
|
use Symfony\Component\Security\Http\FirewallMapInterface;
|
|
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
|
|
|
|
/**
|
|
* SecurityDataCollector.
|
|
*
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
|
*/
|
|
class SecurityDataCollector extends DataCollector
|
|
{
|
|
private $tokenStorage;
|
|
private $roleHierarchy;
|
|
private $logoutUrlGenerator;
|
|
private $accessDecisionManager;
|
|
private $firewallMap;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param TokenStorageInterface|null $tokenStorage
|
|
* @param RoleHierarchyInterface|null $roleHierarchy
|
|
* @param LogoutUrlGenerator|null $logoutUrlGenerator
|
|
* @param AccessDecisionManagerInterface|null $accessDecisionManager
|
|
* @param FirewallMapInterface|null $firewallMap
|
|
*/
|
|
public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null, FirewallMapInterface $firewallMap = null)
|
|
{
|
|
$this->tokenStorage = $tokenStorage;
|
|
$this->roleHierarchy = $roleHierarchy;
|
|
$this->logoutUrlGenerator = $logoutUrlGenerator;
|
|
$this->accessDecisionManager = $accessDecisionManager;
|
|
$this->firewallMap = $firewallMap;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function collect(Request $request, Response $response, \Exception $exception = null)
|
|
{
|
|
if (null === $this->tokenStorage) {
|
|
$this->data = array(
|
|
'enabled' => false,
|
|
'authenticated' => false,
|
|
'token' => null,
|
|
'token_class' => null,
|
|
'logout_url' => null,
|
|
'user' => '',
|
|
'roles' => array(),
|
|
'inherited_roles' => array(),
|
|
'supports_role_hierarchy' => null !== $this->roleHierarchy,
|
|
);
|
|
} elseif (null === $token = $this->tokenStorage->getToken()) {
|
|
$this->data = array(
|
|
'enabled' => true,
|
|
'authenticated' => false,
|
|
'token' => null,
|
|
'token_class' => null,
|
|
'logout_url' => null,
|
|
'user' => '',
|
|
'roles' => array(),
|
|
'inherited_roles' => array(),
|
|
'supports_role_hierarchy' => null !== $this->roleHierarchy,
|
|
);
|
|
} else {
|
|
$inheritedRoles = array();
|
|
$assignedRoles = $token->getRoles();
|
|
|
|
if (null !== $this->roleHierarchy) {
|
|
$allRoles = $this->roleHierarchy->getReachableRoles($assignedRoles);
|
|
foreach ($allRoles as $role) {
|
|
if (!in_array($role, $assignedRoles, true)) {
|
|
$inheritedRoles[] = $role;
|
|
}
|
|
}
|
|
}
|
|
|
|
$logoutUrl = null;
|
|
try {
|
|
if (null !== $this->logoutUrlGenerator) {
|
|
$logoutUrl = $this->logoutUrlGenerator->getLogoutPath();
|
|
}
|
|
} catch (\Exception $e) {
|
|
// fail silently when the logout URL cannot be generated
|
|
}
|
|
|
|
$this->data = array(
|
|
'enabled' => true,
|
|
'authenticated' => $token->isAuthenticated(),
|
|
'token' => $this->cloneVar($token),
|
|
'token_class' => get_class($token),
|
|
'logout_url' => $logoutUrl,
|
|
'user' => $token->getUsername(),
|
|
'roles' => $this->cloneVar(array_map(function (RoleInterface $role) { return $role->getRole(); }, $assignedRoles)),
|
|
'inherited_roles' => $this->cloneVar(array_unique(array_map(function (RoleInterface $role) { return $role->getRole(); }, $inheritedRoles))),
|
|
'supports_role_hierarchy' => null !== $this->roleHierarchy,
|
|
);
|
|
}
|
|
|
|
// collect voters and access decision manager information
|
|
if ($this->accessDecisionManager instanceof DebugAccessDecisionManager) {
|
|
$this->data['access_decision_log'] = array_map(function ($decision) {
|
|
$decision['object'] = $this->cloneVar($decision['object']);
|
|
|
|
return $decision;
|
|
}, $this->accessDecisionManager->getDecisionLog());
|
|
|
|
$this->data['voter_strategy'] = $this->accessDecisionManager->getStrategy();
|
|
|
|
foreach ($this->accessDecisionManager->getVoters() as $voter) {
|
|
$this->data['voters'][] = get_class($voter);
|
|
}
|
|
} else {
|
|
$this->data['access_decision_log'] = array();
|
|
$this->data['voter_strategy'] = 'unknown';
|
|
$this->data['voters'] = array();
|
|
}
|
|
|
|
// collect firewall context information
|
|
$this->data['firewall'] = null;
|
|
if ($this->firewallMap instanceof FirewallMap) {
|
|
$firewallConfig = $this->firewallMap->getFirewallConfig($request);
|
|
if (null !== $firewallConfig) {
|
|
$this->data['firewall'] = array(
|
|
'name' => $firewallConfig->getName(),
|
|
'allows_anonymous' => $firewallConfig->allowsAnonymous(),
|
|
'request_matcher' => $firewallConfig->getRequestMatcher(),
|
|
'security_enabled' => $firewallConfig->isSecurityEnabled(),
|
|
'stateless' => $firewallConfig->isStateless(),
|
|
'provider' => $firewallConfig->getProvider(),
|
|
'context' => $firewallConfig->getContext(),
|
|
'entry_point' => $firewallConfig->getEntryPoint(),
|
|
'access_denied_handler' => $firewallConfig->getAccessDeniedHandler(),
|
|
'access_denied_url' => $firewallConfig->getAccessDeniedUrl(),
|
|
'user_checker' => $firewallConfig->getUserChecker(),
|
|
'listeners' => $this->cloneVar($firewallConfig->getListeners()),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if security is enabled.
|
|
*
|
|
* @return bool true if security is enabled, false otherwise
|
|
*/
|
|
public function isEnabled()
|
|
{
|
|
return $this->data['enabled'];
|
|
}
|
|
|
|
/**
|
|
* Gets the user.
|
|
*
|
|
* @return string The user
|
|
*/
|
|
public function getUser()
|
|
{
|
|
return $this->data['user'];
|
|
}
|
|
|
|
/**
|
|
* Gets the roles of the user.
|
|
*
|
|
* @return array The roles
|
|
*/
|
|
public function getRoles()
|
|
{
|
|
return $this->data['roles'];
|
|
}
|
|
|
|
/**
|
|
* Gets the inherited roles of the user.
|
|
*
|
|
* @return array The inherited roles
|
|
*/
|
|
public function getInheritedRoles()
|
|
{
|
|
return $this->data['inherited_roles'];
|
|
}
|
|
|
|
/**
|
|
* Checks if the data contains information about inherited roles. Still the inherited
|
|
* roles can be an empty array.
|
|
*
|
|
* @return bool true if the profile was contains inherited role information
|
|
*/
|
|
public function supportsRoleHierarchy()
|
|
{
|
|
return $this->data['supports_role_hierarchy'];
|
|
}
|
|
|
|
/**
|
|
* Checks if the user is authenticated or not.
|
|
*
|
|
* @return bool true if the user is authenticated, false otherwise
|
|
*/
|
|
public function isAuthenticated()
|
|
{
|
|
return $this->data['authenticated'];
|
|
}
|
|
|
|
/**
|
|
* Get the class name of the security token.
|
|
*
|
|
* @return string The token
|
|
*/
|
|
public function getTokenClass()
|
|
{
|
|
return $this->data['token_class'];
|
|
}
|
|
|
|
/**
|
|
* Get the full security token class as Data object.
|
|
*
|
|
* @return Data
|
|
*/
|
|
public function getToken()
|
|
{
|
|
return $this->data['token'];
|
|
}
|
|
|
|
/**
|
|
* Get the provider key (i.e. the name of the active firewall).
|
|
*
|
|
* @return string The provider key
|
|
*/
|
|
public function getLogoutUrl()
|
|
{
|
|
return $this->data['logout_url'];
|
|
}
|
|
|
|
/**
|
|
* Returns the FQCN of the security voters enabled in the application.
|
|
*
|
|
* @return string[]
|
|
*/
|
|
public function getVoters()
|
|
{
|
|
return $this->data['voters'];
|
|
}
|
|
|
|
/**
|
|
* Returns the strategy configured for the security voters.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getVoterStrategy()
|
|
{
|
|
return $this->data['voter_strategy'];
|
|
}
|
|
|
|
/**
|
|
* Returns the log of the security decisions made by the access decision manager.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAccessDecisionLog()
|
|
{
|
|
return $this->data['access_decision_log'];
|
|
}
|
|
|
|
/**
|
|
* Returns the configuration of the current firewall context.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getFirewall()
|
|
{
|
|
return $this->data['firewall'];
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function getName()
|
|
{
|
|
return 'security';
|
|
}
|
|
}
|