diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
index 48e6c95998c7a..4dd0b021fe9d2 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
@@ -28,6 +28,25 @@
border: 0;
padding: 0 0 8px 0;
}
+
+ #collector-content .authenticators .badge {
+ color: var(--white);
+ display: inline-block;
+ text-align: center;
+ }
+ #collector-content .authenticators .badge.badge-resolved {
+ background-color: var(--green-500);
+ }
+ #collector-content .authenticators .badge.badge-not_resolved {
+ background-color: var(--yellow-500);
+ }
+
+ #collector-content .authenticators svg[data-icon-name="icon-tabler-check"] {
+ color: var(--green-500);
+ }
+ #collector-content .authenticators svg[data-icon-name="icon-tabler-x"] {
+ color: var(--red-500);
+ }
{% endblock %}
@@ -316,13 +335,15 @@
{% if collector.authenticators|default([]) is not empty %}
-
+
Authenticator |
Supports |
+ Authenticated |
Duration |
Passport |
+ Badges |
@@ -340,8 +361,18 @@
{{ profiler_dump(authenticator.stub) }} |
{{ source('@WebProfiler/Icon/' ~ (authenticator.supports ? 'yes' : 'no') ~ '.svg') }} |
+ {{ authenticator.authenticated is not null ? source('@WebProfiler/Icon/' ~ (authenticator.authenticated ? 'yes' : 'no') ~ '.svg') : '' }} |
{{ '%0.2f'|format(authenticator.duration * 1000) }} ms |
{{ authenticator.passport ? profiler_dump(authenticator.passport) : '(none)' }} |
+
+ {% for badge in authenticator.badges ?? [] %}
+
+ {{ badge.stub|abbr_class }}
+
+ {% else %}
+ (none)
+ {% endfor %}
+ |
{% if loop.last %}
diff --git a/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticator.php
index b142ec510e6bc..794f3e00c1716 100644
--- a/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticator.php
+++ b/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticator.php
@@ -17,6 +17,7 @@
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface;
+use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\EntryPoint\Exception\NotAnEntryPointException;
@@ -29,14 +30,13 @@
*/
final class TraceableAuthenticator implements AuthenticatorInterface, InteractiveAuthenticatorInterface, AuthenticationEntryPointInterface
{
- private AuthenticatorInterface $authenticator;
private ?Passport $passport = null;
private ?float $duration = null;
private ClassStub|string $stub;
+ private ?bool $authenticated = null;
- public function __construct(AuthenticatorInterface $authenticator)
+ public function __construct(private AuthenticatorInterface $authenticator)
{
- $this->authenticator = $authenticator;
}
public function getInfo(): array
@@ -46,6 +46,16 @@ public function getInfo(): array
'passport' => $this->passport,
'duration' => $this->duration,
'stub' => $this->stub ??= class_exists(ClassStub::class) ? new ClassStub($this->authenticator::class) : $this->authenticator::class,
+ 'authenticated' => $this->authenticated,
+ 'badges' => array_map(
+ static function (BadgeInterface $badge): array {
+ return [
+ 'stub' => class_exists(ClassStub::class) ? new ClassStub($badge::class) : $badge::class,
+ 'resolved' => $badge->isResolved(),
+ ];
+ },
+ $this->passport->getBadges(),
+ ),
];
}
@@ -70,11 +80,15 @@ public function createToken(Passport $passport, string $firewallName): TokenInte
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
+ $this->authenticated = true;
+
return $this->authenticator->onAuthenticationSuccess($request, $token, $firewallName);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
+ $this->authenticated = false;
+
return $this->authenticator->onAuthenticationFailure($request, $exception);
}
diff --git a/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticatorManagerListener.php b/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticatorManagerListener.php
index 2e933a32e8c49..218a38ef79c32 100644
--- a/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticatorManagerListener.php
+++ b/src/Symfony/Component/Security/Http/Authenticator/Debug/TraceableAuthenticatorManagerListener.php
@@ -53,6 +53,8 @@ public function authenticate(RequestEvent $event): void
'stub' => $this->hasVardumper ? new ClassStub($skippedAuthenticator::class) : $skippedAuthenticator::class,
'passport' => null,
'duration' => 0,
+ 'authenticated' => null,
+ 'badges' => [],
];
}