Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork5.2k
[Security] Update custom authenticator docs to include identifier normalization#20636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Uh oh!
There was an error while loading.Please reload this page.
b58b83b
toa7df8a2
CompareUh oh!
There was an error while loading.Please reload this page.
security/custom_authenticator.rst Outdated
.. note:: | ||
Similarly, Google normalizes email addresses so that "john.doe", "j.hon.d.oe", | ||
and "johndoe" all correspond to the same account. | ||
This involves removing dots and converting the email address to lowercase | ||
(though normalization specifics depend on your use case). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
With the other note below, I'm not sure this one is needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I believe both notes provide valuable context and would prefer to keep tthem:
- The first shows a well-known real-world example (Google).
- The second one highlights enterprise-specific formats where normalization is important.
a7df8a2
tobf84645
CompareAdded support for normalizing user identifiers in Symfony 7.3 to ensure consistent comparison and storage. Updated documentation with implementation examples, highlighting best practices like converting identifiers to lowercase and handling various formats. This improvement reduces the risk of duplicates and improves reliability in user authentication.
bf84645
toac6a258
CompareFor instance, the example below uses a normalizer that converts usernames to a normalized, ASCII-only, lowercase format, | ||
suitable for consistent comparison and storage. | ||
// src/Security/NormalizedUserBadge.php | ||
namespace App\Security; | ||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; | ||
use Symfony\Component\String\UnicodeString; | ||
use function Symfony\Component\String\u; | ||
final class NormalizedUserBadge extends UserBadge | ||
{ | ||
public function __construct(string $identifier) | ||
{ | ||
$callback = static fn (string $identifier) => u($identifier)->normalize(UnicodeString::NFKC)->ascii()->lower()->toString(); | ||
parent::__construct($identifier, null, $callback); | ||
} | ||
} | ||
// src/Security/PasswordAuthenticator.php | ||
namespace App\Security; | ||
final class PasswordAuthenticator extends AbstractLoginFormAuthenticator | ||
{ | ||
// Simplified for brievety | ||
public function authenticate(Request $request): Passport | ||
{ | ||
$username = (string) $request->request->get('username', ''); | ||
$password = (string) $request->request->get('password', ''); | ||
$request->getSession() | ||
->set(SecurityRequestAttributes::LAST_USERNAME, $username); | ||
return new Passport( | ||
new NormalizedUserBadge($username), | ||
new PasswordCredentials($password), | ||
[ | ||
//All other useful badges | ||
] | ||
); | ||
} | ||
} | ||
.. note:: |
alamiraultMay 9, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
- Php code was not rendered. I added
::
and.. code-block:: php
(Not 100% sure it's the best way) - I replace
(string) $request->request->get()
by$request->request->getString
For instance, the example below uses a normalizer that converts usernames to a normalized, ASCII-only, lowercase format, | |
suitable for consistent comparison and storage. | |
// src/Security/NormalizedUserBadge.php | |
namespace App\Security; | |
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; | |
use Symfony\Component\String\UnicodeString; | |
use function Symfony\Component\String\u; | |
final class NormalizedUserBadge extends UserBadge | |
{ | |
public function __construct(string $identifier) | |
{ | |
$callback = static fn (string $identifier) => u($identifier)->normalize(UnicodeString::NFKC)->ascii()->lower()->toString(); | |
parent::__construct($identifier, null, $callback); | |
} | |
} | |
// src/Security/PasswordAuthenticator.php | |
namespace App\Security; | |
final class PasswordAuthenticator extends AbstractLoginFormAuthenticator | |
{ | |
// Simplified for brievety | |
public function authenticate(Request $request): Passport | |
{ | |
$username = (string) $request->request->get('username', ''); | |
$password = (string) $request->request->get('password', ''); | |
$request->getSession() | |
->set(SecurityRequestAttributes::LAST_USERNAME, $username); | |
return new Passport( | |
new NormalizedUserBadge($username), | |
new PasswordCredentials($password), | |
[ | |
//All other useful badges | |
] | |
); | |
} | |
} | |
..note:: | |
For instance, the example below uses a normalizer that converts usernames to a normalized, ASCII-only, lowercase format, | |
suitable for consistent comparison and storage:: | |
// src/Security/NormalizedUserBadge.php | |
namespace App\Security; | |
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; | |
use Symfony\Component\String\UnicodeString; | |
use function Symfony\Component\String\u; | |
final class NormalizedUserBadge extends UserBadge | |
{ | |
public function __construct(string $identifier) | |
{ | |
$callback = static fn (string $identifier) => u($identifier)->normalize(UnicodeString::NFKC)->ascii()->lower()->toString(); | |
parent::__construct($identifier, null, $callback); | |
} | |
} | |
..code-block::php | |
// src/Security/PasswordAuthenticator.php | |
namespace App\Security; | |
final class PasswordAuthenticator extends AbstractLoginFormAuthenticator | |
{ | |
// Simplified for brievety | |
public function authenticate(Request $request): Passport | |
{ | |
$username = $request->request->getString('username'); | |
$password = $request->request->getString('password'); | |
$request->getSession() | |
->set(SecurityRequestAttributes::LAST_USERNAME, $username); | |
return new Passport( | |
new NormalizedUserBadge($username), | |
new PasswordCredentials($password), | |
[ | |
//All other useful badges | |
] | |
); | |
} | |
} | |
..note:: |
9d65b3d
intosymfony:7.3Uh oh!
There was an error while loading.Please reload this page.
Thanks Florent for this contribution ... and thanks reviewers for your nice review! |
Fixes#20632
Improve the documentation for custom authenticators by detailing the concept of user identifier normalization. Introduced the
NormalizedUserBadge
example to demonstrate how to simplify and standardize identifiers.