Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita9dea1d

Browse files
committed
[Security] Added debug:firewall command
1 parentd1fbf75 commita9dea1d

File tree

4 files changed

+318
-1
lines changed

4 files changed

+318
-1
lines changed

‎src/Symfony/Bundle/SecurityBundle/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
5.3
55
---
66

7+
* Add the`debug:firewall` command.
78
* Deprecate`UserPasswordEncoderCommand` class and the corresponding`user:encode-password` command,
89
use`UserPasswordHashCommand` and`user:hash-password` instead
910
* Deprecate the`security.encoder_factory.generic` service, the`security.encoder_factory` and`Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface` aliases,
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Bundle\SecurityBundle\Command;
13+
14+
usePsr\Container\ContainerInterface;
15+
useSymfony\Bundle\SecurityBundle\Security\FirewallContext;
16+
useSymfony\Bundle\SecurityBundle\Security\LazyFirewallContext;
17+
useSymfony\Component\Console\Command\Command;
18+
useSymfony\Component\Console\Input\InputArgument;
19+
useSymfony\Component\Console\Input\InputInterface;
20+
useSymfony\Component\Console\Input\InputOption;
21+
useSymfony\Component\Console\Output\OutputInterface;
22+
useSymfony\Component\Console\Style\SymfonyStyle;
23+
useSymfony\Component\EventDispatcher\EventDispatcherInterface;
24+
useSymfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
25+
26+
/**
27+
* @author Timo Bakx <timobakx@gmail.com>
28+
*/
29+
finalclass DebugFirewallCommandextends Command
30+
{
31+
protectedstatic$defaultName ='debug:firewall';
32+
protectedstatic$defaultDescription ='Displays information about your security firewall(s)';
33+
34+
private$firewallNames;
35+
private$contexts;
36+
private$eventDispatchers;
37+
private$authenticators;
38+
private$authenticatorManagerEnabled;
39+
40+
/**
41+
* @param string[] $firewallNames
42+
* @param AuthenticatorInterface[][] $authenticators
43+
*/
44+
publicfunction__construct(array$firewallNames,ContainerInterface$contexts,ContainerInterface$eventDispatchers,array$authenticators,bool$authenticatorManagerEnabled)
45+
{
46+
$this->firewallNames =$firewallNames;
47+
$this->contexts =$contexts;
48+
$this->eventDispatchers =$eventDispatchers;
49+
$this->authenticators =$authenticators;
50+
$this->authenticatorManagerEnabled =$authenticatorManagerEnabled;
51+
52+
parent::__construct();
53+
}
54+
55+
protectedfunctionconfigure():void
56+
{
57+
$exampleName =$this->getExampleName();
58+
59+
$this
60+
->setDescription(self::$defaultDescription)
61+
->setHelp(<<<EOF
62+
The <info>%command.name%</info> command displays the firewalls that are configured
63+
in your application:
64+
65+
<info>php %command.full_name%</info>
66+
67+
You can pass a firewall name to display more detailed information about
68+
a specific firewall:
69+
70+
<info>php %command.full_name%$exampleName</info>
71+
72+
To include all events and event listeners for a specific firewall, use the
73+
<info>events</info> option:
74+
75+
<info>php %command.full_name% --events$exampleName</info>
76+
77+
EOF)
78+
->setDefinition([
79+
newInputArgument('name', InputArgument::OPTIONAL,sprintf('A firewall name (for example "%s")',$exampleName)),
80+
newInputOption('events',null, InputOption::VALUE_NONE,'Include a list of event listeners (only available in combination with the "name" argument)'),
81+
]);
82+
}
83+
84+
protectedfunctionexecute(InputInterface$input,OutputInterface$output):int
85+
{
86+
$io =newSymfonyStyle($input,$output);
87+
88+
$name =$input->getArgument('name');
89+
90+
if (null ===$name) {
91+
$this->displayFirewallList($io);
92+
93+
return0;
94+
}
95+
96+
$serviceId =sprintf('security.firewall.map.context.%s',$name);
97+
98+
if (!$this->contexts->has($serviceId)) {
99+
$io->error(sprintf('Firewall %s was not found. Available firewalls are: %s',$name,implode(',',$this->firewallNames)));
100+
101+
return1;
102+
}
103+
104+
/** @var FirewallContext $context */
105+
$context =$this->contexts->get($serviceId);
106+
107+
$io->title(sprintf('Firewall "%s"',$name));
108+
109+
$this->displayFirewallSummary($name,$context,$io);
110+
111+
$this->displaySwitchUser($context,$io);
112+
113+
if ($input->getOption('events')) {
114+
$this->displayEventListeners($name,$context,$io);
115+
}
116+
117+
if ($this->authenticatorManagerEnabled) {
118+
$this->displayAuthenticators($name,$io);
119+
}
120+
121+
return0;
122+
}
123+
124+
protectedfunctiondisplayFirewallList(SymfonyStyle$io):void
125+
{
126+
$io->title('Firewalls');
127+
$io->text('The following firewalls are defined:');
128+
129+
$io->listing($this->firewallNames);
130+
131+
$io->comment(sprintf('To view details of a specific firewall, re-run this command with a firewall name. (e.g. <comment>debug:firewall %s</comment>)',$this->getExampleName()));
132+
}
133+
134+
protectedfunctiondisplayFirewallSummary(string$name,FirewallContext$context,SymfonyStyle$io):void
135+
{
136+
if (null ===$context->getConfig()) {
137+
return;
138+
}
139+
140+
$rows = [
141+
['Name',$name],
142+
['Context',$context->getConfig()->getContext()],
143+
['Lazy',$contextinstanceof LazyFirewallContext ?'Yes' :'No'],
144+
['Stateless',$context->getConfig()->isStateless() ?'Yes' :'No'],
145+
['User Checker',$context->getConfig()->getUserChecker()],
146+
['Provider',$context->getConfig()->getProvider()],
147+
['Entry Point',$context->getConfig()->getEntryPoint()],
148+
['Access Denied URL',$context->getConfig()->getAccessDeniedUrl()],
149+
['Access Denied Handler',$context->getConfig()->getAccessDeniedHandler()],
150+
];
151+
152+
$io->table(
153+
['Option','Value'],
154+
$rows
155+
);
156+
}
157+
158+
privatefunctiondisplaySwitchUser(FirewallContext$context,SymfonyStyle$io)
159+
{
160+
if ((null ===$config =$context->getConfig()) || (null ===$switchUser =$config->getSwitchUser())) {
161+
return;
162+
}
163+
164+
$io->section('User switching');
165+
166+
$io->table(['Option','Value'], [
167+
['Parameter',$switchUser['parameter'] ??''],
168+
['Provider',$switchUser['provider'] ??$config->getProvider()],
169+
['User Role',$switchUser['role'] ??''],
170+
]);
171+
}
172+
173+
protectedfunctiondisplayEventListeners(string$name,FirewallContext$context,SymfonyStyle$io):void
174+
{
175+
$io->title(sprintf('Event listeners for firewall "%s"',$name));
176+
177+
$dispatcherId =sprintf('security.event_dispatcher.%s',$name);
178+
179+
if (!$this->eventDispatchers->has($dispatcherId)) {
180+
$io->text('No event dispatcher has been registered for this firewall.');
181+
182+
return;
183+
}
184+
185+
/** @var EventDispatcherInterface $dispatcher */
186+
$dispatcher =$this->eventDispatchers->get($dispatcherId);
187+
188+
foreach ($dispatcher->getListeners()as$event =>$listeners) {
189+
$io->section(sprintf('"%s" event',$event));
190+
191+
$rows = [];
192+
foreach ($listenersas$order =>$listener) {
193+
$rows[] = [
194+
sprintf('#%d',$order +1),
195+
$this->formatCallable($listener),
196+
$dispatcher->getListenerPriority($event,$listener),
197+
];
198+
}
199+
200+
$io->table(
201+
['Order','Callable','Priority'],
202+
$rows
203+
);
204+
}
205+
}
206+
207+
privatefunctiondisplayAuthenticators(string$name,SymfonyStyle$io):void
208+
{
209+
$io->title(sprintf('Authenticators for firewall "%s"',$name));
210+
211+
$authenticators =$this->authenticators[$name] ?? [];
212+
213+
if (0 ===\count($authenticators)) {
214+
$io->text('No authenticators have been registered for this firewall.');
215+
216+
return;
217+
}
218+
219+
$io->table(
220+
['Classname'],
221+
array_map(
222+
staticfunction ($authenticator) {
223+
return [
224+
\get_class($authenticator),
225+
];
226+
},
227+
$authenticators
228+
)
229+
);
230+
}
231+
232+
privatefunctionformatCallable($callable):string
233+
{
234+
if (\is_array($callable)) {
235+
if (\is_object($callable[0])) {
236+
returnsprintf('%s::%s()',\get_class($callable[0]),$callable[1]);
237+
}
238+
239+
returnsprintf('%s::%s()',$callable[0],$callable[1]);
240+
}
241+
242+
if (\is_string($callable)) {
243+
returnsprintf('%s()',$callable);
244+
}
245+
246+
if ($callableinstanceof \Closure) {
247+
$r =new \ReflectionFunction($callable);
248+
if (false !==strpos($r->name,'{closure}')) {
249+
return'Closure()';
250+
}
251+
if ($class =$r->getClosureScopeClass()) {
252+
returnsprintf('%s::%s()',$class->name,$r->name);
253+
}
254+
255+
return$r->name.'()';
256+
}
257+
258+
if (method_exists($callable,'__invoke')) {
259+
returnsprintf('%s::__invoke()',\get_class($callable));
260+
}
261+
262+
thrownew \InvalidArgumentException('Callable is not describable.');
263+
}
264+
265+
privatefunctiongetExampleName():string
266+
{
267+
$name ='main';
268+
269+
if (!\in_array($name,$this->firewallNames,true)) {
270+
$name =reset($this->firewallNames);
271+
}
272+
273+
return$name;
274+
}
275+
}

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ public function load(array $configs, ContainerBuilder $container)
164164
$container->setParameter('security.access.always_authenticate_before_granting',$config['always_authenticate_before_granting']);
165165
$container->setParameter('security.authentication.hide_user_not_found',$config['hide_user_not_found']);
166166

167+
if (class_exists(Application::class)) {
168+
$loader->load('debug_console.php');
169+
$debugCommand =$container->getDefinition('security.command.debug_firewall');
170+
$debugCommand->replaceArgument(4,$this->authenticatorManagerEnabled);
171+
}
172+
167173
$this->createFirewalls($config,$container);
168174
$this->createAuthorization($config,$container);
169175
$this->createRoleHierarchy($config,$container);
@@ -298,7 +304,10 @@ private function createFirewalls(array $config, ContainerBuilder $container)
298304
$contextRefs[$contextId] =newReference($contextId);
299305
$map[$contextId] =$matcher;
300306
}
301-
$mapDef->replaceArgument(0, ServiceLocatorTagPass::register($container,$contextRefs));
307+
308+
$container->setAlias('security.firewall.context_locator', (string) ServiceLocatorTagPass::register($container,$contextRefs));
309+
310+
$mapDef->replaceArgument(0,newReference('security.firewall.context_locator'));
302311
$mapDef->replaceArgument(1,newIteratorArgument($map));
303312

304313
if (!$this->authenticatorManagerEnabled) {
@@ -503,6 +512,10 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
503512
->addTag('kernel.event_subscriber', ['dispatcher' =>$firewallEventDispatcherId]);
504513

505514
$listeners[] =newReference('security.firewall.authenticator.'.$id);
515+
516+
// Add authenticators to the debug:firewall command
517+
$debugCommand =$container->getDefinition('security.command.debug_firewall');
518+
$debugCommand->replaceArgument(3,array_merge($debugCommand->getArgument(3), [$id =>$authenticators]));
506519
}
507520

508521
$config->replaceArgument(7,$configuredEntryPoint ?:$defaultEntryPoint);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\DependencyInjection\Loader\Configurator;
13+
14+
useSymfony\Bundle\SecurityBundle\Command\DebugFirewallCommand;
15+
16+
returnstaticfunction (ContainerConfigurator$container) {
17+
$container->services()
18+
->set('security.command.debug_firewall', DebugFirewallCommand::class)
19+
->args([
20+
param('security.firewalls'),
21+
service('security.firewall.context_locator'),
22+
tagged_locator('event_dispatcher.dispatcher'),
23+
[],
24+
false,
25+
])
26+
->tag('console.command', ['command' =>'debug:firewall'])
27+
;
28+
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp