-
Notifications
You must be signed in to change notification settings - Fork 104
Expand file tree
/
Copy pathAuthenticationMiddleware.php
More file actions
126 lines (112 loc) · 4.69 KB
/
AuthenticationMiddleware.php
File metadata and controls
126 lines (112 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 1.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Authentication\Middleware;
use Authentication\AuthenticationServiceInterface;
use Authentication\AuthenticationServiceProviderInterface;
use Authentication\Authenticator\AuthenticationRequiredException;
use Authentication\Authenticator\StatelessInterface;
use Authentication\Authenticator\UnauthenticatedException;
use Laminas\Diactoros\Response;
use Laminas\Diactoros\Response\RedirectResponse;
use Laminas\Diactoros\Stream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
/**
* Authentication Middleware
*/
class AuthenticationMiddleware implements MiddlewareInterface
{
/**
* Authentication service or application instance.
*
* @var \Authentication\AuthenticationServiceInterface|\Authentication\AuthenticationServiceProviderInterface
*/
protected AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject;
/**
* Constructor
*
* @param \Authentication\AuthenticationServiceInterface|\Authentication\AuthenticationServiceProviderInterface $subject Authentication service or application instance.
* @throws \InvalidArgumentException When invalid subject has been passed.
*/
public function __construct(
AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject
) {
$this->subject = $subject;
}
/**
* Callable implementation for the middleware stack.
*
* @param \Psr\Http\Message\ServerRequestInterface $request The request.
* @param \Psr\Http\Server\RequestHandlerInterface $handler The request handler.
* @return \Psr\Http\Message\ResponseInterface A response.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$service = $this->getAuthenticationService($request);
try {
$result = $service->authenticate($request);
} catch (AuthenticationRequiredException $e) {
$body = new Stream('php://memory', 'rw');
$body->write($e->getBody());
$response = new Response();
$response = $response->withStatus($e->getCode())
->withBody($body);
foreach ($e->getHeaders() as $header => $value) {
$response = $response->withHeader($header, $value);
}
return $response;
}
$request = $request->withAttribute($service->getIdentityAttribute(), $service->getIdentity());
$request = $request->withAttribute('authentication', $service);
$request = $request->withAttribute('authenticationResult', $result);
try {
$response = $handler->handle($request);
$authenticator = $service->getAuthenticationProvider();
if ($authenticator !== null && !$authenticator instanceof StatelessInterface) {
/**
* @psalm-suppress PossiblyNullArgument
* @phpstan-ignore-next-line
*/
$return = $service->persistIdentity($request, $response, $result->getData());
$response = $return['response'];
}
} catch (UnauthenticatedException $e) {
$url = $service->getUnauthenticatedRedirectUrl($request);
if ($url) {
return new RedirectResponse($url);
}
throw $e;
}
return $response;
}
/**
* Returns AuthenticationServiceInterface instance.
*
* @param \Psr\Http\Message\ServerRequestInterface $request Server request.
* @return \Authentication\AuthenticationServiceInterface
* @throws \RuntimeException When authentication method has not been defined.
*/
protected function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
$subject = $this->subject;
if ($subject instanceof AuthenticationServiceProviderInterface) {
$subject = $subject->getAuthenticationService($request);
}
return $subject;
}
}