Skip to content

Commit 0375d4f

Browse files
committed
Require a logged in user to resolve an authoration request
1 parent 978087a commit 0375d4f

8 files changed

+116
-112
lines changed

src/Event/AuthorizationRequestResolveEvent.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,19 @@ final class AuthorizationRequestResolveEvent extends Event
4242
private $response;
4343

4444
/**
45-
* @var UserInterface|null
45+
* @var UserInterface
4646
*/
4747
private $user;
4848

4949
/**
5050
* @param Scope[] $scopes
5151
*/
52-
public function __construct(AuthorizationRequestInterface $authorizationRequest, array $scopes, ClientInterface $client)
52+
public function __construct(AuthorizationRequestInterface $authorizationRequest, array $scopes, ClientInterface $client, UserInterface $user)
5353
{
5454
$this->authorizationRequest = $authorizationRequest;
5555
$this->scopes = $scopes;
5656
$this->client = $client;
57+
$this->user = $user;
5758
}
5859

5960
public function getAuthorizationResolution(): bool
@@ -107,13 +108,6 @@ public function getUser(): ?UserInterface
107108
return $this->user;
108109
}
109110

110-
public function setUser(?UserInterface $user): self
111-
{
112-
$this->user = $user;
113-
114-
return $this;
115-
}
116-
117111
/**
118112
* @return Scope[]
119113
*/

src/Event/AuthorizationRequestResolveEventFactory.php

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,31 @@
66

77
use League\Bundle\OAuth2ServerBundle\Converter\ScopeConverterInterface;
88
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
9-
use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface;
9+
use Symfony\Bundle\SecurityBundle\Security;
10+
use Symfony\Component\Security\Core\Security as LegacySecurity;
1011

11-
class AuthorizationRequestResolveEventFactory
12-
{
13-
/**
14-
* @var ScopeConverterInterface
15-
*/
16-
private $scopeConverter;
17-
18-
/**
19-
* @var ClientManagerInterface
20-
*/
21-
private $clientManager;
22-
23-
public function __construct(ScopeConverterInterface $scopeConverter, ClientManagerInterface $clientManager)
12+
if (class_exists(Security::class)) {
13+
final class AuthorizationRequestResolveEventFactory
2414
{
25-
$this->scopeConverter = $scopeConverter;
26-
$this->clientManager = $clientManager;
27-
}
15+
use AuthorizationRequestResolveEventFactoryTrait;
2816

29-
public function fromAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): AuthorizationRequestResolveEvent
17+
public function __construct(ScopeConverterInterface $scopeConverter, ClientManagerInterface $clientManager, Security $security)
18+
{
19+
$this->scopeConverter = $scopeConverter;
20+
$this->clientManager = $clientManager;
21+
$this->security = $security;
22+
}
23+
}
24+
} else {
25+
final class AuthorizationRequestResolveEventFactory
3026
{
31-
$scopes = $this->scopeConverter->toDomainArray(array_values($authorizationRequest->getScopes()));
32-
33-
$client = $this->clientManager->find($authorizationRequest->getClient()->getIdentifier());
27+
use AuthorizationRequestResolveEventFactoryTrait;
3428

35-
if (null === $client) {
36-
throw new \RuntimeException(\sprintf('No client found for the given identifier \'%s\'.', $authorizationRequest->getClient()->getIdentifier()));
29+
public function __construct(ScopeConverterInterface $scopeConverter, ClientManagerInterface $clientManager, LegacySecurity $security)
30+
{
31+
$this->scopeConverter = $scopeConverter;
32+
$this->clientManager = $clientManager;
33+
$this->security = $security;
3734
}
38-
39-
return new AuthorizationRequestResolveEvent($authorizationRequest, $scopes, $client);
4035
}
4136
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace League\Bundle\OAuth2ServerBundle\Event;
6+
7+
use League\Bundle\OAuth2ServerBundle\Converter\ScopeConverterInterface;
8+
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
9+
use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface;
10+
use Symfony\Bundle\SecurityBundle\Security;
11+
use Symfony\Component\Security\Core\Security as LegacySecurity;
12+
13+
/**
14+
* @internal
15+
*/
16+
trait AuthorizationRequestResolveEventFactoryTrait
17+
{
18+
/**
19+
* @var ScopeConverterInterface
20+
*/
21+
private $scopeConverter;
22+
23+
/**
24+
* @var ClientManagerInterface
25+
*/
26+
private $clientManager;
27+
28+
/**
29+
* @var Security|LegacySecurity
30+
*/
31+
private $security;
32+
33+
public function fromAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): AuthorizationRequestResolveEvent
34+
{
35+
$scopes = $this->scopeConverter->toDomainArray(array_values($authorizationRequest->getScopes()));
36+
37+
$client = $this->clientManager->find($authorizationRequest->getClient()->getIdentifier());
38+
39+
if (null === $client) {
40+
throw new \RuntimeException(\sprintf('No client found for the given identifier \'%s\'.', $authorizationRequest->getClient()->getIdentifier()));
41+
}
42+
43+
$user = $this->security->getUser();
44+
if (null === $user) {
45+
throw new \RuntimeException('A logged in user is required to resolve the request authorization.');
46+
}
47+
48+
return new AuthorizationRequestResolveEvent($authorizationRequest, $scopes, $client, $user);
49+
}
50+
}

src/EventListener/AuthorizationRequestUserResolvingListener.php

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/EventListener/AuthorizationRequestUserResolvingListenerTrait.php

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/Resources/config/services.php

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use League\Bundle\OAuth2ServerBundle\Converter\UserConverterInterface;
2323
use League\Bundle\OAuth2ServerBundle\Event\AuthorizationRequestResolveEventFactory;
2424
use League\Bundle\OAuth2ServerBundle\EventListener\AddClientDefaultScopesListener;
25-
use League\Bundle\OAuth2ServerBundle\EventListener\AuthorizationRequestUserResolvingListener;
2625
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
2726
use League\Bundle\OAuth2ServerBundle\Manager\AuthorizationCodeManagerInterface;
2827
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
@@ -55,9 +54,11 @@
5554
use Nyholm\Psr7\Factory\Psr17Factory;
5655
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
5756
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
57+
use Symfony\Bundle\SecurityBundle\Security;
5858
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
5959
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
6060
use Symfony\Component\HttpFoundation\RequestStack;
61+
use Symfony\Component\Security\Core\Security as LegacySecurity;
6162

6263
return static function (ContainerConfigurator $container): void {
6364
$container->services()
@@ -206,18 +207,6 @@
206207
->tag('controller.service_arguments')
207208
->alias(AuthorizationController::class, 'league.oauth2_server.controller.authorization')
208209

209-
// Authorization listeners
210-
->set('league.oauth2_server.listener.authorization_request_user_resolving', AuthorizationRequestUserResolvingListener::class)
211-
->args([
212-
service('security.helper'),
213-
])
214-
->tag('kernel.event_listener', [
215-
'event' => OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE,
216-
'method' => 'onAuthorizationRequest',
217-
'priority' => 1024,
218-
])
219-
->alias(AuthorizationRequestUserResolvingListener::class, 'league.oauth2_server.listener.authorization_request_user_resolving')
220-
221210
// Token controller
222211
->set('league.oauth2_server.controller.token', TokenController::class)
223212
->args([
@@ -292,6 +281,7 @@
292281
->args([
293282
service(ScopeConverterInterface::class),
294283
service(ClientManagerInterface::class),
284+
service(class_exists(Security::class) ? Security::class : LegacySecurity::class),
295285
])
296286
->alias(AuthorizationRequestResolveEventFactory::class, 'league.oauth2_server.factory.authorization_request_resolve_event')
297287

tests/Acceptance/AuthorizationEndpointTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ protected function setUp(): void
3131
);
3232
}
3333

34+
private function loginUser(string $username = FixtureFactory::FIXTURE_USER, string $firewallContext = 'authorization'): void
35+
{
36+
$userProvider = static::getContainer()->get('security.user_providers');
37+
$user = method_exists($userProvider, 'loadUserByIdentifier') ? $userProvider->loadUserByIdentifier($username) : $userProvider->loadUserByUsername($username);
38+
$this->client->loginUser($user, $firewallContext);
39+
}
40+
3441
public function testSuccessfulCodeRequest(): void
3542
{
3643
$this->client
@@ -40,6 +47,8 @@ public function testSuccessfulCodeRequest(): void
4047
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
4148
});
4249

50+
$this->loginUser();
51+
4352
$this->client->request(
4453
'GET',
4554
'/authorize',
@@ -75,6 +84,8 @@ public function testSuccessfulPKCEAuthCodeRequest(): void
7584
'-_'
7685
);
7786

87+
$this->loginUser();
88+
7889
$this->client
7990
->getContainer()
8091
->get('event_dispatcher')
@@ -138,6 +149,8 @@ public function testAuthCodeRequestWithPublicClientWithoutCodeChallengeWhenTheCh
138149
$this->fail('This event should not have been dispatched.');
139150
});
140151

152+
$this->loginUser();
153+
141154
$this->client->request(
142155
'GET',
143156
'/authorize',
@@ -176,6 +189,8 @@ public function testAuthCodeRequestWithClientWhoIsNotAllowedToMakeARequestWithPl
176189
$this->fail('This event should not have been dispatched.');
177190
});
178191

192+
$this->loginUser();
193+
179194
$this->client->request(
180195
'GET',
181196
'/authorize',
@@ -220,6 +235,8 @@ public function testAuthCodeRequestWithClientWhoIsAllowedToMakeARequestWithPlain
220235
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
221236
});
222237

238+
$this->loginUser();
239+
223240
$this->client->request(
224241
'GET',
225242
'/authorize',
@@ -272,6 +289,8 @@ public function testSuccessfulTokenRequest(): void
272289
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
273290
});
274291

292+
$this->loginUser();
293+
275294
$this->client->request(
276295
'GET',
277296
'/authorize',
@@ -308,6 +327,8 @@ public function testCodeRequestRedirectToResolutionUri(): void
308327
]));
309328
});
310329

330+
$this->loginUser();
331+
311332
$this->client->request(
312333
'GET',
313334
'/authorize',
@@ -341,6 +362,8 @@ public function testAuthorizationRequestEventIsStoppedAfterSettingAResponse(): v
341362
]));
342363
}, 200);
343364

365+
$this->loginUser();
366+
344367
$this->client->request(
345368
'GET',
346369
'/authorize',
@@ -374,6 +397,8 @@ public function testAuthorizationRequestEventIsStoppedAfterResolution(): void
374397
);
375398
}, 100);
376399

400+
$this->loginUser();
401+
377402
$this->client->request(
378403
'GET',
379404
'/authorize',
@@ -406,6 +431,8 @@ public function testFailedCodeRequestRedirectWithFakedRedirectUri(): void
406431
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
407432
});
408433

434+
$this->loginUser();
435+
409436
$this->client->request(
410437
'GET',
411438
'/authorize',
@@ -430,6 +457,7 @@ public function testFailedCodeRequestRedirectWithFakedRedirectUri(): void
430457

431458
public function testFailedAuthorizeRequest(): void
432459
{
460+
$this->loginUser();
433461
$this->client->request(
434462
'GET',
435463
'/authorize'

tests/TestKernel.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
117117
'stateless' => true,
118118
'oauth2' => true,
119119
],
120+
'authorization' => [
121+
'provider' => 'in_memory',
122+
'pattern' => '^/authorize',
123+
'http_basic' => true,
124+
'stateless' => true,
125+
],
120126
],
121127
'providers' => [
122128
'in_memory' => [
@@ -138,6 +144,12 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
138144
],
139145
],
140146
],
147+
'access_control' => [
148+
[
149+
'path' => '^/authorize',
150+
'roles' => class_exists(Security::class) ? 'IS_AUTHENTICATED' : 'IS_AUTHENTICATED_REMEMBERED',
151+
],
152+
],
141153
];
142154

143155
if (!class_exists(Security::class)) {

0 commit comments

Comments
 (0)