• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TYPO3GmbH / symfony-keycloak-bundle / 18338394949

08 Oct 2025 08:19AM UTC coverage: 4.405% (-0.02%) from 4.425%
18338394949

Pull #21

github

web-flow
Merge f9ea55bad into 5798572fc
Pull Request #21: [BUGFIX] Allow uppercase LDAP uids

0 of 3 new or added lines in 1 file covered. (0.0%)

10 of 227 relevant lines covered (4.41%)

9.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Security/KeyCloakAuthenticator.php
1
<?php
2
declare(strict_types=1);
3

4
/*
5
 * This file is part of the package t3g/symfony-keycloak-bundle.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE file that was distributed with this source code.
9
 */
10

11
namespace T3G\Bundle\Keycloak\Security;
12

13
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
14
use KnpU\OAuth2ClientBundle\Client\OAuth2ClientInterface;
15
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
16
use Symfony\Component\HttpFoundation\RedirectResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpFoundation\Session\SessionInterface;
21
use Symfony\Component\Routing\RouterInterface;
22
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
23
use Symfony\Component\Security\Core\Exception\AuthenticationException;
24
use Symfony\Component\Security\Core\User\UserProviderInterface;
25
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
26
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
27
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
28
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
29
use T3G\Bundle\Keycloak\Service\RedirectService;
30
use T3G\Bundle\Keycloak\Service\TokenService;
31

32
class KeyCloakAuthenticator extends OAuth2Authenticator implements AuthenticationEntrypointInterface
33
{
34
    public const SESSION_KEYCLOAK_ACCESS_TOKEN = 'keycloak_access_token';
35
    private OAuth2ClientInterface $client;
36
    private SessionInterface $session;
37
    private RouterInterface $router;
38
    private UserProviderInterface $userProvider;
39
    private TokenService $tokenService;
40
    private RedirectService $redirectService;
41
    private ?string $routeAuthentication;
42
    private ?string $routeSuccess;
43

44
    /**
45
     * @param KeyCloakUserProvider $userProvider
46
     */
47
    public function __construct(ClientRegistry $clientRegistry, RequestStack $requestStack, RouterInterface $router, UserProviderInterface $userProvider, TokenService $tokenService, RedirectService $redirectService, ?string $routeAuthentication = null, ?string $routeSuccess = null)
48
    {
49
        $this->client = $clientRegistry->getClient('keycloak');
×
50
        $this->session = $requestStack->getSession();
×
51
        $this->router = $router;
×
52
        $this->userProvider = $userProvider;
×
53
        $this->tokenService = $tokenService;
×
54
        $this->redirectService = $redirectService;
×
55
        $this->routeAuthentication = $routeAuthentication;
×
56
        $this->routeSuccess = $routeSuccess;
×
57
    }
58

59
    public function supports(Request $request): ?bool
60
    {
61
        return $this->routeAuthentication === $request->attributes->get('_route');
×
62
    }
63

64
    public function authenticate(Request $request): Passport
65
    {
66
        $accessToken = $this->fetchAccessToken($this->client);
×
67
        $this->session->set(self::SESSION_KEYCLOAK_ACCESS_TOKEN, $accessToken);
×
68
        $userData = $this->tokenService->fetchUserData();
×
NEW
69
        $preferredUsername = strtolower($userData['preferred_username']);
×
70

71
        return new SelfValidatingPassport(
×
NEW
72
            new UserBadge($preferredUsername, fn () => $this->userProvider->loadUserByIdentifier(
×
NEW
73
                $preferredUsername,
×
74
                $userData['realm_access']['roles'] ?? [],
×
75
                $this->tokenService->getScopes(),
×
76
                $userData['email'] ?? null,
×
77
                $userData['name'] ?? null,
×
78
                true
×
79
            ))
×
80
        );
×
81
    }
82

83
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
84
    {
85
        if (null === $this->routeSuccess) {
×
86
            return null;
×
87
        }
88

89
        $redirectUrl = $this->getPreviousUrl($request, $firewallName);
×
90
        if (null === $redirectUrl || '' === $redirectUrl) {
×
91
            $redirectUrl = $this->router->generate($this->routeSuccess);
×
92
        }
93

94
        return new RedirectResponse(
×
95
            $redirectUrl,
×
96
            Response::HTTP_TEMPORARY_REDIRECT
×
97
        );
×
98
    }
99

100
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
101
    {
102
        $message = strtr($exception->getMessageKey(), $exception->getMessageData());
×
103

104
        return new Response($message, Response::HTTP_FORBIDDEN);
×
105
    }
106

107
    /**
108
     * Called when authentication is needed, but it's not sent.
109
     * This redirects to the 'login'.
110
     */
111
    public function start(Request $request, AuthenticationException $authException = null): Response
112
    {
113
        return $this->redirectService->generateLoginRedirectResponse();
×
114
    }
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc