1
+ <?php
2
+
3
+ /* For licensing terms, see /license.txt */
4
+
5
+ declare (strict_types=1 );
6
+
7
+ namespace Chamilo \CoreBundle \Security \Authenticator ;
8
+
9
+ use Lexik \Bundle \JWTAuthenticationBundle \Services \JWTTokenManagerInterface ;
10
+ use Symfony \Component \HttpFoundation \RedirectResponse ;
11
+ use Symfony \Component \HttpFoundation \Request ;
12
+ use Symfony \Component \HttpFoundation \Response ;
13
+ use Symfony \Component \Routing \RouterInterface ;
14
+ use Symfony \Component \Security \Core \Authentication \Token \TokenInterface ;
15
+ use Symfony \Component \Security \Core \Exception \AuthenticationException ;
16
+ use Symfony \Component \Security \Core \User \UserProviderInterface ;
17
+ use Symfony \Component \Security \Http \Authenticator \AbstractAuthenticator ;
18
+ use Symfony \Component \Security \Http \Authenticator \Passport \Badge \UserBadge ;
19
+ use Symfony \Component \Security \Http \Authenticator \Passport \Passport ;
20
+ use Symfony \Component \Security \Http \Authenticator \Passport \SelfValidatingPassport ;
21
+
22
+ class LoginTokenAuthenticator extends AbstractAuthenticator
23
+ {
24
+ public function __construct (
25
+ protected readonly UserProviderInterface $ userProvider ,
26
+ protected readonly RouterInterface $ router ,
27
+ protected readonly JWTTokenManagerInterface $ jwtManager
28
+ ) {}
29
+
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ public function supports (Request $ request ): ?bool
34
+ {
35
+ return $ request ->attributes ->get ('_route ' ) === 'login_token_check '
36
+ && $ request ->headers ->has ('Authorization ' )
37
+ ;
38
+ }
39
+
40
+ /**
41
+ * @inheritDoc
42
+ */
43
+ public function authenticate (Request $ request ): Passport
44
+ {
45
+ $ authHeader = $ request ->headers ->get ('Authorization ' );
46
+
47
+ if (!$ authHeader || !str_starts_with ($ authHeader , 'Bearer ' )) {
48
+ throw new AuthenticationException ('Missing token. ' );
49
+ }
50
+
51
+ $ jwt = substr ($ authHeader , 7 );
52
+
53
+ try {
54
+ $ payload = $ this ->jwtManager ->parse ($ jwt );
55
+ $ username = $ payload ['username ' ] ?? $ payload ['sub ' ] ?? null ;
56
+
57
+ if (!$ username ) {
58
+ throw new AuthenticationException ('Token does not contain a username. ' );
59
+ }
60
+
61
+ } catch (\Exception $ e ) {
62
+ throw new AuthenticationException ('Invalid JWT token: ' .$ e ->getMessage ());
63
+ }
64
+
65
+ return new SelfValidatingPassport (
66
+ new UserBadge (
67
+ $ username ,
68
+ fn (string $ username ) => $ this ->userProvider ->loadUserByIdentifier ($ username )
69
+ )
70
+ );
71
+ }
72
+
73
+ /**
74
+ * @inheritDoc
75
+ */
76
+ public function onAuthenticationSuccess (Request $ request , TokenInterface $ token , string $ firewallName ): ?Response
77
+ {
78
+ $ targetUrl = $ this ->router ->generate ('index ' );
79
+
80
+ return new RedirectResponse ($ targetUrl );
81
+ }
82
+
83
+ /**
84
+ * @inheritDoc
85
+ */
86
+ public function onAuthenticationFailure (Request $ request , AuthenticationException $ exception ): ?Response
87
+ {
88
+ $ message = strtr ($ exception ->getMessage (), $ exception ->getMessageData ());
89
+
90
+ return new Response ($ message , Response::HTTP_FORBIDDEN );
91
+ }
92
+ }
0 commit comments