-
-
Notifications
You must be signed in to change notification settings - Fork 5.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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 7.3
Are you sure you want to change the base?
Conversation
b58b83b
to
a7df8a2
Compare
You can optionally pass a user identifier normalizer as third argument to the | ||
``UserBadge``. This callable receives the ``$userIdentifier`` | ||
and must return a normalized user identifier as a string. | ||
|
||
.. versionadded:: 7.3 |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
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.
Many thanks.
I will take time to update this section.
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.
It should be fixed with the last commit
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
to
bf84645
Compare
Added 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
to
ac6a258
Compare
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:: |
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:: |
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.