Skip to content

Commit f58f59f

Browse files
vincentchalamonfabpot
authored andcommitted
[Security] Add OidcUserInfoTokenHandler and OidcUser
1 parent 7b10f10 commit f58f59f

File tree

5 files changed

+399
-0
lines changed

5 files changed

+399
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Add `AttributesBasedUserProviderInterface` to allow `$attributes` optional argument on `loadUserByIdentifier`
8+
* Add `OidcUser` with OIDC support for `OidcUserInfoTokenHandler`
9+
410
6.2
511
---
612

Tests/User/OidcUserTest.php

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Tests\User;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Security\Core\User\OidcUser;
16+
17+
class OidcUserTest extends TestCase
18+
{
19+
public function testCannotCreateUserWithoutSubProperty()
20+
{
21+
$this->expectException(\InvalidArgumentException::class);
22+
$this->expectExceptionMessage('The "sub" claim cannot be empty.');
23+
24+
new OidcUser();
25+
}
26+
27+
public function testCreateFullUserWithAdditionalClaimsUsingPositionalParameters()
28+
{
29+
$this->assertEquals(new OidcUser(
30+
userIdentifier: 'john.doe',
31+
roles: ['ROLE_USER', 'ROLE_ADMIN'],
32+
sub: 'e21bf182-1538-406e-8ccb-e25a17aba39f',
33+
name: 'John DOE',
34+
givenName: 'John',
35+
familyName: 'DOE',
36+
middleName: 'Fitzgerald',
37+
nickname: 'Johnny',
38+
preferredUsername: 'john.doe',
39+
profile: 'https://www.example.com/john-doe',
40+
picture: 'https://www.example.com/pics/john-doe.jpg',
41+
website: 'https://www.example.com',
42+
43+
emailVerified: true,
44+
gender: 'male',
45+
birthdate: '1980-05-15',
46+
zoneinfo: 'Europe/Paris',
47+
locale: 'fr-FR',
48+
phoneNumber: '+33 (0) 6 12 34 56 78',
49+
phoneNumberVerified: false,
50+
address: [
51+
'formatted' => '1 Rue des Moulins 75000 Paris - France',
52+
'street_address' => '1 Rue des Moulins',
53+
'locality' => 'Paris',
54+
'region' => 'Île-de-France',
55+
'postal_code' => '75000',
56+
'country' => 'France',
57+
],
58+
updatedAt: (new \DateTimeImmutable())->setTimestamp(1669628917),
59+
additionalClaims: [
60+
'impersonator' => [
61+
'username' => '[email protected]',
62+
],
63+
'customId' => 12345,
64+
],
65+
), new OidcUser(...[
66+
'userIdentifier' => 'john.doe',
67+
'roles' => ['ROLE_USER', 'ROLE_ADMIN'],
68+
'sub' => 'e21bf182-1538-406e-8ccb-e25a17aba39f',
69+
'name' => 'John DOE',
70+
'givenName' => 'John',
71+
'familyName' => 'DOE',
72+
'middleName' => 'Fitzgerald',
73+
'nickname' => 'Johnny',
74+
'preferredUsername' => 'john.doe',
75+
'profile' => 'https://www.example.com/john-doe',
76+
'picture' => 'https://www.example.com/pics/john-doe.jpg',
77+
'website' => 'https://www.example.com',
78+
'email' => '[email protected]',
79+
'emailVerified' => true,
80+
'gender' => 'male',
81+
'birthdate' => '1980-05-15',
82+
'zoneinfo' => 'Europe/Paris',
83+
'locale' => 'fr-FR',
84+
'phoneNumber' => '+33 (0) 6 12 34 56 78',
85+
'phoneNumberVerified' => false,
86+
'address' => [
87+
'formatted' => '1 Rue des Moulins 75000 Paris - France',
88+
'street_address' => '1 Rue des Moulins',
89+
'locality' => 'Paris',
90+
'region' => 'Île-de-France',
91+
'postal_code' => '75000',
92+
'country' => 'France',
93+
],
94+
'updatedAt' => (new \DateTimeImmutable())->setTimestamp(1669628917),
95+
'impersonator' => [
96+
'username' => '[email protected]',
97+
],
98+
'customId' => 12345,
99+
]));
100+
}
101+
102+
public function testCreateFullUserWithAdditionalClaims()
103+
{
104+
$this->assertEquals(new OidcUser(
105+
userIdentifier: 'john.doe',
106+
roles: ['ROLE_USER', 'ROLE_ADMIN'],
107+
sub: 'e21bf182-1538-406e-8ccb-e25a17aba39f',
108+
name: 'John DOE',
109+
givenName: 'John',
110+
familyName: 'DOE',
111+
middleName: 'Fitzgerald',
112+
nickname: 'Johnny',
113+
preferredUsername: 'john.doe',
114+
profile: 'https://www.example.com/john-doe',
115+
picture: 'https://www.example.com/pics/john-doe.jpg',
116+
website: 'https://www.example.com',
117+
118+
emailVerified: true,
119+
gender: 'male',
120+
birthdate: '1980-05-15',
121+
zoneinfo: 'Europe/Paris',
122+
locale: 'fr-FR',
123+
phoneNumber: '+33 (0) 6 12 34 56 78',
124+
phoneNumberVerified: false,
125+
address: [
126+
'formatted' => '1 Rue des Moulins 75000 Paris - France',
127+
'street_address' => '1 Rue des Moulins',
128+
'locality' => 'Paris',
129+
'region' => 'Île-de-France',
130+
'postal_code' => '75000',
131+
'country' => 'France',
132+
],
133+
updatedAt: (new \DateTimeImmutable())->setTimestamp(1669628917),
134+
additionalClaims: [
135+
[
136+
'username' => '[email protected]',
137+
],
138+
12345,
139+
],
140+
), new OidcUser(
141+
'john.doe',
142+
['ROLE_USER', 'ROLE_ADMIN'],
143+
'e21bf182-1538-406e-8ccb-e25a17aba39f',
144+
'John DOE',
145+
'John',
146+
'DOE',
147+
'Fitzgerald',
148+
'Johnny',
149+
'john.doe',
150+
'https://www.example.com/john-doe',
151+
'https://www.example.com/pics/john-doe.jpg',
152+
'https://www.example.com',
153+
154+
true,
155+
'male',
156+
'1980-05-15',
157+
'Europe/Paris',
158+
'fr-FR',
159+
'+33 (0) 6 12 34 56 78',
160+
false,
161+
[
162+
'formatted' => '1 Rue des Moulins 75000 Paris - France',
163+
'street_address' => '1 Rue des Moulins',
164+
'locality' => 'Paris',
165+
'region' => 'Île-de-France',
166+
'postal_code' => '75000',
167+
'country' => 'France',
168+
],
169+
(new \DateTimeImmutable())->setTimestamp(1669628917),
170+
[
171+
'username' => '[email protected]',
172+
],
173+
12345
174+
));
175+
}
176+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\User;
13+
14+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
15+
16+
/**
17+
* Overrides UserProviderInterface to add an "attributes" argument on loadUserByIdentifier.
18+
* This is particularly useful with self-contained access tokens.
19+
*
20+
* @experimental
21+
*/
22+
interface AttributesBasedUserProviderInterface extends UserProviderInterface
23+
{
24+
/**
25+
* Loads the user for the given user identifier (e.g. username or email) and attributes.
26+
*
27+
* This method must throw UserNotFoundException if the user is not found.
28+
*
29+
* @throws UserNotFoundException
30+
*/
31+
public function loadUserByIdentifier(string $identifier, array $attributes = []): UserInterface;
32+
}

0 commit comments

Comments
 (0)