feature #40567 [Security] Move the badges resolution check to AuthenticatorManager (chalasr)

This PR was merged into the 5.3-dev branch.

Discussion
----------

[Security] Move the badges resolution check to `AuthenticatorManager`

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no (BC breaks on experimental code)
| Tickets       | Fixes #40491
| License       | MIT
| Doc PR        | -

Commits
-------

532f4aaa8e [Security] Move the badges resolution check to `AuthenticatorManager`
This commit is contained in:
Robin Chalas 2021-03-24 15:58:59 +01:00
commit 2dcf313a87
5 changed files with 18 additions and 16 deletions

View File

@ -91,6 +91,8 @@ Routing
Security
--------
* [BC BREAK] Remove method `checkIfCompletelyResolved()` from `PassportInterface`, checking that passport badges are
resolved is up to `AuthenticatorManager`
* Deprecate class `User`, use `InMemoryUser` or your own implementation instead.
If you are using the `isAccountNonLocked()`, `isAccountNonExpired()` or `isCredentialsNonExpired()` method, consider re-implementing
them in your own user class, as they are not part of the `InMemoryUser` API

View File

@ -4,6 +4,9 @@ CHANGELOG
5.3
---
* Add `PassportInterface:getBadges()`, implemented by `PassportTrait`
* [BC BREAK] Remove method `checkIfCompletelyResolved()` from `PassportInterface`, checking that passport badges are
resolved is up to `AuthenticatorManager`
* Deprecate class `User`, use `InMemoryUser` instead
* Deprecate class `UserChecker`, use `InMemoryUserChecker` or your own implementation instead
* [BC break] Remove support for passing a `UserInterface` implementation to `Passport`, use the `UserBadge` instead.

View File

@ -19,6 +19,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface;
@ -168,7 +169,11 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
$this->eventDispatcher->dispatch($event);
// check if all badges are resolved
$passport->checkIfCompletelyResolved();
foreach ($passport->getBadges() as $badge) {
if (!$badge->isResolved()) {
throw new BadCredentialsException(sprintf('Authentication failed: Security badge "%s" is not resolved, did you forget to register the correct listeners?', get_debug_type($badge)));
}
}
// create the authenticated token
$authenticatedToken = $authenticator->createAuthenticatedToken($passport, $this->firewallName);

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Http\Authenticator\Passport;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface;
/**
@ -43,9 +42,7 @@ interface PassportInterface
public function getBadge(string $badgeFqcn): ?BadgeInterface;
/**
* Checks if all badges are marked as resolved.
*
* @throws BadCredentialsException when a badge is not marked as resolved
* @return array<class-string<BadgeInterface>, BadgeInterface> An array of badge instances indexed by class name
*/
public function checkIfCompletelyResolved(): void;
public function getBadges(): array;
}

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Http\Authenticator\Passport;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface;
/**
@ -21,9 +20,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface;
*/
trait PassportTrait
{
/**
* @var BadgeInterface[]
*/
private $badges = [];
public function addBadge(BadgeInterface $badge): PassportInterface
@ -43,12 +39,11 @@ trait PassportTrait
return $this->badges[$badgeFqcn] ?? null;
}
public function checkIfCompletelyResolved(): void
/**
* @return array<class-string<BadgeInterface>, BadgeInterface>
*/
public function getBadges(): array
{
foreach ($this->badges as $badge) {
if (!$badge->isResolved()) {
throw new BadCredentialsException(sprintf('Authentication failed security badge "%s" is not resolved, did you forget to register the correct listeners?', \get_class($badge)));
}
}
return $this->badges;
}
}