[!!!][TASK] Remove leftover deprecated hooks
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Middleware / FrontendUserAuthenticator.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Frontend\Middleware;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
20 use Psr\Http\Server\MiddlewareInterface;
21 use Psr\Http\Server\RequestHandlerInterface;
22 use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
23 use TYPO3\CMS\Core\Context\Context;
24 use TYPO3\CMS\Core\Context\UserAspect;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
27
28 /**
29 * This middleware authenticates a Frontend User (fe_users).
30 * A valid $GLOBALS['TSFE'] object is needed for the time being, being fully backwards-compatible.
31 */
32 class FrontendUserAuthenticator implements MiddlewareInterface
33 {
34 /**
35 * Creates a frontend user authentication object, tries to authenticate a user
36 * and stores the object in $GLOBALS['TSFE']->fe_user.
37 *
38 * @param ServerRequestInterface $request
39 * @param RequestHandlerInterface $handler
40 * @return ResponseInterface
41 */
42 public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
43 {
44 $frontendUser = GeneralUtility::makeInstance(FrontendUserAuthentication::class);
45
46 // List of page IDs where to look for frontend user records
47 $pid = $request->getParsedBody()['pid'] ?? $request->getQueryParams()['pid'] ?? 0;
48 if ($pid) {
49 $frontendUser->checkPid_value = implode(',', GeneralUtility::intExplode(',', $pid));
50 }
51
52 // Check if a session is transferred, and update the cookie parameters
53 $frontendSessionKey = $request->getParsedBody()['FE_SESSION_KEY'] ?? $request->getQueryParams()['FE_SESSION_KEY'] ?? '';
54 if ($frontendSessionKey) {
55 $request = $this->transferFrontendUserSession($frontendUser, $request, $frontendSessionKey);
56 }
57
58 // Authenticate now
59 $frontendUser->start();
60 $frontendUser->unpack_uc();
61
62 // Keep the backwards-compatibility for TYPO3 v9, to have the fe_user within the global TSFE object
63 $GLOBALS['TSFE']->fe_user = $frontendUser;
64
65 // Register the frontend user as aspect
66 $this->setFrontendUserAspect(GeneralUtility::makeInstance(Context::class), $frontendUser);
67
68 return $handler->handle($request);
69 }
70
71 /**
72 * It's possible to transfer a frontend user session via a GET/POST parameter 'FE_SESSION_KEY'.
73 * In the future, this logic should be moved into the FrontendUserAuthentication object directly,
74 * but only if FrontendUserAuthentication does not request superglobals (like $_COOKIE) anymore.
75 *
76 * @param FrontendUserAuthentication $frontendUser
77 * @param ServerRequestInterface $request
78 * @param string $frontendSessionKey
79 * @return ServerRequestInterface
80 */
81 protected function transferFrontendUserSession(
82 FrontendUserAuthentication $frontendUser,
83 ServerRequestInterface $request,
84 string $frontendSessionKey
85 ): ServerRequestInterface {
86 list($sessionId, $hash) = explode('-', $frontendSessionKey);
87 // If the session key hash check is OK, set the cookie
88 if (md5($sessionId . '/' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) === (string)$hash) {
89 $cookieName = FrontendUserAuthentication::getCookieName();
90
91 // keep the global cookie overwriting for now, as long as FrontendUserAuthentication does not
92 // use the request object for fetching the cookie information.
93 $_COOKIE[$cookieName] = $sessionId;
94 if (isset($_SERVER['HTTP_COOKIE'])) {
95 // See http://forge.typo3.org/issues/27740
96 $_SERVER['HTTP_COOKIE'] .= ';' . $cookieName . '=' . $sessionId;
97 }
98 // Add the cookie to the Server Request object
99 $cookieParams = $request->getCookieParams();
100 $cookieParams[$cookieName] = $sessionId;
101 $request = $request->withCookieParams($cookieParams);
102 // @deprecated: we override the current request because it was enriched by cookie information here.
103 $GLOBALS['TYPO3_REQUEST'] = $request;
104 $frontendUser->forceSetCookie = true;
105 $frontendUser->dontSetCookie = false;
106 }
107 return $request;
108 }
109
110 /**
111 * Register the frontend user as aspect
112 *
113 * @param Context $context
114 * @param AbstractUserAuthentication $user
115 */
116 protected function setFrontendUserAspect(Context $context, AbstractUserAuthentication $user)
117 {
118 $context->setAspect('frontend.user', GeneralUtility::makeInstance(UserAspect::class, $user));
119 }
120 }