Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 33af1e0

Browse files
committed
Comments addressed
1 parent f3f833c commit 33af1e0

File tree

7 files changed

+67
-153
lines changed

7 files changed

+67
-153
lines changed

src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_access_token.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@
6565

6666
// OAuth2 Introspection (RFC 7662)
6767
->set('security.access_token_handler.oauth2', Oauth2TokenHandler::class)
68-
->abstract()
69-
->args([
70-
abstract_arg('http client'),
71-
service('logger')->nullOnInvalid(),
72-
'sub',
73-
])
68+
->abstract()
69+
->args([
70+
abstract_arg('http client'),
71+
service('logger')->nullOnInvalid(),
72+
'sub',
73+
])
7474
;
7575
};

src/Symfony/Component/Security/Core/Tests/User/OAuth2UserTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class OAuth2UserTest extends TestCase
1919
public function testCannotCreateUserWithoutSubProperty()
2020
{
2121
$this->expectException(\InvalidArgumentException::class);
22-
$this->expectExceptionMessage('The "sub" and "username" claims cannot be empty.');
22+
$this->expectExceptionMessage('The "sub" or "username" claims must be provided.');
2323

2424
new OAuth2User();
2525
}

src/Symfony/Component/Security/Core/User/OAuth2User.php

Lines changed: 14 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,22 @@
1818
*/
1919
class OAuth2User implements UserInterface
2020
{
21-
private array $additionalClaims = [];
21+
public readonly array $additionalClaims;
2222

2323
public function __construct(
2424
private array $roles = ['ROLE_USER'],
2525
// Standard Claims (https://datatracker.ietf.org/doc/html/rfc7662#section-2.2)
26-
private ?string $scope = null,
27-
private ?string $clientId = null,
28-
private ?string $username = null,
29-
private ?string $tokenType = null,
30-
private ?int $exp = null,
31-
private ?int $iat = null,
32-
private ?int $nbf = null,
33-
private ?string $sub = null,
34-
private ?string $aud = null,
35-
private ?string $iss = null,
36-
private ?string $jti = null,
26+
public readonly ?string $scope = null,
27+
public readonly ?string $clientId = null,
28+
public readonly ?string $username = null,
29+
public readonly ?string $tokenType = null,
30+
public readonly ?int $exp = null,
31+
public readonly ?int $iat = null,
32+
public readonly ?int $nbf = null,
33+
public readonly ?string $sub = null,
34+
public readonly ?string $aud = null,
35+
public readonly ?string $iss = null,
36+
public readonly ?string $jti = null,
3737

3838
// Additional Claims ("
3939
// Specific implementations MAY extend this structure with
@@ -43,7 +43,7 @@ public function __construct(
4343
...$additionalClaims
4444
) {
4545
if ((null === $sub || '' === $sub) && (null === $username || '' === $username)) {
46-
throw new \InvalidArgumentException('The "sub" and "username" claims cannot be empty.');
46+
throw new \InvalidArgumentException('The "sub" or "username" claims must be provided.');
4747
}
4848

4949
$this->additionalClaims = $additionalClaims['additionalClaims'] ?? $additionalClaims;
@@ -63,70 +63,10 @@ public function getRoles(): array
6363

6464
public function getUserIdentifier(): string
6565
{
66-
return (string) ($this->getSub() ?? $this->getUsername());
66+
return (string) ($this->sub ?? $this->username);
6767
}
6868

6969
public function eraseCredentials(): void
7070
{
7171
}
72-
73-
public function getScope(): ?string
74-
{
75-
return $this->scope;
76-
}
77-
78-
public function getClientId(): ?string
79-
{
80-
return $this->clientId;
81-
}
82-
83-
public function getUsername(): ?string
84-
{
85-
return $this->username;
86-
}
87-
88-
public function getTokenType(): ?string
89-
{
90-
return $this->tokenType;
91-
}
92-
93-
public function getExp(): ?int
94-
{
95-
return $this->exp;
96-
}
97-
98-
public function getIat(): ?int
99-
{
100-
return $this->iat;
101-
}
102-
103-
public function getNbf(): ?int
104-
{
105-
return $this->nbf;
106-
}
107-
108-
public function getSub(): ?string
109-
{
110-
return $this->sub;
111-
}
112-
113-
public function getAud(): ?string
114-
{
115-
return $this->aud;
116-
}
117-
118-
public function getIss(): ?string
119-
{
120-
return $this->iss;
121-
}
122-
123-
public function getJti(): ?string
124-
{
125-
return $this->jti;
126-
}
127-
128-
public function getAdditionalClaims(): array
129-
{
130-
return $this->additionalClaims;
131-
}
13272
}

src/Symfony/Component/Security/Http/AccessToken/OAuth2/OAuth2Trait.php

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

src/Symfony/Component/Security/Http/AccessToken/OAuth2/Oauth2TokenHandler.php

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,29 @@
1313

1414
use Psr\Log\LoggerInterface;
1515
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
16+
use Symfony\Component\Security\Core\User\OAuth2User;
1617
use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface;
1718
use Symfony\Component\Security\Http\AccessToken\OAuth2\Exception\InactiveAccessTokenException;
1819
use Symfony\Component\Security\Http\AccessToken\OAuth2\Exception\MissingClaimException;
1920
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
2021
use Symfony\Contracts\HttpClient\HttpClientInterface;
22+
use function Symfony\Component\String\u;
2123

2224
/**
2325
* The token handler validates the token on the authorization server.
26+
*
2427
* It uses the Introspection Endpoint as per the RFC7662
2528
*
2629
* @see https://tools.ietf.org/html/rfc7662
2730
*
28-
* @experimental
31+
* @internal
2932
*/
3033
final class Oauth2TokenHandler implements AccessTokenHandlerInterface
3134
{
32-
use OAuth2Trait;
33-
3435
public function __construct(
35-
private HttpClientInterface $client,
36-
private ?LoggerInterface $logger = null,
37-
private string $claim = 'sub'
36+
private readonly HttpClientInterface $client,
37+
private readonly ?LoggerInterface $logger = null,
38+
private readonly string $claim = 'sub'
3839
) {
3940
}
4041

@@ -43,7 +44,7 @@ public function getUserBadgeFrom(string $accessToken): UserBadge
4344
try {
4445
// Call the Introspection Endpoint to retrieve the user info
4546
// If the token is invalid or expired, the Introspection Endpoint will return 'active' => false
46-
$claims = $this->client->request('POST', '',[
47+
$claims = $this->client->request('POST', '', [
4748
'headers' => [
4849
'Content-Type' => 'application/x-www-form-urlencoded',
4950
],
@@ -53,13 +54,10 @@ public function getUserBadgeFrom(string $accessToken): UserBadge
5354
],
5455
])->toArray();
5556

56-
if (empty($claims['active'])) {
57-
throw new MissingClaimException(sprintf('"%s" claim not found on the authorization server response.', 'active'));
57+
if (!($claims['active'] ?? false)) {
58+
throw new InactiveAccessTokenException('The "active" claim was not found on the authorization server response or is set to false.');
5859
}
59-
if ($claims['active'] !== true) {
60-
throw new InactiveAccessTokenException('The access token is not active.');
61-
}
62-
if (empty($claims[$this->claim])) {
60+
if (!($claims[$this->claim] ?? false)) {
6361
throw new MissingClaimException(sprintf('"%s" claim not found on the authorization server response.', 'active'));
6462
}
6563

@@ -73,4 +71,33 @@ public function getUserBadgeFrom(string $accessToken): UserBadge
7371
throw new BadCredentialsException('Invalid credentials.', $e->getCode(), $e);
7472
}
7573
}
74+
75+
private function createUser(array $claims): OAuth2User
76+
{
77+
if (!\function_exists(\Symfony\Component\String\u::class)) {
78+
throw new \LogicException('You cannot use the "OAuth2TokenHandler" since the String component is not installed. Try running "composer require symfony/string".');
79+
}
80+
81+
foreach ($claims as $claim => $value) {
82+
unset($claims[$claim]);
83+
if ('' === $value || null === $value) {
84+
continue;
85+
}
86+
$claims[u($claim)->camel()->toString()] = $value;
87+
}
88+
89+
if ('' !== ($claims['updatedAt'] ?? '')) {
90+
$claims['updatedAt'] = (new \DateTimeImmutable())->setTimestamp($claims['updatedAt']);
91+
}
92+
93+
if ('' !== ($claims['emailVerified'] ?? '')) {
94+
$claims['emailVerified'] = (bool) $claims['emailVerified'];
95+
}
96+
97+
if ('' !== ($claims['phoneNumberVerified'] ?? '')) {
98+
$claims['phoneNumberVerified'] = (bool) $claims['phoneNumberVerified'];
99+
}
100+
101+
return new OAuth2User(...$claims);
102+
}
76103
}

src/Symfony/Component/Security/Http/AccessToken/Oidc/OidcTrait.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ private function createUser(array $claims): OidcUser
3636
$claims[u($claim)->camel()->toString()] = $value;
3737
}
3838

39-
if (isset($claims['updatedAt']) && '' !== $claims['updatedAt']) {
39+
if ('' !== ($claims['updatedAt'] ?? '')) {
4040
$claims['updatedAt'] = (new \DateTimeImmutable())->setTimestamp($claims['updatedAt']);
4141
}
4242

43-
if (\array_key_exists('emailVerified', $claims) && null !== $claims['emailVerified'] && '' !== $claims['emailVerified']) {
43+
if ('' !== ($claims['emailVerified'] ?? '')) {
4444
$claims['emailVerified'] = (bool) $claims['emailVerified'];
4545
}
4646

47-
if (\array_key_exists('phoneNumberVerified', $claims) && null !== $claims['phoneNumberVerified'] && '' !== $claims['phoneNumberVerified']) {
47+
if ('' !== ($claims['phoneNumberVerified'] ?? '')) {
4848
$claims['phoneNumberVerified'] = (bool) $claims['phoneNumberVerified'];
4949
}
5050

src/Symfony/Component/Security/Http/Tests/AccessToken/OAuth2/OAuth2TokenHandlerTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ public function testGetsUserIdentifierFromOAuth2ServerResponse(string $expected)
6363

6464
$this->assertEquals(new UserBadge($expected, fn () => $expectedUser, $claims), $userBadge);
6565
$this->assertInstanceOf(OAuth2User::class, $actualUser);
66-
$this->assertEquals($claims, $userBadge->getAttributes());
67-
$this->assertEquals($claims['sub'], $actualUser->getUserIdentifier());
66+
$this->assertSame($claims, $userBadge->getAttributes());
67+
$this->assertSame($claims['sub'], $actualUser->getUserIdentifier());
6868
}
6969

70-
public function getClaims(): iterable
70+
public static function getClaims(): iterable
7171
{
7272
yield ['Z5O3upPC88QrAjx00dis'];
7373
}

0 commit comments

Comments
 (0)