├── .gitignore ├── Core ├── Event │ ├── AuthenticationSuccessEvent.php │ ├── AuthenticationEvent.php │ ├── AuthenticationFailureEvent.php │ └── VoteEvent.php ├── Exception │ ├── ExceptionInterface.php │ ├── LogicException.php │ ├── RuntimeException.php │ ├── InvalidArgumentException.php │ ├── UnsupportedUserException.php │ ├── LogoutException.php │ ├── LockedException.php │ ├── DisabledException.php │ ├── InvalidCsrfTokenException.php │ ├── AccountExpiredException.php │ ├── TokenNotFoundException.php │ ├── BadCredentialsException.php │ ├── CredentialsExpiredException.php │ ├── CookieTheftException.php │ ├── ProviderNotFoundException.php │ ├── AuthenticationServiceException.php │ ├── LazyResponseException.php │ ├── AuthenticationCredentialsNotFoundException.php │ ├── InsufficientAuthenticationException.php │ ├── AuthenticationExpiredException.php │ ├── SessionUnavailableException.php │ ├── AccessDeniedException.php │ ├── AccountStatusException.php │ ├── UsernameNotFoundException.php │ └── CustomUserMessageAuthenticationException.php ├── Encoder │ ├── SelfSaltingEncoderInterface.php │ ├── EncoderAwareInterface.php │ ├── EncoderFactoryInterface.php │ ├── UserPasswordEncoderInterface.php │ ├── PasswordEncoderInterface.php │ ├── UserPasswordEncoder.php │ ├── PlaintextPasswordEncoder.php │ ├── MigratingPasswordEncoder.php │ └── MessageDigestPasswordEncoder.php ├── README.md ├── Role │ ├── RoleHierarchyInterface.php │ ├── Role.php │ └── SwitchUserRole.php ├── Validator │ └── Constraints │ │ ├── UserPassword.php │ │ └── UserPasswordValidator.php ├── Authorization │ ├── AuthorizationCheckerInterface.php │ ├── AccessDecisionManagerInterface.php │ ├── Voter │ │ ├── VoterInterface.php │ │ ├── TraceableVoter.php │ │ ├── RoleVoter.php │ │ ├── RoleHierarchyVoter.php │ │ └── Voter.php │ ├── ExpressionLanguage.php │ └── AuthorizationChecker.php ├── Authentication │ ├── SimpleAuthenticatorInterface.php │ ├── AuthenticationManagerInterface.php │ ├── Token │ │ ├── Storage │ │ │ ├── TokenStorageInterface.php │ │ │ ├── TokenStorage.php │ │ │ └── UsageTrackingTokenStorage.php │ │ ├── SwitchUserToken.php │ │ ├── AnonymousToken.php │ │ └── PreAuthenticatedToken.php │ ├── Provider │ │ ├── AuthenticationProviderInterface.php │ │ ├── AnonymousAuthenticationProvider.php │ │ ├── SimpleAuthenticationProvider.php │ │ ├── PreAuthenticatedAuthenticationProvider.php │ │ └── RememberMeAuthenticationProvider.php │ ├── RememberMe │ │ ├── PersistentTokenInterface.php │ │ ├── TokenProviderInterface.php │ │ ├── InMemoryTokenProvider.php │ │ └── PersistentToken.php │ └── AuthenticationTrustResolverInterface.php ├── User │ ├── PasswordUpgraderInterface.php │ ├── EquatableInterface.php │ ├── UserCheckerInterface.php │ ├── MissingUserProvider.php │ ├── LdapUserProvider.php │ ├── UserProviderInterface.php │ ├── UserInterface.php │ └── UserChecker.php ├── AuthenticationEvents.php ├── LICENSE ├── composer.json └── Security.php ├── Csrf ├── Exception │ └── TokenNotFoundException.php ├── README.md ├── TokenStorage │ ├── ClearableTokenStorageInterface.php │ └── TokenStorageInterface.php ├── TokenGenerator │ ├── TokenGeneratorInterface.php │ └── UriSafeTokenGenerator.php ├── LICENSE ├── composer.json ├── CsrfToken.php └── CsrfTokenManagerInterface.php ├── Guard ├── README.md ├── PasswordAuthenticatedInterface.php ├── Token │ ├── GuardTokenInterface.php │ ├── PreAuthenticationGuardToken.php │ └── PostAuthenticationGuardToken.php ├── composer.json ├── LICENSE ├── AbstractGuardAuthenticator.php └── Authenticator │ └── AbstractFormLoginAuthenticator.php ├── Http ├── Firewall │ ├── ListenerInterface.php │ ├── AbstractListener.php │ ├── RemoteUserAuthenticationListener.php │ ├── LegacyListenerTrait.php │ └── X509AuthenticationListener.php ├── README.md ├── Authentication │ ├── SimplePreAuthenticatorInterface.php │ ├── SimpleFormAuthenticatorInterface.php │ ├── AuthenticationSuccessHandlerInterface.php │ ├── AuthenticationFailureHandlerInterface.php │ ├── CustomAuthenticationFailureHandler.php │ ├── CustomAuthenticationSuccessHandler.php │ └── AuthenticationUtils.php ├── AccessMapInterface.php ├── Logout │ ├── SessionLogoutHandler.php │ ├── LogoutHandlerInterface.php │ ├── LogoutSuccessHandlerInterface.php │ ├── CsrfTokenClearingLogoutHandler.php │ ├── DefaultLogoutSuccessHandler.php │ └── CookieClearingLogoutHandler.php ├── Authorization │ └── AccessDeniedHandlerInterface.php ├── LICENSE ├── Session │ ├── SessionAuthenticationStrategyInterface.php │ └── SessionAuthenticationStrategy.php ├── SecurityEvents.php ├── FirewallMapInterface.php ├── Event │ ├── DeauthenticatedEvent.php │ ├── InteractiveLoginEvent.php │ ├── SwitchUserEvent.php │ └── LazyResponseEvent.php ├── EntryPoint │ ├── BasicAuthenticationEntryPoint.php │ ├── AuthenticationEntryPointInterface.php │ ├── RetryAuthenticationEntryPoint.php │ └── FormAuthenticationEntryPoint.php ├── RememberMe │ └── ResponseListener.php ├── Util │ └── TargetPathTrait.php ├── AccessMap.php ├── FirewallMap.php ├── composer.json └── Controller │ └── UserValueResolver.php ├── README.md ├── phpunit.xml.dist ├── LICENSE └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | phpunit.xml 4 | -------------------------------------------------------------------------------- /Core/Event/AuthenticationSuccessEvent.php: -------------------------------------------------------------------------------- 1 | 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\Event; 13 | 14 | /** 15 | * @final since Symfony 4.4 16 | */ 17 | class AuthenticationSuccessEvent extends AuthenticationEvent 18 | { 19 | } 20 | -------------------------------------------------------------------------------- /Core/Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * Base ExceptionInterface for the Security component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | interface ExceptionInterface extends \Throwable 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /Core/Exception/LogicException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * Base LogicException for the Security component. 16 | * 17 | * @author Iltar van der Berg 18 | */ 19 | class LogicException extends \LogicException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /Csrf/Exception/TokenNotFoundException.php: -------------------------------------------------------------------------------- 1 | 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\Csrf\Exception; 13 | 14 | use Symfony\Component\Security\Core\Exception\RuntimeException; 15 | 16 | /** 17 | * @author Bernhard Schussek 18 | */ 19 | class TokenNotFoundException extends RuntimeException 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /Core/Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * Base RuntimeException for the Security component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class RuntimeException extends \RuntimeException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /Csrf/README.md: -------------------------------------------------------------------------------- 1 | Security Component - CSRF 2 | ========================= 3 | 4 | The Security CSRF (cross-site request forgery) component provides a class 5 | `CsrfTokenManager` for generating and validating CSRF tokens. 6 | 7 | Resources 8 | --------- 9 | 10 | * [Documentation](https://symfony.com/doc/current/components/security.html) 11 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) 12 | * [Report issues](https://github.com/symfony/symfony/issues) and 13 | [send Pull Requests](https://github.com/symfony/symfony/pulls) 14 | in the [main Symfony repository](https://github.com/symfony/symfony) 15 | -------------------------------------------------------------------------------- /Core/Encoder/SelfSaltingEncoderInterface.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | /** 15 | * SelfSaltingEncoderInterface is a marker interface for encoders that do not 16 | * require a user-generated salt. 17 | * 18 | * @author Zan Baldwin 19 | */ 20 | interface SelfSaltingEncoderInterface 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Core/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * Base InvalidArgumentException for the Security component. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /Guard/README.md: -------------------------------------------------------------------------------- 1 | Security Component - Guard 2 | ========================== 3 | 4 | The Guard component brings many layers of authentication together, making 5 | it much easier to create complex authentication systems where you have 6 | total control. 7 | 8 | Resources 9 | --------- 10 | 11 | * [Documentation](https://symfony.com/doc/current/components/security.html) 12 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) 13 | * [Report issues](https://github.com/symfony/symfony/issues) and 14 | [send Pull Requests](https://github.com/symfony/symfony/pulls) 15 | in the [main Symfony repository](https://github.com/symfony/symfony) 16 | -------------------------------------------------------------------------------- /Csrf/TokenStorage/ClearableTokenStorageInterface.php: -------------------------------------------------------------------------------- 1 | 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\Csrf\TokenStorage; 13 | 14 | /** 15 | * @author Christian Flothmann 16 | */ 17 | interface ClearableTokenStorageInterface extends TokenStorageInterface 18 | { 19 | /** 20 | * Removes all CSRF tokens. 21 | */ 22 | public function clear(); 23 | } 24 | -------------------------------------------------------------------------------- /Core/Exception/UnsupportedUserException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * This exception is thrown when an account is reloaded from a provider which 16 | * doesn't support the passed implementation of UserInterface. 17 | * 18 | * @author Johannes M. Schmitt 19 | */ 20 | class UnsupportedUserException extends AuthenticationServiceException 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /Csrf/TokenGenerator/TokenGeneratorInterface.php: -------------------------------------------------------------------------------- 1 | 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\Csrf\TokenGenerator; 13 | 14 | /** 15 | * Generates CSRF tokens. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | interface TokenGeneratorInterface 20 | { 21 | /** 22 | * Generates a CSRF token. 23 | * 24 | * @return string The generated CSRF token 25 | */ 26 | public function generateToken(); 27 | } 28 | -------------------------------------------------------------------------------- /Core/README.md: -------------------------------------------------------------------------------- 1 | Security Component - Core 2 | ========================= 3 | 4 | Security provides an infrastructure for sophisticated authorization systems, 5 | which makes it possible to easily separate the actual authorization logic from 6 | so called user providers that hold the users credentials. It is inspired by 7 | the Java Spring framework. 8 | 9 | Resources 10 | --------- 11 | 12 | * [Documentation](https://symfony.com/doc/current/components/security.html) 13 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) 14 | * [Report issues](https://github.com/symfony/symfony/issues) and 15 | [send Pull Requests](https://github.com/symfony/symfony/pulls) 16 | in the [main Symfony repository](https://github.com/symfony/symfony) 17 | -------------------------------------------------------------------------------- /Core/Exception/LogoutException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * LogoutException is thrown when the account cannot be logged out. 16 | * 17 | * @author Jeremy Mikola 18 | */ 19 | class LogoutException extends RuntimeException 20 | { 21 | public function __construct(string $message = 'Logout Exception', \Throwable $previous = null) 22 | { 23 | parent::__construct($message, 403, $previous); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Guard/PasswordAuthenticatedInterface.php: -------------------------------------------------------------------------------- 1 | 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\Guard; 13 | 14 | /** 15 | * An optional interface for "guard" authenticators that deal with user passwords. 16 | */ 17 | interface PasswordAuthenticatedInterface 18 | { 19 | /** 20 | * Returns the clear-text password contained in credentials if any. 21 | * 22 | * @param mixed $credentials The user credentials 23 | */ 24 | public function getPassword($credentials): ?string; 25 | } 26 | -------------------------------------------------------------------------------- /Http/Firewall/ListenerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Firewall; 13 | 14 | use Symfony\Component\HttpKernel\Event\GetResponseEvent; 15 | 16 | /** 17 | * Interface that must be implemented by firewall listeners. 18 | * 19 | * @author Johannes M. Schmitt 20 | * 21 | * @deprecated since Symfony 4.3, turn listeners into callables instead 22 | */ 23 | interface ListenerInterface 24 | { 25 | public function handle(GetResponseEvent $event); 26 | } 27 | -------------------------------------------------------------------------------- /Http/README.md: -------------------------------------------------------------------------------- 1 | Security Component - HTTP Integration 2 | ===================================== 3 | 4 | Security provides an infrastructure for sophisticated authorization systems, 5 | which makes it possible to easily separate the actual authorization logic from 6 | so called user providers that hold the users credentials. It is inspired by 7 | the Java Spring framework. 8 | 9 | Resources 10 | --------- 11 | 12 | * [Documentation](https://symfony.com/doc/current/components/security.html) 13 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) 14 | * [Report issues](https://github.com/symfony/symfony/issues) and 15 | [send Pull Requests](https://github.com/symfony/symfony/pulls) 16 | in the [main Symfony repository](https://github.com/symfony/symfony) 17 | -------------------------------------------------------------------------------- /Core/Exception/LockedException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * LockedException is thrown if the user account is locked. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class LockedException extends AccountStatusException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Account is locked.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Encoder/EncoderAwareInterface.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | /** 15 | * @author Christophe Coevoet 16 | */ 17 | interface EncoderAwareInterface 18 | { 19 | /** 20 | * Gets the name of the encoder used to encode the password. 21 | * 22 | * If the method returns null, the standard way to retrieve the encoder 23 | * will be used instead. 24 | * 25 | * @return string|null 26 | */ 27 | public function getEncoderName(); 28 | } 29 | -------------------------------------------------------------------------------- /Core/Exception/DisabledException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * DisabledException is thrown when the user account is disabled. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class DisabledException extends AccountStatusException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Account is disabled.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Exception/InvalidCsrfTokenException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * This exception is thrown when the csrf token is invalid. 16 | * 17 | * @author Johannes M. Schmitt 18 | * @author Alexander 19 | */ 20 | class InvalidCsrfTokenException extends AuthenticationException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Invalid CSRF token.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Exception/AccountExpiredException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * AccountExpiredException is thrown when the user account has expired. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class AccountExpiredException extends AccountStatusException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Account has expired.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Exception/TokenNotFoundException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * TokenNotFoundException is thrown if a Token cannot be found. 16 | * 17 | * @author Johannes M. Schmitt 18 | * @author Alexander 19 | */ 20 | class TokenNotFoundException extends AuthenticationException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'No token could be found.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Exception/BadCredentialsException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * BadCredentialsException is thrown when the user credentials are invalid. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class BadCredentialsException extends AuthenticationException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Invalid credentials.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Guard/Token/GuardTokenInterface.php: -------------------------------------------------------------------------------- 1 | 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\Guard\Token; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * A marker interface that both guard tokens implement. 18 | * 19 | * Any tokens passed to GuardAuthenticationProvider (i.e. any tokens that 20 | * are handled by the guard auth system) must implement this 21 | * interface. 22 | * 23 | * @author Ryan Weaver 24 | */ 25 | interface GuardTokenInterface extends TokenInterface 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /Http/Authentication/SimplePreAuthenticatorInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; 16 | 17 | /** 18 | * @author Jordi Boggiano 19 | * 20 | * @deprecated since Symfony 4.2, use Guard instead. 21 | */ 22 | interface SimplePreAuthenticatorInterface extends SimpleAuthenticatorInterface 23 | { 24 | public function createToken(Request $request, $providerKey); 25 | } 26 | -------------------------------------------------------------------------------- /Core/Exception/CredentialsExpiredException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * CredentialsExpiredException is thrown when the user account credentials have expired. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class CredentialsExpiredException extends AccountStatusException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Credentials have expired.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Security Component 2 | ================== 3 | 4 | The Security component provides a complete security system for your web 5 | application. It ships with facilities for authenticating using HTTP basic, 6 | interactive form login or X.509 certificate login, but 7 | also allows you to implement your own authentication strategies. Furthermore, 8 | the component provides ways to authorize authenticated users based on their 9 | roles. 10 | 11 | Resources 12 | --------- 13 | 14 | * [Documentation](https://symfony.com/doc/current/components/security.html) 15 | * [Contributing](https://symfony.com/doc/current/contributing/index.html) 16 | * [Report issues](https://github.com/symfony/symfony/issues) and 17 | [send Pull Requests](https://github.com/symfony/symfony/pulls) 18 | in the [main Symfony repository](https://github.com/symfony/symfony) 19 | -------------------------------------------------------------------------------- /Core/Role/RoleHierarchyInterface.php: -------------------------------------------------------------------------------- 1 | 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\Role; 13 | 14 | /** 15 | * RoleHierarchyInterface is the interface for a role hierarchy. 16 | * 17 | * The getReachableRoles(Role[] $roles) method that returns an array of all reachable Role objects is deprecated 18 | * since Symfony 4.3. 19 | * 20 | * @author Fabien Potencier 21 | * 22 | * @method string[] getReachableRoleNames(string[] $roles) The associated roles - not implementing it is deprecated since Symfony 4.3 23 | */ 24 | interface RoleHierarchyInterface 25 | { 26 | } 27 | -------------------------------------------------------------------------------- /Http/Authentication/SimpleFormAuthenticatorInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; 16 | 17 | /** 18 | * @author Jordi Boggiano 19 | * 20 | * @deprecated since Symfony 4.2, use Guard instead. 21 | */ 22 | interface SimpleFormAuthenticatorInterface extends SimpleAuthenticatorInterface 23 | { 24 | public function createToken(Request $request, $username, $password, $providerKey); 25 | } 26 | -------------------------------------------------------------------------------- /Core/Validator/Constraints/UserPassword.php: -------------------------------------------------------------------------------- 1 | 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\Validator\Constraints; 13 | 14 | use Symfony\Component\Validator\Constraint; 15 | 16 | /** 17 | * @Annotation 18 | * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) 19 | */ 20 | class UserPassword extends Constraint 21 | { 22 | public $message = 'This value should be the user\'s current password.'; 23 | public $service = 'security.validator.user_password'; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function validatedBy() 29 | { 30 | return $this->service; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Core/Authorization/AuthorizationCheckerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authorization; 13 | 14 | /** 15 | * The AuthorizationCheckerInterface. 16 | * 17 | * @author Johannes M. Schmitt 18 | */ 19 | interface AuthorizationCheckerInterface 20 | { 21 | /** 22 | * Checks if the attributes are granted against the current authentication token and optionally supplied subject. 23 | * 24 | * @param mixed $attributes 25 | * @param mixed $subject 26 | * 27 | * @return bool 28 | */ 29 | public function isGranted($attributes, $subject = null); 30 | } 31 | -------------------------------------------------------------------------------- /Core/Exception/CookieTheftException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * This exception is thrown when the RememberMeServices implementation 16 | * detects that a presented cookie has already been used by someone else. 17 | * 18 | * @author Johannes M. Schmitt 19 | * @author Alexander 20 | */ 21 | class CookieTheftException extends AuthenticationException 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function getMessageKey() 27 | { 28 | return 'Cookie has already been used by someone else.'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Core/Exception/ProviderNotFoundException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * ProviderNotFoundException is thrown when no AuthenticationProviderInterface instance 16 | * supports an authentication Token. 17 | * 18 | * @author Fabien Potencier 19 | * @author Alexander 20 | */ 21 | class ProviderNotFoundException extends AuthenticationException 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function getMessageKey() 27 | { 28 | return 'No authentication provider found to support the authentication token.'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Core/Authentication/SimpleAuthenticatorInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Component\Security\Core\User\UserProviderInterface; 16 | 17 | /** 18 | * @author Jordi Boggiano 19 | * 20 | * @deprecated since Symfony 4.2, use Guard instead. 21 | */ 22 | interface SimpleAuthenticatorInterface 23 | { 24 | public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey); 25 | 26 | public function supportsToken(TokenInterface $token, $providerKey); 27 | } 28 | -------------------------------------------------------------------------------- /Core/Exception/AuthenticationServiceException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * AuthenticationServiceException is thrown when an authentication request could not be processed due to a system problem. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class AuthenticationServiceException extends AuthenticationException 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getMessageKey() 26 | { 27 | return 'Authentication request could not be processed due to a system problem.'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Exception/LazyResponseException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | use Symfony\Component\HttpFoundation\Response; 15 | 16 | /** 17 | * A signaling exception that wraps a lazily computed response. 18 | * 19 | * @author Nicolas Grekas 20 | */ 21 | class LazyResponseException extends \Exception implements ExceptionInterface 22 | { 23 | private $response; 24 | 25 | public function __construct(Response $response) 26 | { 27 | $this->response = $response; 28 | } 29 | 30 | public function getResponse(): Response 31 | { 32 | return $this->response; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Core/Exception/AuthenticationCredentialsNotFoundException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * AuthenticationCredentialsNotFoundException is thrown when an authentication is rejected 16 | * because no Token is available. 17 | * 18 | * @author Fabien Potencier 19 | * @author Alexander 20 | */ 21 | class AuthenticationCredentialsNotFoundException extends AuthenticationException 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function getMessageKey() 27 | { 28 | return 'Authentication credentials could not be found.'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Http/AccessMapInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | 16 | /** 17 | * AccessMap allows configuration of different access control rules for 18 | * specific parts of the website. 19 | * 20 | * @author Fabien Potencier 21 | * @author Kris Wallsmith 22 | */ 23 | interface AccessMapInterface 24 | { 25 | /** 26 | * Returns security attributes and required channel for the supplied request. 27 | * 28 | * @return array A tuple of security attributes and the required channel 29 | */ 30 | public function getPatterns(Request $request); 31 | } 32 | -------------------------------------------------------------------------------- /Core/Event/AuthenticationEvent.php: -------------------------------------------------------------------------------- 1 | 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\Event; 13 | 14 | use Symfony\Component\EventDispatcher\Event; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | 17 | /** 18 | * This is a general purpose authentication event. 19 | * 20 | * @author Johannes M. Schmitt 21 | */ 22 | class AuthenticationEvent extends Event 23 | { 24 | private $authenticationToken; 25 | 26 | public function __construct(TokenInterface $token) 27 | { 28 | $this->authenticationToken = $token; 29 | } 30 | 31 | public function getAuthenticationToken() 32 | { 33 | return $this->authenticationToken; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Core/Exception/InsufficientAuthenticationException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * InsufficientAuthenticationException is thrown if the user credentials are not sufficiently trusted. 16 | * 17 | * This is the case when a user is anonymous and the resource to be displayed has an access role. 18 | * 19 | * @author Fabien Potencier 20 | * @author Alexander 21 | */ 22 | class InsufficientAuthenticationException extends AuthenticationException 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function getMessageKey() 28 | { 29 | return 'Not privileged to request the resource.'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Guard/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/security-guard", 3 | "type": "library", 4 | "description": "Symfony Security Component - Guard", 5 | "keywords": [], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1.3", 20 | "symfony/security-core": "^3.4.22|^4.2.3|^5.0", 21 | "symfony/security-http": "^4.4.1" 22 | }, 23 | "require-dev": { 24 | "psr/log": "^1|^2|^3" 25 | }, 26 | "autoload": { 27 | "psr-4": { "Symfony\\Component\\Security\\Guard\\": "" }, 28 | "exclude-from-classmap": [ 29 | "/Tests/" 30 | ] 31 | }, 32 | "minimum-stability": "dev" 33 | } 34 | -------------------------------------------------------------------------------- /Http/Logout/SessionLogoutHandler.php: -------------------------------------------------------------------------------- 1 | 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\Http\Logout; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | 18 | /** 19 | * Handler for clearing invalidating the current session. 20 | * 21 | * @author Johannes M. Schmitt 22 | */ 23 | class SessionLogoutHandler implements LogoutHandlerInterface 24 | { 25 | /** 26 | * Invalidate the current session. 27 | */ 28 | public function logout(Request $request, Response $response, TokenInterface $token) 29 | { 30 | $request->getSession()->invalidate(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Core/Exception/AuthenticationExpiredException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * AuthenticationExpiredException is thrown when an authenticated token becomes un-authenticated between requests. 16 | * 17 | * In practice, this is due to the User changing between requests (e.g. password changes), 18 | * causes the token to become un-authenticated. 19 | * 20 | * @author Ryan Weaver 21 | */ 22 | class AuthenticationExpiredException extends AccountStatusException 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function getMessageKey() 28 | { 29 | return 'Authentication expired because your account information has changed.'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Core/User/PasswordUpgraderInterface.php: -------------------------------------------------------------------------------- 1 | 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 | /** 15 | * @author Nicolas Grekas 16 | */ 17 | interface PasswordUpgraderInterface 18 | { 19 | /** 20 | * Upgrades the encoded password of a user, typically for using a better hash algorithm. 21 | * 22 | * This method should persist the new password in the user storage and update the $user object accordingly. 23 | * Because you don't want your users not being able to log in, this method should be opportunistic: 24 | * it's fine if it does nothing or if it fails without throwing any exception. 25 | */ 26 | public function upgradePassword(UserInterface $user, string $newEncodedPassword): void; 27 | } 28 | -------------------------------------------------------------------------------- /Http/Authorization/AccessDeniedHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authorization; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; 17 | 18 | /** 19 | * This is used by the ExceptionListener to translate an AccessDeniedException 20 | * to a Response object. 21 | * 22 | * @author Johannes M. Schmitt 23 | */ 24 | interface AccessDeniedHandlerInterface 25 | { 26 | /** 27 | * Handles an access denied failure. 28 | * 29 | * @return Response|null 30 | */ 31 | public function handle(Request $request, AccessDeniedException $accessDeniedException); 32 | } 33 | -------------------------------------------------------------------------------- /Core/User/EquatableInterface.php: -------------------------------------------------------------------------------- 1 | 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 | /** 15 | * EquatableInterface used to test if two objects are equal in security 16 | * and re-authentication context. 17 | * 18 | * @author Dariusz Górecki 19 | */ 20 | interface EquatableInterface 21 | { 22 | /** 23 | * The equality comparison should neither be done by referential equality 24 | * nor by comparing identities (i.e. getId() === getId()). 25 | * 26 | * However, you do not need to compare every attribute, but only those that 27 | * are relevant for assessing whether re-authentication is required. 28 | * 29 | * @return bool 30 | */ 31 | public function isEqualTo(UserInterface $user); 32 | } 33 | -------------------------------------------------------------------------------- /Core/AuthenticationEvents.php: -------------------------------------------------------------------------------- 1 | 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; 13 | 14 | final class AuthenticationEvents 15 | { 16 | /** 17 | * The AUTHENTICATION_SUCCESS event occurs after a user is authenticated 18 | * by one provider. 19 | * 20 | * @Event("Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent") 21 | */ 22 | public const AUTHENTICATION_SUCCESS = 'security.authentication.success'; 23 | 24 | /** 25 | * The AUTHENTICATION_FAILURE event occurs after a user cannot be 26 | * authenticated by any of the providers. 27 | * 28 | * @Event("Symfony\Component\Security\Core\Event\AuthenticationFailureEvent") 29 | */ 30 | public const AUTHENTICATION_FAILURE = 'security.authentication.failure'; 31 | } 32 | -------------------------------------------------------------------------------- /Core/Encoder/EncoderFactoryInterface.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | 16 | /** 17 | * EncoderFactoryInterface to support different encoders for different accounts. 18 | * 19 | * @author Johannes M. Schmitt 20 | */ 21 | interface EncoderFactoryInterface 22 | { 23 | /** 24 | * Returns the password encoder to use for the given account. 25 | * 26 | * @param UserInterface|string $user A UserInterface instance or a class name 27 | * 28 | * @return PasswordEncoderInterface 29 | * 30 | * @throws \RuntimeException when no password encoder could be found for the user 31 | */ 32 | public function getEncoder($user); 33 | } 34 | -------------------------------------------------------------------------------- /Http/Logout/LogoutHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Logout; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | 18 | /** 19 | * Interface that needs to be implemented by LogoutHandlers. 20 | * 21 | * @author Johannes M. Schmitt 22 | */ 23 | interface LogoutHandlerInterface 24 | { 25 | /** 26 | * This method is called by the LogoutListener when a user has requested 27 | * to be logged out. Usually, you would unset session variables, or remove 28 | * cookies, etc. 29 | */ 30 | public function logout(Request $request, Response $response, TokenInterface $token); 31 | } 32 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ./*/Tests/ 18 | 19 | 20 | 21 | 22 | 23 | ./ 24 | 25 | ./vendor 26 | ./*/Resources 27 | ./*/Tests 28 | ./*/vendor 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Core/Exception/SessionUnavailableException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * This exception is thrown when no session is available. 16 | * 17 | * Possible reasons for this are: 18 | * 19 | * a) The session timed out because the user waited too long. 20 | * b) The user has disabled cookies, and a new session is started on each 21 | * request. 22 | * 23 | * @author Johannes M. Schmitt 24 | * @author Alexander 25 | */ 26 | class SessionUnavailableException extends AuthenticationException 27 | { 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function getMessageKey() 32 | { 33 | return 'No session available, it either timed out or cookies are not enabled.'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Core/Authorization/AccessDecisionManagerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authorization; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * AccessDecisionManagerInterface makes authorization decisions. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | interface AccessDecisionManagerInterface 22 | { 23 | /** 24 | * Decides whether the access is possible or not. 25 | * 26 | * @param array $attributes An array of attributes associated with the method being invoked 27 | * @param object $object The object to secure 28 | * 29 | * @return bool true if the access is granted, false otherwise 30 | */ 31 | public function decide(TokenInterface $token, array $attributes, $object = null); 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2022 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Core/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2022 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Csrf/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2022 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Http/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2022 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Guard/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2022 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Core/Authentication/AuthenticationManagerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 16 | 17 | /** 18 | * AuthenticationManagerInterface is the interface for authentication managers, 19 | * which process Token authentication. 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | interface AuthenticationManagerInterface 24 | { 25 | /** 26 | * Attempts to authenticate a TokenInterface object. 27 | * 28 | * @return TokenInterface An authenticated TokenInterface instance, never null 29 | * 30 | * @throws AuthenticationException if the authentication fails 31 | */ 32 | public function authenticate(TokenInterface $token); 33 | } 34 | -------------------------------------------------------------------------------- /Http/Logout/LogoutSuccessHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Logout; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | 17 | /** 18 | * LogoutSuccesshandlerInterface. 19 | * 20 | * In contrast to the LogoutHandlerInterface, this interface can return a response 21 | * which is then used instead of the default behavior. 22 | * 23 | * If you want to only perform some logout related clean-up task, use the 24 | * LogoutHandlerInterface instead. 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | interface LogoutSuccessHandlerInterface 29 | { 30 | /** 31 | * Creates a Response object to send upon a successful logout. 32 | * 33 | * @return Response never null 34 | */ 35 | public function onLogoutSuccess(Request $request); 36 | } 37 | -------------------------------------------------------------------------------- /Core/Event/AuthenticationFailureEvent.php: -------------------------------------------------------------------------------- 1 | 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\Event; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 16 | 17 | /** 18 | * This event is dispatched on authentication failure. 19 | * 20 | * @author Johannes M. Schmitt 21 | * 22 | * @final since Symfony 4.4 23 | */ 24 | class AuthenticationFailureEvent extends AuthenticationEvent 25 | { 26 | private $authenticationException; 27 | 28 | public function __construct(TokenInterface $token, AuthenticationException $ex) 29 | { 30 | parent::__construct($token); 31 | 32 | $this->authenticationException = $ex; 33 | } 34 | 35 | public function getAuthenticationException() 36 | { 37 | return $this->authenticationException; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Core/Authentication/Token/Storage/TokenStorageInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Token\Storage; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * The TokenStorageInterface. 18 | * 19 | * @author Johannes M. Schmitt 20 | */ 21 | interface TokenStorageInterface 22 | { 23 | /** 24 | * Returns the current security token. 25 | * 26 | * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available 27 | */ 28 | public function getToken(); 29 | 30 | /** 31 | * Sets the authentication token. 32 | * 33 | * @param TokenInterface|null $token A TokenInterface token, or null if no further authentication information should be stored 34 | */ 35 | public function setToken(TokenInterface $token = null); 36 | } 37 | -------------------------------------------------------------------------------- /Http/Logout/CsrfTokenClearingLogoutHandler.php: -------------------------------------------------------------------------------- 1 | 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\Http\Logout; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface; 18 | 19 | /** 20 | * @author Christian Flothmann 21 | */ 22 | class CsrfTokenClearingLogoutHandler implements LogoutHandlerInterface 23 | { 24 | private $csrfTokenStorage; 25 | 26 | public function __construct(ClearableTokenStorageInterface $csrfTokenStorage) 27 | { 28 | $this->csrfTokenStorage = $csrfTokenStorage; 29 | } 30 | 31 | public function logout(Request $request, Response $response, TokenInterface $token) 32 | { 33 | $this->csrfTokenStorage->clear(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Http/Session/SessionAuthenticationStrategyInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Session; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | 17 | /** 18 | * SessionAuthenticationStrategyInterface. 19 | * 20 | * Implementation are responsible for updating the session after an interactive 21 | * authentication attempt was successful. 22 | * 23 | * @author Johannes M. Schmitt 24 | */ 25 | interface SessionAuthenticationStrategyInterface 26 | { 27 | /** 28 | * This performs any necessary changes to the session. 29 | * 30 | * This method should be called before the TokenStorage is populated with a 31 | * Token. It should be used by authentication listeners when a session is used. 32 | */ 33 | public function onAuthentication(Request $request, TokenInterface $token); 34 | } 35 | -------------------------------------------------------------------------------- /Csrf/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/security-csrf", 3 | "type": "library", 4 | "description": "Symfony Security Component - CSRF Library", 5 | "keywords": [], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1.3", 20 | "symfony/polyfill-php80": "^1.16", 21 | "symfony/security-core": "^3.4|^4.0|^5.0" 22 | }, 23 | "require-dev": { 24 | "symfony/http-foundation": "^3.4|^4.0|^5.0" 25 | }, 26 | "conflict": { 27 | "symfony/http-foundation": "<3.4" 28 | }, 29 | "suggest": { 30 | "symfony/http-foundation": "For using the class SessionTokenStorage." 31 | }, 32 | "autoload": { 33 | "psr-4": { "Symfony\\Component\\Security\\Csrf\\": "" }, 34 | "exclude-from-classmap": [ 35 | "/Tests/" 36 | ] 37 | }, 38 | "minimum-stability": "dev" 39 | } 40 | -------------------------------------------------------------------------------- /Http/SecurityEvents.php: -------------------------------------------------------------------------------- 1 | 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\Http; 13 | 14 | final class SecurityEvents 15 | { 16 | /** 17 | * The INTERACTIVE_LOGIN event occurs after a user has actively logged 18 | * into your website. It is important to distinguish this action from 19 | * non-interactive authentication methods, such as: 20 | * - authentication based on your session. 21 | * - authentication using an HTTP basic or HTTP digest header. 22 | * 23 | * @Event("Symfony\Component\Security\Http\Event\InteractiveLoginEvent") 24 | */ 25 | public const INTERACTIVE_LOGIN = 'security.interactive_login'; 26 | 27 | /** 28 | * The SWITCH_USER event occurs before switch to another user and 29 | * before exit from an already switched user. 30 | * 31 | * @Event("Symfony\Component\Security\Http\Event\SwitchUserEvent") 32 | */ 33 | public const SWITCH_USER = 'security.switch_user'; 34 | } 35 | -------------------------------------------------------------------------------- /Core/User/UserCheckerInterface.php: -------------------------------------------------------------------------------- 1 | 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\AccountStatusException; 15 | 16 | /** 17 | * Implement to throw AccountStatusException during the authentication process. 18 | * 19 | * Can be used when you want to check the account status, e.g when the account is 20 | * disabled or blocked. This should not be used to make authentication decisions. 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | interface UserCheckerInterface 25 | { 26 | /** 27 | * Checks the user account before authentication. 28 | * 29 | * @throws AccountStatusException 30 | */ 31 | public function checkPreAuth(UserInterface $user); 32 | 33 | /** 34 | * Checks the user account after authentication. 35 | * 36 | * @throws AccountStatusException 37 | */ 38 | public function checkPostAuth(UserInterface $user); 39 | } 40 | -------------------------------------------------------------------------------- /Core/Encoder/UserPasswordEncoderInterface.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | 16 | /** 17 | * UserPasswordEncoderInterface is the interface for the password encoder service. 18 | * 19 | * @author Ariel Ferrandini 20 | * 21 | * @method bool needsRehash(UserInterface $user) 22 | */ 23 | interface UserPasswordEncoderInterface 24 | { 25 | /** 26 | * Encodes the plain password. 27 | * 28 | * @param string $plainPassword The password to encode 29 | * 30 | * @return string The encoded password 31 | */ 32 | public function encodePassword(UserInterface $user, $plainPassword); 33 | 34 | /** 35 | * @param string $raw A raw password 36 | * 37 | * @return bool true if the password is valid, false otherwise 38 | */ 39 | public function isPasswordValid(UserInterface $user, $raw); 40 | } 41 | -------------------------------------------------------------------------------- /Http/FirewallMapInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | 16 | /** 17 | * This interface must be implemented by firewall maps. 18 | * 19 | * @author Johannes M. Schmitt 20 | */ 21 | interface FirewallMapInterface 22 | { 23 | /** 24 | * Returns the authentication listeners, and the exception listener to use 25 | * for the given request. 26 | * 27 | * If there are no authentication listeners, the first inner array must be 28 | * empty. 29 | * 30 | * If there is no exception listener, the second element of the outer array 31 | * must be null. 32 | * 33 | * If there is no logout listener, the third element of the outer array 34 | * must be null. 35 | * 36 | * @return array of the format [[AuthenticationListener], ExceptionListener, LogoutListener] 37 | */ 38 | public function getListeners(Request $request); 39 | } 40 | -------------------------------------------------------------------------------- /Http/Logout/DefaultLogoutSuccessHandler.php: -------------------------------------------------------------------------------- 1 | 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\Http\Logout; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Http\HttpUtils; 16 | 17 | /** 18 | * Default logout success handler will redirect users to a configured path. 19 | * 20 | * @author Fabien Potencier 21 | * @author Alexander 22 | */ 23 | class DefaultLogoutSuccessHandler implements LogoutSuccessHandlerInterface 24 | { 25 | protected $httpUtils; 26 | protected $targetUrl; 27 | 28 | public function __construct(HttpUtils $httpUtils, string $targetUrl = '/') 29 | { 30 | $this->httpUtils = $httpUtils; 31 | $this->targetUrl = $targetUrl; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function onLogoutSuccess(Request $request) 38 | { 39 | return $this->httpUtils->createRedirectResponse($request, $this->targetUrl); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Guard/AbstractGuardAuthenticator.php: -------------------------------------------------------------------------------- 1 | 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\Guard; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; 16 | 17 | /** 18 | * An optional base class that creates a PostAuthenticationGuardToken for you. 19 | * 20 | * @author Ryan Weaver 21 | */ 22 | abstract class AbstractGuardAuthenticator implements AuthenticatorInterface 23 | { 24 | /** 25 | * Shortcut to create a PostAuthenticationGuardToken for you, if you don't really 26 | * care about which authenticated token you're using. 27 | * 28 | * @param string $providerKey 29 | * 30 | * @return PostAuthenticationGuardToken 31 | */ 32 | public function createAuthenticatedToken(UserInterface $user, $providerKey) 33 | { 34 | return new PostAuthenticationGuardToken( 35 | $user, 36 | $providerKey, 37 | $user->getRoles() 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Http/Event/DeauthenticatedEvent.php: -------------------------------------------------------------------------------- 1 | 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\Http\Event; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Contracts\EventDispatcher\Event; 16 | 17 | /** 18 | * Deauthentication happens in case the user has changed when trying to refresh the token. 19 | * 20 | * @author Hamza Amrouche 21 | * 22 | * @final since Symfony 4.4 23 | */ 24 | class DeauthenticatedEvent extends Event 25 | { 26 | private $originalToken; 27 | private $refreshedToken; 28 | 29 | public function __construct(TokenInterface $originalToken, TokenInterface $refreshedToken) 30 | { 31 | $this->originalToken = $originalToken; 32 | $this->refreshedToken = $refreshedToken; 33 | } 34 | 35 | public function getRefreshedToken(): TokenInterface 36 | { 37 | return $this->refreshedToken; 38 | } 39 | 40 | public function getOriginalToken(): TokenInterface 41 | { 42 | return $this->originalToken; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Core/Authorization/Voter/VoterInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authorization\Voter; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * VoterInterface is the interface implemented by all voters. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | interface VoterInterface 22 | { 23 | public const ACCESS_GRANTED = 1; 24 | public const ACCESS_ABSTAIN = 0; 25 | public const ACCESS_DENIED = -1; 26 | 27 | /** 28 | * Returns the vote for the given parameters. 29 | * 30 | * This method must return one of the following constants: 31 | * ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN. 32 | * 33 | * @param mixed $subject The subject to secure 34 | * @param array $attributes An array of attributes associated with the method being invoked 35 | * 36 | * @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED 37 | */ 38 | public function vote(TokenInterface $token, $subject, array $attributes); 39 | } 40 | -------------------------------------------------------------------------------- /Core/Role/Role.php: -------------------------------------------------------------------------------- 1 | 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\Role; 13 | 14 | /** 15 | * Role is a simple implementation representing a role identified by a string. 16 | * 17 | * @author Fabien Potencier 18 | * 19 | * @deprecated since Symfony 4.3, to be removed in 5.0. Use strings as roles instead. 20 | */ 21 | class Role 22 | { 23 | private $role; 24 | 25 | public function __construct(string $role) 26 | { 27 | if (\func_num_args() < 2 || func_get_arg(1)) { 28 | @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), \E_USER_DEPRECATED); 29 | } 30 | 31 | $this->role = $role; 32 | } 33 | 34 | /** 35 | * Returns a string representation of the role. 36 | * 37 | * @return string 38 | */ 39 | public function getRole() 40 | { 41 | return $this->role; 42 | } 43 | 44 | public function __toString(): string 45 | { 46 | return $this->role; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Csrf/TokenGenerator/UriSafeTokenGenerator.php: -------------------------------------------------------------------------------- 1 | 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\Csrf\TokenGenerator; 13 | 14 | /** 15 | * Generates CSRF tokens. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class UriSafeTokenGenerator implements TokenGeneratorInterface 20 | { 21 | private $entropy; 22 | 23 | /** 24 | * Generates URI-safe CSRF tokens. 25 | * 26 | * @param int $entropy The amount of entropy collected for each token (in bits) 27 | */ 28 | public function __construct(int $entropy = 256) 29 | { 30 | $this->entropy = $entropy; 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function generateToken() 37 | { 38 | // Generate an URI safe base64 encoded string that does not contain "+", 39 | // "/" or "=" which need to be URL encoded and make URLs unnecessarily 40 | // longer. 41 | $bytes = random_bytes($this->entropy / 8); 42 | 43 | return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '='); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Csrf/CsrfToken.php: -------------------------------------------------------------------------------- 1 | 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\Csrf; 13 | 14 | /** 15 | * A CSRF token. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | class CsrfToken 20 | { 21 | private $id; 22 | private $value; 23 | 24 | public function __construct(string $id, ?string $value) 25 | { 26 | $this->id = $id; 27 | $this->value = $value ?? ''; 28 | } 29 | 30 | /** 31 | * Returns the ID of the CSRF token. 32 | * 33 | * @return string The token ID 34 | */ 35 | public function getId() 36 | { 37 | return $this->id; 38 | } 39 | 40 | /** 41 | * Returns the value of the CSRF token. 42 | * 43 | * @return string The token value 44 | */ 45 | public function getValue() 46 | { 47 | return $this->value; 48 | } 49 | 50 | /** 51 | * Returns the value of the CSRF token. 52 | * 53 | * @return string The token value 54 | */ 55 | public function __toString() 56 | { 57 | return $this->value; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Http/Authentication/AuthenticationSuccessHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | 18 | /** 19 | * Interface for a custom authentication success handler. 20 | * 21 | * If you want to customize the success handling process, instead of 22 | * overwriting the respective listener globally, you can set a custom success 23 | * handler which implements this interface. 24 | * 25 | * @author Johannes M. Schmitt 26 | */ 27 | interface AuthenticationSuccessHandlerInterface 28 | { 29 | /** 30 | * This is called when an interactive authentication attempt succeeds. This 31 | * is called by authentication listeners inheriting from 32 | * AbstractAuthenticationListener. 33 | * 34 | * @return Response 35 | */ 36 | public function onAuthenticationSuccess(Request $request, TokenInterface $token); 37 | } 38 | -------------------------------------------------------------------------------- /Core/Authentication/Provider/AuthenticationProviderInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Provider; 13 | 14 | use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | 17 | /** 18 | * AuthenticationProviderInterface is the interface for all authentication 19 | * providers. 20 | * 21 | * Concrete implementations processes specific Token instances. 22 | * 23 | * @author Fabien Potencier 24 | */ 25 | interface AuthenticationProviderInterface extends AuthenticationManagerInterface 26 | { 27 | /** 28 | * Use this constant for not provided username. 29 | * 30 | * @var string 31 | */ 32 | public const USERNAME_NONE_PROVIDED = 'NONE_PROVIDED'; 33 | 34 | /** 35 | * Checks whether this provider supports the given token. 36 | * 37 | * @return bool true if the implementation supports the Token, false otherwise 38 | */ 39 | public function supports(TokenInterface $token); 40 | } 41 | -------------------------------------------------------------------------------- /Http/EntryPoint/BasicAuthenticationEntryPoint.php: -------------------------------------------------------------------------------- 1 | 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\Http\EntryPoint; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | 18 | /** 19 | * BasicAuthenticationEntryPoint starts an HTTP Basic authentication. 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface 24 | { 25 | private $realmName; 26 | 27 | public function __construct(string $realmName) 28 | { 29 | $this->realmName = $realmName; 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function start(Request $request, AuthenticationException $authException = null) 36 | { 37 | $response = new Response(); 38 | $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName)); 39 | $response->setStatusCode(401); 40 | 41 | return $response; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Http/Authentication/AuthenticationFailureHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | 18 | /** 19 | * Interface for custom authentication failure handlers. 20 | * 21 | * If you want to customize the failure handling process, instead of 22 | * overwriting the respective listener globally, you can set a custom failure 23 | * handler which implements this interface. 24 | * 25 | * @author Johannes M. Schmitt 26 | */ 27 | interface AuthenticationFailureHandlerInterface 28 | { 29 | /** 30 | * This is called when an interactive authentication attempt fails. This is 31 | * called by authentication listeners inheriting from 32 | * AbstractAuthenticationListener. 33 | * 34 | * @return Response The response to return, never null 35 | */ 36 | public function onAuthenticationFailure(Request $request, AuthenticationException $exception); 37 | } 38 | -------------------------------------------------------------------------------- /Http/Authentication/CustomAuthenticationFailureHandler.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 16 | 17 | /** 18 | * @author Fabien Potencier 19 | */ 20 | class CustomAuthenticationFailureHandler implements AuthenticationFailureHandlerInterface 21 | { 22 | private $handler; 23 | 24 | /** 25 | * @param array $options Options for processing a successful authentication attempt 26 | */ 27 | public function __construct(AuthenticationFailureHandlerInterface $handler, array $options) 28 | { 29 | $this->handler = $handler; 30 | if (method_exists($handler, 'setOptions')) { 31 | $this->handler->setOptions($options); 32 | } 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 39 | { 40 | return $this->handler->onAuthenticationFailure($request, $exception); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Core/Authentication/RememberMe/PersistentTokenInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\RememberMe; 13 | 14 | /** 15 | * Interface to be implemented by persistent token classes (such as 16 | * Doctrine entities representing a remember-me token). 17 | * 18 | * @author Johannes M. Schmitt 19 | */ 20 | interface PersistentTokenInterface 21 | { 22 | /** 23 | * Returns the class of the user. 24 | * 25 | * @return string 26 | */ 27 | public function getClass(); 28 | 29 | /** 30 | * Returns the username. 31 | * 32 | * @return string 33 | */ 34 | public function getUsername(); 35 | 36 | /** 37 | * Returns the series. 38 | * 39 | * @return string 40 | */ 41 | public function getSeries(); 42 | 43 | /** 44 | * Returns the token value. 45 | * 46 | * @return string 47 | */ 48 | public function getTokenValue(); 49 | 50 | /** 51 | * Returns the time the token was last used. 52 | * 53 | * @return \DateTime 54 | */ 55 | public function getLastUsed(); 56 | } 57 | -------------------------------------------------------------------------------- /Http/Firewall/AbstractListener.php: -------------------------------------------------------------------------------- 1 | 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\Http\Firewall; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpKernel\Event\RequestEvent; 16 | 17 | /** 18 | * A base class for listeners that can tell whether they should authenticate incoming requests. 19 | * 20 | * @author Nicolas Grekas 21 | */ 22 | abstract class AbstractListener 23 | { 24 | final public function __invoke(RequestEvent $event) 25 | { 26 | if (false !== $this->supports($event->getRequest())) { 27 | $this->authenticate($event); 28 | } 29 | } 30 | 31 | /** 32 | * Tells whether the authenticate() method should be called or not depending on the incoming request. 33 | * 34 | * Returning null means authenticate() can be called lazily when accessing the token storage. 35 | */ 36 | abstract public function supports(Request $request): ?bool; 37 | 38 | /** 39 | * Does whatever is required to authenticate the request, typically calling $event->setResponse() internally. 40 | */ 41 | abstract public function authenticate(RequestEvent $event); 42 | } 43 | -------------------------------------------------------------------------------- /Core/Authentication/AuthenticationTrustResolverInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * Interface for resolving the authentication status of a given token. 18 | * 19 | * @author Johannes M. Schmitt 20 | */ 21 | interface AuthenticationTrustResolverInterface 22 | { 23 | /** 24 | * Resolves whether the passed token implementation is authenticated 25 | * anonymously. 26 | * 27 | * If null is passed, the method must return false. 28 | * 29 | * @return bool 30 | */ 31 | public function isAnonymous(TokenInterface $token = null); 32 | 33 | /** 34 | * Resolves whether the passed token implementation is authenticated 35 | * using remember-me capabilities. 36 | * 37 | * @return bool 38 | */ 39 | public function isRememberMe(TokenInterface $token = null); 40 | 41 | /** 42 | * Resolves whether the passed token implementation is fully authenticated. 43 | * 44 | * @return bool 45 | */ 46 | public function isFullFledged(TokenInterface $token = null); 47 | } 48 | -------------------------------------------------------------------------------- /Http/Event/InteractiveLoginEvent.php: -------------------------------------------------------------------------------- 1 | 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\Http\Event; 13 | 14 | use Symfony\Component\EventDispatcher\Event; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | 18 | /** 19 | * @author Fabien Potencier 20 | * 21 | * @final since Symfony 4.4 22 | */ 23 | class InteractiveLoginEvent extends Event 24 | { 25 | private $request; 26 | private $authenticationToken; 27 | 28 | public function __construct(Request $request, TokenInterface $authenticationToken) 29 | { 30 | $this->request = $request; 31 | $this->authenticationToken = $authenticationToken; 32 | } 33 | 34 | /** 35 | * Gets the request. 36 | * 37 | * @return Request A Request instance 38 | */ 39 | public function getRequest() 40 | { 41 | return $this->request; 42 | } 43 | 44 | /** 45 | * Gets the authentication token. 46 | * 47 | * @return TokenInterface A TokenInterface instance 48 | */ 49 | public function getAuthenticationToken() 50 | { 51 | return $this->authenticationToken; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Core/Event/VoteEvent.php: -------------------------------------------------------------------------------- 1 | 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\Event; 13 | 14 | use Symfony\Component\EventDispatcher\Event; 15 | use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; 16 | 17 | /** 18 | * This event is dispatched on voter vote. 19 | * 20 | * @author Laurent VOULLEMIER 21 | * 22 | * @internal 23 | */ 24 | final class VoteEvent extends Event 25 | { 26 | private $voter; 27 | private $subject; 28 | private $attributes; 29 | private $vote; 30 | 31 | public function __construct(VoterInterface $voter, $subject, array $attributes, int $vote) 32 | { 33 | $this->voter = $voter; 34 | $this->subject = $subject; 35 | $this->attributes = $attributes; 36 | $this->vote = $vote; 37 | } 38 | 39 | public function getVoter(): VoterInterface 40 | { 41 | return $this->voter; 42 | } 43 | 44 | public function getSubject() 45 | { 46 | return $this->subject; 47 | } 48 | 49 | public function getAttributes(): array 50 | { 51 | return $this->attributes; 52 | } 53 | 54 | public function getVote(): int 55 | { 56 | return $this->vote; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Http/RememberMe/ResponseListener.php: -------------------------------------------------------------------------------- 1 | 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\Http\RememberMe; 13 | 14 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 15 | use Symfony\Component\HttpKernel\Event\FilterResponseEvent; 16 | use Symfony\Component\HttpKernel\KernelEvents; 17 | 18 | /** 19 | * Adds remember-me cookies to the Response. 20 | * 21 | * @author Johannes M. Schmitt 22 | * 23 | * @final since Symfony 4.3 24 | */ 25 | class ResponseListener implements EventSubscriberInterface 26 | { 27 | public function onKernelResponse(FilterResponseEvent $event) 28 | { 29 | if (!$event->isMasterRequest()) { 30 | return; 31 | } 32 | 33 | $request = $event->getRequest(); 34 | $response = $event->getResponse(); 35 | 36 | if ($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)) { 37 | $response->headers->setCookie($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)); 38 | } 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public static function getSubscribedEvents() 45 | { 46 | return [KernelEvents::RESPONSE => 'onKernelResponse']; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Http/Logout/CookieClearingLogoutHandler.php: -------------------------------------------------------------------------------- 1 | 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\Http\Logout; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | 18 | /** 19 | * This handler clears the passed cookies when a user logs out. 20 | * 21 | * @author Johannes M. Schmitt 22 | */ 23 | class CookieClearingLogoutHandler implements LogoutHandlerInterface 24 | { 25 | private $cookies; 26 | 27 | /** 28 | * @param array $cookies An array of cookie names to unset 29 | */ 30 | public function __construct(array $cookies) 31 | { 32 | $this->cookies = $cookies; 33 | } 34 | 35 | /** 36 | * Implementation for the LogoutHandlerInterface. Deletes all requested cookies. 37 | */ 38 | public function logout(Request $request, Response $response, TokenInterface $token) 39 | { 40 | foreach ($this->cookies as $cookieName => $cookieData) { 41 | $response->headers->clearCookie($cookieName, $cookieData['path'], $cookieData['domain'], $cookieData['secure'] ?? false, true, $cookieData['samesite'] ?? null); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Core/Exception/AccessDeniedException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * AccessDeniedException is thrown when the account has not the required role. 16 | * 17 | * @author Fabien Potencier 18 | */ 19 | class AccessDeniedException extends RuntimeException 20 | { 21 | private $attributes = []; 22 | private $subject; 23 | 24 | public function __construct(string $message = 'Access Denied.', \Throwable $previous = null) 25 | { 26 | parent::__construct($message, 403, $previous); 27 | } 28 | 29 | /** 30 | * @return array 31 | */ 32 | public function getAttributes() 33 | { 34 | return $this->attributes; 35 | } 36 | 37 | /** 38 | * @param array|string $attributes 39 | */ 40 | public function setAttributes($attributes) 41 | { 42 | $this->attributes = (array) $attributes; 43 | } 44 | 45 | /** 46 | * @return mixed 47 | */ 48 | public function getSubject() 49 | { 50 | return $this->subject; 51 | } 52 | 53 | /** 54 | * @param mixed $subject 55 | */ 56 | public function setSubject($subject) 57 | { 58 | $this->subject = $subject; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Http/Util/TargetPathTrait.php: -------------------------------------------------------------------------------- 1 | 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\Http\Util; 13 | 14 | use Symfony\Component\HttpFoundation\Session\SessionInterface; 15 | 16 | /** 17 | * Trait to get (and set) the URL the user last visited before being forced to authenticate. 18 | */ 19 | trait TargetPathTrait 20 | { 21 | /** 22 | * Sets the target path the user should be redirected to after authentication. 23 | * 24 | * Usually, you do not need to set this directly. 25 | */ 26 | private function saveTargetPath(SessionInterface $session, string $providerKey, string $uri) 27 | { 28 | $session->set('_security.'.$providerKey.'.target_path', $uri); 29 | } 30 | 31 | /** 32 | * Returns the URL (if any) the user visited that forced them to login. 33 | */ 34 | private function getTargetPath(SessionInterface $session, string $providerKey): ?string 35 | { 36 | return $session->get('_security.'.$providerKey.'.target_path'); 37 | } 38 | 39 | /** 40 | * Removes the target path from the session. 41 | */ 42 | private function removeTargetPath(SessionInterface $session, string $providerKey) 43 | { 44 | $session->remove('_security.'.$providerKey.'.target_path'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Http/AccessMap.php: -------------------------------------------------------------------------------- 1 | 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\Http; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\RequestMatcherInterface; 16 | 17 | /** 18 | * AccessMap allows configuration of different access control rules for 19 | * specific parts of the website. 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | class AccessMap implements AccessMapInterface 24 | { 25 | private $map = []; 26 | 27 | /** 28 | * @param array $attributes An array of attributes to pass to the access decision manager (like roles) 29 | * @param string|null $channel The channel to enforce (http, https, or null) 30 | */ 31 | public function add(RequestMatcherInterface $requestMatcher, array $attributes = [], $channel = null) 32 | { 33 | $this->map[] = [$requestMatcher, $attributes, $channel]; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function getPatterns(Request $request) 40 | { 41 | foreach ($this->map as $elements) { 42 | if (null === $elements[0] || $elements[0]->matches($request)) { 43 | return [$elements[1], $elements[2]]; 44 | } 45 | } 46 | 47 | return [null, null]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Http/FirewallMap.php: -------------------------------------------------------------------------------- 1 | 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\Http; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\RequestMatcherInterface; 16 | use Symfony\Component\Security\Http\Firewall\ExceptionListener; 17 | use Symfony\Component\Security\Http\Firewall\LogoutListener; 18 | 19 | /** 20 | * FirewallMap allows configuration of different firewalls for specific parts 21 | * of the website. 22 | * 23 | * @author Fabien Potencier 24 | */ 25 | class FirewallMap implements FirewallMapInterface 26 | { 27 | private $map = []; 28 | 29 | public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = [], ExceptionListener $exceptionListener = null, LogoutListener $logoutListener = null) 30 | { 31 | $this->map[] = [$requestMatcher, $listeners, $exceptionListener, $logoutListener]; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function getListeners(Request $request) 38 | { 39 | foreach ($this->map as $elements) { 40 | if (null === $elements[0] || $elements[0]->matches($request)) { 41 | return [$elements[1], $elements[2], $elements[3]]; 42 | } 43 | } 44 | 45 | return [[], null, null]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Core/User/MissingUserProvider.php: -------------------------------------------------------------------------------- 1 | 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\Config\Definition\Exception\InvalidConfigurationException; 15 | 16 | /** 17 | * MissingUserProvider is a dummy user provider used to throw proper exception 18 | * when a firewall requires a user provider but none was defined. 19 | * 20 | * @internal 21 | */ 22 | class MissingUserProvider implements UserProviderInterface 23 | { 24 | /** 25 | * @param string $firewall the firewall missing a provider 26 | */ 27 | public function __construct(string $firewall) 28 | { 29 | throw new InvalidConfigurationException(sprintf('"%s" firewall requires a user provider but none was defined.', $firewall)); 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function loadUserByUsername($username): UserInterface 36 | { 37 | throw new \BadMethodCallException(); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function refreshUser(UserInterface $user): UserInterface 44 | { 45 | throw new \BadMethodCallException(); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function supportsClass($class): bool 52 | { 53 | throw new \BadMethodCallException(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Http/Authentication/CustomAuthenticationSuccessHandler.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | 17 | /** 18 | * @author Fabien Potencier 19 | */ 20 | class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface 21 | { 22 | private $handler; 23 | 24 | /** 25 | * @param array $options Options for processing a successful authentication attempt 26 | * @param string $providerKey The provider key 27 | */ 28 | public function __construct(AuthenticationSuccessHandlerInterface $handler, array $options, string $providerKey) 29 | { 30 | $this->handler = $handler; 31 | if (method_exists($handler, 'setOptions')) { 32 | $this->handler->setOptions($options); 33 | } 34 | if (method_exists($handler, 'setProviderKey')) { 35 | $this->handler->setProviderKey($providerKey); 36 | } 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function onAuthenticationSuccess(Request $request, TokenInterface $token) 43 | { 44 | return $this->handler->onAuthenticationSuccess($request, $token); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Core/Exception/AccountStatusException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | 16 | /** 17 | * AccountStatusException is the base class for authentication exceptions 18 | * caused by the user account status. 19 | * 20 | * @author Fabien Potencier 21 | * @author Alexander 22 | */ 23 | abstract class AccountStatusException extends AuthenticationException 24 | { 25 | private $user; 26 | 27 | /** 28 | * Get the user. 29 | * 30 | * @return UserInterface|null 31 | */ 32 | public function getUser() 33 | { 34 | return $this->user; 35 | } 36 | 37 | public function setUser(UserInterface $user) 38 | { 39 | $this->user = $user; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function __serialize(): array 46 | { 47 | return [$this->user, parent::__serialize()]; 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function __unserialize(array $data): void 54 | { 55 | [$this->user, $parentData] = $data; 56 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 57 | parent::__unserialize($parentData); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Core/Authentication/RememberMe/TokenProviderInterface.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\RememberMe; 13 | 14 | use Symfony\Component\Security\Core\Exception\TokenNotFoundException; 15 | 16 | /** 17 | * Interface for TokenProviders. 18 | * 19 | * @author Johannes M. Schmitt 20 | */ 21 | interface TokenProviderInterface 22 | { 23 | /** 24 | * Loads the active token for the given series. 25 | * 26 | * @param string $series 27 | * 28 | * @return PersistentTokenInterface 29 | * 30 | * @throws TokenNotFoundException if the token is not found 31 | */ 32 | public function loadTokenBySeries($series); 33 | 34 | /** 35 | * Deletes all tokens belonging to series. 36 | * 37 | * @param string $series 38 | */ 39 | public function deleteTokenBySeries($series); 40 | 41 | /** 42 | * Updates the token according to this data. 43 | * 44 | * @param string $series 45 | * @param string $tokenValue 46 | * 47 | * @throws TokenNotFoundException if the token is not found 48 | */ 49 | public function updateToken($series, $tokenValue, \DateTime $lastUsed); 50 | 51 | /** 52 | * Creates a new token. 53 | */ 54 | public function createNewToken(PersistentTokenInterface $token); 55 | } 56 | -------------------------------------------------------------------------------- /Core/Authorization/ExpressionLanguage.php: -------------------------------------------------------------------------------- 1 | 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\Authorization; 13 | 14 | use Psr\Cache\CacheItemPoolInterface; 15 | use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; 16 | 17 | // Help opcache.preload discover always-needed symbols 18 | class_exists(ExpressionLanguageProvider::class); 19 | 20 | if (!class_exists(BaseExpressionLanguage::class)) { 21 | throw new \LogicException(sprintf('The "%s" class requires the "ExpressionLanguage" component. Try running "composer require symfony/expression-language".', ExpressionLanguage::class)); 22 | } else { 23 | /** 24 | * Adds some function to the default ExpressionLanguage. 25 | * 26 | * @author Fabien Potencier 27 | * 28 | * @see ExpressionLanguageProvider 29 | */ 30 | class ExpressionLanguage extends BaseExpressionLanguage 31 | { 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function __construct(CacheItemPoolInterface $cache = null, array $providers = []) 36 | { 37 | // prepend the default provider to let users override it easily 38 | array_unshift($providers, new ExpressionLanguageProvider()); 39 | 40 | parent::__construct($cache, $providers); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Http/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/security-http", 3 | "type": "library", 4 | "description": "Symfony Security Component - HTTP Integration", 5 | "keywords": [], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1.3", 20 | "symfony/security-core": "^4.4.8", 21 | "symfony/http-foundation": "^3.4.40|^4.4.7|^5.0.7", 22 | "symfony/http-kernel": "^4.4", 23 | "symfony/polyfill-php80": "^1.16", 24 | "symfony/property-access": "^3.4|^4.0|^5.0" 25 | }, 26 | "require-dev": { 27 | "symfony/routing": "^3.4|^4.0|^5.0", 28 | "symfony/security-csrf": "^3.4.11|^4.0.11|^5.0", 29 | "psr/log": "^1|^2|^3" 30 | }, 31 | "conflict": { 32 | "symfony/event-dispatcher": ">=5", 33 | "symfony/security-csrf": "<3.4.11|~4.0,<4.0.11" 34 | }, 35 | "suggest": { 36 | "symfony/security-csrf": "For using tokens to protect authentication/logout attempts", 37 | "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs" 38 | }, 39 | "autoload": { 40 | "psr-4": { "Symfony\\Component\\Security\\Http\\": "" }, 41 | "exclude-from-classmap": [ 42 | "/Tests/" 43 | ] 44 | }, 45 | "minimum-stability": "dev" 46 | } 47 | -------------------------------------------------------------------------------- /Core/Encoder/PasswordEncoderInterface.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 15 | 16 | /** 17 | * PasswordEncoderInterface is the interface for all encoders. 18 | * 19 | * @author Fabien Potencier 20 | * 21 | * @method bool needsRehash(string $encoded) 22 | */ 23 | interface PasswordEncoderInterface 24 | { 25 | /** 26 | * Encodes the raw password. 27 | * 28 | * @param string $raw The password to encode 29 | * @param string|null $salt The salt 30 | * 31 | * @return string The encoded password 32 | * 33 | * @throws BadCredentialsException If the raw password is invalid, e.g. excessively long 34 | * @throws \InvalidArgumentException If the salt is invalid 35 | */ 36 | public function encodePassword($raw, $salt); 37 | 38 | /** 39 | * Checks a raw password against an encoded password. 40 | * 41 | * @param string $encoded An encoded password 42 | * @param string $raw A raw password 43 | * @param string|null $salt The salt 44 | * 45 | * @return bool true if the password is valid, false otherwise 46 | * 47 | * @throws \InvalidArgumentException If the salt is invalid 48 | */ 49 | public function isPasswordValid($encoded, $raw, $salt); 50 | } 51 | -------------------------------------------------------------------------------- /Http/EntryPoint/AuthenticationEntryPointInterface.php: -------------------------------------------------------------------------------- 1 | 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\Http\EntryPoint; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | 18 | /** 19 | * Implement this interface for any classes that will be called to "start" 20 | * the authentication process (see method for more details). 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | interface AuthenticationEntryPointInterface 25 | { 26 | /** 27 | * Returns a response that directs the user to authenticate. 28 | * 29 | * This is called when an anonymous request accesses a resource that 30 | * requires authentication. The job of this method is to return some 31 | * response that "helps" the user start into the authentication process. 32 | * 33 | * Examples: 34 | * 35 | * - For a form login, you might redirect to the login page 36 | * 37 | * return new RedirectResponse('/login'); 38 | * 39 | * - For an API token authentication system, you return a 401 response 40 | * 41 | * return new Response('Auth header required', 401); 42 | * 43 | * @return Response 44 | */ 45 | public function start(Request $request, AuthenticationException $authException = null); 46 | } 47 | -------------------------------------------------------------------------------- /Csrf/TokenStorage/TokenStorageInterface.php: -------------------------------------------------------------------------------- 1 | 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\Csrf\TokenStorage; 13 | 14 | /** 15 | * Stores CSRF tokens. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | interface TokenStorageInterface 20 | { 21 | /** 22 | * Reads a stored CSRF token. 23 | * 24 | * @param string $tokenId The token ID 25 | * 26 | * @return string The stored token 27 | * 28 | * @throws \Symfony\Component\Security\Csrf\Exception\TokenNotFoundException If the token ID does not exist 29 | */ 30 | public function getToken($tokenId); 31 | 32 | /** 33 | * Stores a CSRF token. 34 | * 35 | * @param string $tokenId The token ID 36 | * @param string $token The CSRF token 37 | */ 38 | public function setToken($tokenId, $token); 39 | 40 | /** 41 | * Removes a CSRF token. 42 | * 43 | * @param string $tokenId The token ID 44 | * 45 | * @return string|null Returns the removed token if one existed, NULL 46 | * otherwise 47 | */ 48 | public function removeToken($tokenId); 49 | 50 | /** 51 | * Checks whether a token with the given token ID exists. 52 | * 53 | * @param string $tokenId The token ID 54 | * 55 | * @return bool Whether a token exists with the given ID 56 | */ 57 | public function hasToken($tokenId); 58 | } 59 | -------------------------------------------------------------------------------- /Http/Event/SwitchUserEvent.php: -------------------------------------------------------------------------------- 1 | 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\Http\Event; 13 | 14 | use Symfony\Component\EventDispatcher\Event; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | use Symfony\Component\Security\Core\User\UserInterface; 18 | 19 | /** 20 | * SwitchUserEvent. 21 | * 22 | * @author Fabien Potencier 23 | * 24 | * @final since Symfony 4.4 25 | */ 26 | class SwitchUserEvent extends Event 27 | { 28 | private $request; 29 | private $targetUser; 30 | private $token; 31 | 32 | public function __construct(Request $request, UserInterface $targetUser, TokenInterface $token = null) 33 | { 34 | $this->request = $request; 35 | $this->targetUser = $targetUser; 36 | $this->token = $token; 37 | } 38 | 39 | /** 40 | * @return Request 41 | */ 42 | public function getRequest() 43 | { 44 | return $this->request; 45 | } 46 | 47 | /** 48 | * @return UserInterface 49 | */ 50 | public function getTargetUser() 51 | { 52 | return $this->targetUser; 53 | } 54 | 55 | /** 56 | * @return TokenInterface|null 57 | */ 58 | public function getToken() 59 | { 60 | return $this->token; 61 | } 62 | 63 | public function setToken(TokenInterface $token) 64 | { 65 | $this->token = $token; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Core/Authorization/Voter/TraceableVoter.php: -------------------------------------------------------------------------------- 1 | 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\Authorization\Voter; 13 | 14 | use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Core\Event\VoteEvent; 17 | use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; 18 | 19 | /** 20 | * Decorates voter classes to send result events. 21 | * 22 | * @author Laurent VOULLEMIER 23 | * 24 | * @internal 25 | */ 26 | class TraceableVoter implements VoterInterface 27 | { 28 | private $voter; 29 | private $eventDispatcher; 30 | 31 | public function __construct(VoterInterface $voter, EventDispatcherInterface $eventDispatcher) 32 | { 33 | $this->voter = $voter; 34 | 35 | if (class_exists(LegacyEventDispatcherProxy::class)) { 36 | $this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher); 37 | } else { 38 | $this->eventDispatcher = $eventDispatcher; 39 | } 40 | } 41 | 42 | public function vote(TokenInterface $token, $subject, array $attributes) 43 | { 44 | $result = $this->voter->vote($token, $subject, $attributes); 45 | 46 | $this->eventDispatcher->dispatch(new VoteEvent($this->voter, $subject, $attributes, $result), 'debug.security.authorization.vote'); 47 | 48 | return $result; 49 | } 50 | 51 | public function getDecoratedVoter(): VoterInterface 52 | { 53 | return $this->voter; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Http/Firewall/RemoteUserAuthenticationListener.php: -------------------------------------------------------------------------------- 1 | 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\Http\Firewall; 13 | 14 | use Psr\Log\LoggerInterface; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; 17 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 18 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 19 | use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; 20 | 21 | /** 22 | * REMOTE_USER authentication listener. 23 | * 24 | * @author Fabien Potencier 25 | * @author Maxime Douailin 26 | */ 27 | class RemoteUserAuthenticationListener extends AbstractPreAuthenticatedListener 28 | { 29 | private $userKey; 30 | 31 | public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, string $providerKey, string $userKey = 'REMOTE_USER', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) 32 | { 33 | parent::__construct($tokenStorage, $authenticationManager, $providerKey, $logger, $dispatcher); 34 | 35 | $this->userKey = $userKey; 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | protected function getPreAuthenticatedData(Request $request) 42 | { 43 | if (!$request->server->has($this->userKey)) { 44 | throw new BadCredentialsException(sprintf('User key was not found: "%s".', $this->userKey)); 45 | } 46 | 47 | return [$request->server->get($this->userKey), null]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Core/Encoder/UserPasswordEncoder.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | 16 | /** 17 | * A generic password encoder. 18 | * 19 | * @author Ariel Ferrandini 20 | */ 21 | class UserPasswordEncoder implements UserPasswordEncoderInterface 22 | { 23 | private $encoderFactory; 24 | 25 | public function __construct(EncoderFactoryInterface $encoderFactory) 26 | { 27 | $this->encoderFactory = $encoderFactory; 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function encodePassword(UserInterface $user, $plainPassword) 34 | { 35 | $encoder = $this->encoderFactory->getEncoder($user); 36 | 37 | return $encoder->encodePassword($plainPassword, $user->getSalt()); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function isPasswordValid(UserInterface $user, $raw) 44 | { 45 | if (null === $user->getPassword()) { 46 | return false; 47 | } 48 | 49 | $encoder = $this->encoderFactory->getEncoder($user); 50 | 51 | return $encoder->isPasswordValid($user->getPassword(), $raw, $user->getSalt()); 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function needsRehash(UserInterface $user): bool 58 | { 59 | if (null === $user->getPassword()) { 60 | return false; 61 | } 62 | 63 | $encoder = $this->encoderFactory->getEncoder($user); 64 | 65 | return method_exists($encoder, 'needsRehash') && $encoder->needsRehash($user->getPassword()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Core/Exception/UsernameNotFoundException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * UsernameNotFoundException is thrown if a User cannot be found by its username. 16 | * 17 | * @author Fabien Potencier 18 | * @author Alexander 19 | */ 20 | class UsernameNotFoundException extends AuthenticationException 21 | { 22 | private $username; 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function getMessageKey() 28 | { 29 | return 'Username could not be found.'; 30 | } 31 | 32 | /** 33 | * Get the username. 34 | * 35 | * @return string 36 | */ 37 | public function getUsername() 38 | { 39 | return $this->username; 40 | } 41 | 42 | /** 43 | * Set the username. 44 | * 45 | * @param string $username 46 | */ 47 | public function setUsername($username) 48 | { 49 | $this->username = $username; 50 | } 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | public function getMessageData() 56 | { 57 | return ['{{ username }}' => $this->username]; 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function __serialize(): array 64 | { 65 | return [$this->username, parent::__serialize()]; 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | public function __unserialize(array $data): void 72 | { 73 | [$this->username, $parentData] = $data; 74 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 75 | parent::__unserialize($parentData); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Core/Encoder/PlaintextPasswordEncoder.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 15 | 16 | /** 17 | * PlaintextPasswordEncoder does not do any encoding but is useful in testing environments. 18 | * 19 | * As this encoder is not cryptographically secure, usage of it in production environments is discouraged. 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | class PlaintextPasswordEncoder extends BasePasswordEncoder 24 | { 25 | private $ignorePasswordCase; 26 | 27 | /** 28 | * @param bool $ignorePasswordCase Compare password case-insensitive 29 | */ 30 | public function __construct(bool $ignorePasswordCase = false) 31 | { 32 | $this->ignorePasswordCase = $ignorePasswordCase; 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function encodePassword($raw, $salt) 39 | { 40 | if ($this->isPasswordTooLong($raw)) { 41 | throw new BadCredentialsException('Invalid password.'); 42 | } 43 | 44 | return $this->mergePasswordAndSalt($raw, $salt); 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function isPasswordValid($encoded, $raw, $salt) 51 | { 52 | if ($this->isPasswordTooLong($raw)) { 53 | return false; 54 | } 55 | 56 | $pass2 = $this->mergePasswordAndSalt($raw, $salt); 57 | 58 | if (!$this->ignorePasswordCase) { 59 | return $this->comparePasswords($encoded, $pass2); 60 | } 61 | 62 | return $this->comparePasswords(strtolower($encoded), strtolower($pass2)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Core/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/security-core", 3 | "type": "library", 4 | "description": "Symfony Security Component - Core Library", 5 | "keywords": [], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1.3", 20 | "symfony/event-dispatcher-contracts": "^1.1|^2", 21 | "symfony/polyfill-php80": "^1.16", 22 | "symfony/service-contracts": "^1.1.6|^2" 23 | }, 24 | "require-dev": { 25 | "psr/container": "^1.0|^2.0", 26 | "symfony/event-dispatcher": "^4.3", 27 | "symfony/expression-language": "^3.4|^4.0|^5.0", 28 | "symfony/http-foundation": "^3.4|^4.0|^5.0", 29 | "symfony/ldap": "^4.4|^5.0", 30 | "symfony/translation": "^4.4|^5.0", 31 | "symfony/validator": "^3.4.31|^4.3.4|^5.0", 32 | "psr/log": "^1|^2|^3" 33 | }, 34 | "conflict": { 35 | "symfony/event-dispatcher": "<4.3|>=5", 36 | "symfony/security-guard": "<4.3", 37 | "symfony/ldap": "<4.4" 38 | }, 39 | "suggest": { 40 | "psr/container-implementation": "To instantiate the Security class", 41 | "symfony/event-dispatcher": "", 42 | "symfony/http-foundation": "", 43 | "symfony/validator": "For using the user password constraint", 44 | "symfony/expression-language": "For using the expression voter", 45 | "symfony/ldap": "For using LDAP integration" 46 | }, 47 | "autoload": { 48 | "psr-4": { "Symfony\\Component\\Security\\Core\\": "" }, 49 | "exclude-from-classmap": [ 50 | "/Tests/" 51 | ] 52 | }, 53 | "minimum-stability": "dev" 54 | } 55 | -------------------------------------------------------------------------------- /Http/EntryPoint/RetryAuthenticationEntryPoint.php: -------------------------------------------------------------------------------- 1 | 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\Http\EntryPoint; 13 | 14 | use Symfony\Component\HttpFoundation\RedirectResponse; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | 18 | /** 19 | * RetryAuthenticationEntryPoint redirects URL based on the configured scheme. 20 | * 21 | * This entry point is not intended to work with HTTP post requests. 22 | * 23 | * @author Fabien Potencier 24 | */ 25 | class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface 26 | { 27 | private $httpPort; 28 | private $httpsPort; 29 | 30 | public function __construct(int $httpPort = 80, int $httpsPort = 443) 31 | { 32 | $this->httpPort = $httpPort; 33 | $this->httpsPort = $httpsPort; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function start(Request $request, AuthenticationException $authException = null) 40 | { 41 | $scheme = $request->isSecure() ? 'http' : 'https'; 42 | if ('http' === $scheme && 80 != $this->httpPort) { 43 | $port = ':'.$this->httpPort; 44 | } elseif ('https' === $scheme && 443 != $this->httpsPort) { 45 | $port = ':'.$this->httpsPort; 46 | } else { 47 | $port = ''; 48 | } 49 | 50 | $qs = $request->getQueryString(); 51 | if (null !== $qs) { 52 | $qs = '?'.$qs; 53 | } 54 | 55 | $url = $scheme.'://'.$request->getHost().$port.$request->getBaseUrl().$request->getPathInfo().$qs; 56 | 57 | return new RedirectResponse($url, 301); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Http/Event/LazyResponseEvent.php: -------------------------------------------------------------------------------- 1 | 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\Http\Event; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\Response; 16 | use Symfony\Component\HttpKernel\Event\RequestEvent; 17 | use Symfony\Component\HttpKernel\HttpKernelInterface; 18 | use Symfony\Component\Security\Core\Exception\LazyResponseException; 19 | 20 | /** 21 | * Wraps a lazily computed response in a signaling exception. 22 | * 23 | * @author Nicolas Grekas 24 | */ 25 | final class LazyResponseEvent extends RequestEvent 26 | { 27 | private $event; 28 | 29 | public function __construct(parent $event) 30 | { 31 | $this->event = $event; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function setResponse(Response $response) 38 | { 39 | $this->stopPropagation(); 40 | $this->event->stopPropagation(); 41 | 42 | throw new LazyResponseException($response); 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | public function getKernel(): HttpKernelInterface 49 | { 50 | return $this->event->getKernel(); 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | public function getRequest(): Request 57 | { 58 | return $this->event->getRequest(); 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | */ 64 | public function getRequestType(): int 65 | { 66 | return $this->event->getRequestType(); 67 | } 68 | 69 | /** 70 | * {@inheritdoc} 71 | */ 72 | public function isMasterRequest(): bool 73 | { 74 | return $this->event->isMasterRequest(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Http/Controller/UserValueResolver.php: -------------------------------------------------------------------------------- 1 | 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\Http\Controller; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; 16 | use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; 17 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 18 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 19 | use Symfony\Component\Security\Core\User\UserInterface; 20 | 21 | /** 22 | * Supports the argument type of {@see UserInterface}. 23 | * 24 | * @author Iltar van der Berg 25 | */ 26 | final class UserValueResolver implements ArgumentValueResolverInterface 27 | { 28 | private $tokenStorage; 29 | 30 | public function __construct(TokenStorageInterface $tokenStorage) 31 | { 32 | $this->tokenStorage = $tokenStorage; 33 | } 34 | 35 | public function supports(Request $request, ArgumentMetadata $argument): bool 36 | { 37 | // only security user implementations are supported 38 | if (UserInterface::class !== $argument->getType()) { 39 | return false; 40 | } 41 | 42 | $token = $this->tokenStorage->getToken(); 43 | if (!$token instanceof TokenInterface) { 44 | return false; 45 | } 46 | 47 | $user = $token->getUser(); 48 | 49 | // in case it's not an object we cannot do anything with it; E.g. "anon." 50 | return $user instanceof UserInterface; 51 | } 52 | 53 | public function resolve(Request $request, ArgumentMetadata $argument): iterable 54 | { 55 | yield $this->tokenStorage->getToken()->getUser(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Core/Authentication/RememberMe/InMemoryTokenProvider.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\RememberMe; 13 | 14 | use Symfony\Component\Security\Core\Exception\TokenNotFoundException; 15 | 16 | /** 17 | * This class is used for testing purposes, and is not really suited for production. 18 | * 19 | * @author Johannes M. Schmitt 20 | */ 21 | class InMemoryTokenProvider implements TokenProviderInterface 22 | { 23 | private $tokens = []; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function loadTokenBySeries($series) 29 | { 30 | if (!isset($this->tokens[$series])) { 31 | throw new TokenNotFoundException('No token found.'); 32 | } 33 | 34 | return $this->tokens[$series]; 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function updateToken($series, $tokenValue, \DateTime $lastUsed) 41 | { 42 | if (!isset($this->tokens[$series])) { 43 | throw new TokenNotFoundException('No token found.'); 44 | } 45 | 46 | $token = new PersistentToken( 47 | $this->tokens[$series]->getClass(), 48 | $this->tokens[$series]->getUsername(), 49 | $series, 50 | $tokenValue, 51 | $lastUsed 52 | ); 53 | $this->tokens[$series] = $token; 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function deleteTokenBySeries($series) 60 | { 61 | unset($this->tokens[$series]); 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | */ 67 | public function createNewToken(PersistentTokenInterface $token) 68 | { 69 | $this->tokens[$token->getSeries()] = $token; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Core/Role/SwitchUserRole.php: -------------------------------------------------------------------------------- 1 | 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\Role; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * SwitchUserRole is used when the current user temporarily impersonates 18 | * another one. 19 | * 20 | * @author Fabien Potencier 21 | * 22 | * @deprecated since version 4.3, to be removed in 5.0. Use strings as roles instead. 23 | */ 24 | class SwitchUserRole extends Role 25 | { 26 | private $deprecationTriggered = false; 27 | private $source; 28 | 29 | /** 30 | * @param string $role The role as a string 31 | */ 32 | public function __construct(string $role, TokenInterface $source) 33 | { 34 | if ($triggerDeprecation = \func_num_args() < 3 || func_get_arg(2)) { 35 | @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), \E_USER_DEPRECATED); 36 | 37 | $this->deprecationTriggered = true; 38 | } 39 | 40 | parent::__construct($role, $triggerDeprecation); 41 | 42 | $this->source = $source; 43 | } 44 | 45 | /** 46 | * Returns the original Token. 47 | * 48 | * @return TokenInterface The original TokenInterface instance 49 | */ 50 | public function getSource() 51 | { 52 | if (!$this->deprecationTriggered && (\func_num_args() < 1 || func_get_arg(0))) { 53 | @trigger_error(sprintf('The "%s" class is deprecated since version 4.3 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), \E_USER_DEPRECATED); 54 | 55 | $this->deprecationTriggered = true; 56 | } 57 | 58 | return $this->source; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Core/Authentication/Token/SwitchUserToken.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Token; 13 | 14 | /** 15 | * Token representing a user who temporarily impersonates another one. 16 | * 17 | * @author Christian Flothmann 18 | */ 19 | class SwitchUserToken extends UsernamePasswordToken 20 | { 21 | private $originalToken; 22 | 23 | /** 24 | * @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method 25 | * @param mixed $credentials This usually is the password of the user 26 | * @param string $providerKey The provider key 27 | * @param string[] $roles An array of roles 28 | * 29 | * @throws \InvalidArgumentException 30 | */ 31 | public function __construct($user, $credentials, string $providerKey, array $roles, TokenInterface $originalToken) 32 | { 33 | parent::__construct($user, $credentials, $providerKey, $roles); 34 | 35 | $this->originalToken = $originalToken; 36 | } 37 | 38 | public function getOriginalToken(): TokenInterface 39 | { 40 | return $this->originalToken; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function __serialize(): array 47 | { 48 | return [$this->originalToken, parent::__serialize()]; 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function __unserialize(array $data): void 55 | { 56 | [$this->originalToken, $parentData] = $data; 57 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 58 | parent::__unserialize($parentData); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Core/Authentication/Token/AnonymousToken.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Token; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | 16 | /** 17 | * AnonymousToken represents an anonymous token. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class AnonymousToken extends AbstractToken 22 | { 23 | private $secret; 24 | 25 | /** 26 | * @param string $secret A secret used to make sure the token is created by the app and not by a malicious client 27 | * @param string|\Stringable|UserInterface $user 28 | * @param string[] $roles 29 | */ 30 | public function __construct(string $secret, $user, array $roles = []) 31 | { 32 | parent::__construct($roles); 33 | 34 | $this->secret = $secret; 35 | $this->setUser($user); 36 | $this->setAuthenticated(true); 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function getCredentials() 43 | { 44 | return ''; 45 | } 46 | 47 | /** 48 | * Returns the secret. 49 | * 50 | * @return string 51 | */ 52 | public function getSecret() 53 | { 54 | return $this->secret; 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function __serialize(): array 61 | { 62 | return [$this->secret, parent::__serialize()]; 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | */ 68 | public function __unserialize(array $data): void 69 | { 70 | [$this->secret, $parentData] = $data; 71 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 72 | parent::__unserialize($parentData); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Http/Firewall/LegacyListenerTrait.php: -------------------------------------------------------------------------------- 1 | 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\Http\Firewall; 13 | 14 | use Symfony\Component\HttpFoundation\Response; 15 | use Symfony\Component\HttpKernel\Event\GetResponseEvent; 16 | use Symfony\Component\HttpKernel\Event\RequestEvent; 17 | 18 | // Help opcache.preload discover always-needed symbols 19 | class_exists(RequestEvent::class); 20 | 21 | /** 22 | * @deprecated 23 | * 24 | * @internal 25 | */ 26 | trait LegacyListenerTrait 27 | { 28 | /** 29 | * @deprecated since Symfony 4.3, use __invoke() instead 30 | */ 31 | public function handle(GetResponseEvent $event) 32 | { 33 | @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.3, use __invoke() instead.', __METHOD__), \E_USER_DEPRECATED); 34 | 35 | if (!$event instanceof RequestEvent) { 36 | $event = new class($event) extends RequestEvent { 37 | private $event; 38 | 39 | public function __construct(GetResponseEvent $event) 40 | { 41 | parent::__construct($event->getKernel(), $event->getRequest(), $event->getRequestType()); 42 | $this->event = $event; 43 | } 44 | 45 | public function getResponse() 46 | { 47 | return $this->event->getResponse(); 48 | } 49 | 50 | public function setResponse(Response $response) 51 | { 52 | $this->event->setResponse($response); 53 | } 54 | 55 | public function hasResponse() 56 | { 57 | return $this->event->hasResponse(); 58 | } 59 | }; 60 | } 61 | 62 | $this->__invoke($event); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Core/Authentication/Provider/AnonymousAuthenticationProvider.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Provider; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 18 | 19 | /** 20 | * AnonymousAuthenticationProvider validates AnonymousToken instances. 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | class AnonymousAuthenticationProvider implements AuthenticationProviderInterface 25 | { 26 | /** 27 | * Used to determine if the token is created by the application 28 | * instead of a malicious client. 29 | * 30 | * @var string 31 | */ 32 | private $secret; 33 | 34 | /** 35 | * @param string $secret The secret shared with the AnonymousToken 36 | */ 37 | public function __construct(string $secret) 38 | { 39 | $this->secret = $secret; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function authenticate(TokenInterface $token) 46 | { 47 | if (!$this->supports($token)) { 48 | throw new AuthenticationException('The token is not supported by this authentication provider.'); 49 | } 50 | 51 | if ($this->secret !== $token->getSecret()) { 52 | throw new BadCredentialsException('The Token does not contain the expected key.'); 53 | } 54 | 55 | return $token; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function supports(TokenInterface $token) 62 | { 63 | return $token instanceof AnonymousToken; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Core/User/LdapUserProvider.php: -------------------------------------------------------------------------------- 1 | 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\Ldap\Entry; 15 | use Symfony\Component\Ldap\Security\LdapUserProvider as BaseLdapUserProvider; 16 | use Symfony\Component\Security\Core\Exception\UnsupportedUserException; 17 | 18 | @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', LdapUserProvider::class, BaseLdapUserProvider::class), \E_USER_DEPRECATED); 19 | 20 | /** 21 | * LdapUserProvider is a simple user provider on top of ldap. 22 | * 23 | * @author Grégoire Pineau 24 | * @author Charles Sarrazin 25 | * 26 | * @deprecated since Symfony 4.4, use "Symfony\Component\Ldap\Security\LdapUserProvider" instead 27 | */ 28 | class LdapUserProvider extends BaseLdapUserProvider 29 | { 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function refreshUser(UserInterface $user) 34 | { 35 | if (!$user instanceof User) { 36 | throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user))); 37 | } 38 | 39 | return new User($user->getUsername(), null, $user->getRoles()); 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function supportsClass($class) 46 | { 47 | return 'Symfony\Component\Security\Core\User\User' === $class; 48 | } 49 | 50 | /** 51 | * Loads a user from an LDAP entry. 52 | * 53 | * @return User 54 | */ 55 | protected function loadUser($username, Entry $entry) 56 | { 57 | $ldapUser = parent::loadUser($username, $entry); 58 | 59 | return new User($ldapUser->getUsername(), $ldapUser->getPassword(), $ldapUser->getRoles(), true, true, true, true, $ldapUser->getExtraFields()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Guard/Token/PreAuthenticationGuardToken.php: -------------------------------------------------------------------------------- 1 | 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\Guard\Token; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; 15 | 16 | /** 17 | * The token used by the guard auth system before authentication. 18 | * 19 | * The GuardAuthenticationListener creates this, which is then consumed 20 | * immediately by the GuardAuthenticationProvider. If authentication is 21 | * successful, a different authenticated token is returned 22 | * 23 | * @author Ryan Weaver 24 | */ 25 | class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface 26 | { 27 | private $credentials; 28 | private $guardProviderKey; 29 | 30 | /** 31 | * @param mixed $credentials 32 | * @param string $guardProviderKey Unique key that bind this token to a specific AuthenticatorInterface 33 | */ 34 | public function __construct($credentials, string $guardProviderKey) 35 | { 36 | $this->credentials = $credentials; 37 | $this->guardProviderKey = $guardProviderKey; 38 | 39 | parent::__construct([]); 40 | 41 | // never authenticated 42 | parent::setAuthenticated(false); 43 | } 44 | 45 | public function getGuardProviderKey() 46 | { 47 | return $this->guardProviderKey; 48 | } 49 | 50 | /** 51 | * Returns the user credentials, which might be an array of anything you 52 | * wanted to put in there (e.g. username, password, favoriteColor). 53 | * 54 | * @return mixed The user credentials 55 | */ 56 | public function getCredentials() 57 | { 58 | return $this->credentials; 59 | } 60 | 61 | public function setAuthenticated($authenticated) 62 | { 63 | throw new \LogicException('The PreAuthenticationGuardToken is *never* authenticated.'); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Guard/Authenticator/AbstractFormLoginAuthenticator.php: -------------------------------------------------------------------------------- 1 | 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\Guard\Authenticator; 13 | 14 | use Symfony\Component\HttpFoundation\RedirectResponse; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 18 | use Symfony\Component\Security\Core\Security; 19 | use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; 20 | 21 | /** 22 | * A base class to make form login authentication easier! 23 | * 24 | * @author Ryan Weaver 25 | */ 26 | abstract class AbstractFormLoginAuthenticator extends AbstractGuardAuthenticator 27 | { 28 | /** 29 | * Return the URL to the login page. 30 | * 31 | * @return string 32 | */ 33 | abstract protected function getLoginUrl(); 34 | 35 | /** 36 | * Override to change what happens after a bad username/password is submitted. 37 | * 38 | * @return Response 39 | */ 40 | public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 41 | { 42 | if ($request->hasSession()) { 43 | $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); 44 | } 45 | 46 | $url = $this->getLoginUrl(); 47 | 48 | return new RedirectResponse($url); 49 | } 50 | 51 | public function supportsRememberMe() 52 | { 53 | return true; 54 | } 55 | 56 | /** 57 | * Override to control what happens when the user hits a secure page 58 | * but isn't logged in yet. 59 | * 60 | * @return Response 61 | */ 62 | public function start(Request $request, AuthenticationException $authException = null) 63 | { 64 | $url = $this->getLoginUrl(); 65 | 66 | return new RedirectResponse($url); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Core/Encoder/MigratingPasswordEncoder.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | /** 15 | * Hashes passwords using the best available encoder. 16 | * Validates them using a chain of encoders. 17 | * 18 | * /!\ Don't put a PlaintextPasswordEncoder in the list as that'd mean a leaked hash 19 | * could be used to authenticate successfully without knowing the cleartext password. 20 | * 21 | * @author Nicolas Grekas 22 | */ 23 | final class MigratingPasswordEncoder extends BasePasswordEncoder implements SelfSaltingEncoderInterface 24 | { 25 | private $bestEncoder; 26 | private $extraEncoders; 27 | 28 | public function __construct(PasswordEncoderInterface $bestEncoder, PasswordEncoderInterface ...$extraEncoders) 29 | { 30 | $this->bestEncoder = $bestEncoder; 31 | $this->extraEncoders = $extraEncoders; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function encodePassword($raw, $salt): string 38 | { 39 | return $this->bestEncoder->encodePassword($raw, $salt); 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function isPasswordValid($encoded, $raw, $salt): bool 46 | { 47 | if ($this->bestEncoder->isPasswordValid($encoded, $raw, $salt)) { 48 | return true; 49 | } 50 | 51 | if (!$this->bestEncoder->needsRehash($encoded)) { 52 | return false; 53 | } 54 | 55 | foreach ($this->extraEncoders as $encoder) { 56 | if ($encoder->isPasswordValid($encoded, $raw, $salt)) { 57 | return true; 58 | } 59 | } 60 | 61 | return false; 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | */ 67 | public function needsRehash(string $encoded): bool 68 | { 69 | return $this->bestEncoder->needsRehash($encoded); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Http/EntryPoint/FormAuthenticationEntryPoint.php: -------------------------------------------------------------------------------- 1 | 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\Http\EntryPoint; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpKernel\HttpKernelInterface; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | use Symfony\Component\Security\Http\HttpUtils; 18 | 19 | /** 20 | * FormAuthenticationEntryPoint starts an authentication via a login form. 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface 25 | { 26 | private $loginPath; 27 | private $useForward; 28 | private $httpKernel; 29 | private $httpUtils; 30 | 31 | /** 32 | * @param string $loginPath The path to the login form 33 | * @param bool $useForward Whether to forward or redirect to the login form 34 | */ 35 | public function __construct(HttpKernelInterface $kernel, HttpUtils $httpUtils, string $loginPath, bool $useForward = false) 36 | { 37 | $this->httpKernel = $kernel; 38 | $this->httpUtils = $httpUtils; 39 | $this->loginPath = $loginPath; 40 | $this->useForward = $useForward; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function start(Request $request, AuthenticationException $authException = null) 47 | { 48 | if ($this->useForward) { 49 | $subRequest = $this->httpUtils->createRequest($request, $this->loginPath); 50 | 51 | $response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST); 52 | if (200 === $response->getStatusCode()) { 53 | $response->setStatusCode(401); 54 | } 55 | 56 | return $response; 57 | } 58 | 59 | return $this->httpUtils->createRedirectResponse($request, $this->loginPath); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Csrf/CsrfTokenManagerInterface.php: -------------------------------------------------------------------------------- 1 | 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\Csrf; 13 | 14 | /** 15 | * Manages CSRF tokens. 16 | * 17 | * @author Bernhard Schussek 18 | */ 19 | interface CsrfTokenManagerInterface 20 | { 21 | /** 22 | * Returns a CSRF token for the given ID. 23 | * 24 | * If previously no token existed for the given ID, a new token is 25 | * generated. Otherwise the existing token is returned (with the same value, 26 | * not the same instance). 27 | * 28 | * @param string $tokenId The token ID. You may choose an arbitrary value 29 | * for the ID 30 | * 31 | * @return CsrfToken The CSRF token 32 | */ 33 | public function getToken($tokenId); 34 | 35 | /** 36 | * Generates a new token value for the given ID. 37 | * 38 | * This method will generate a new token for the given token ID, independent 39 | * of whether a token value previously existed or not. It can be used to 40 | * enforce once-only tokens in environments with high security needs. 41 | * 42 | * @param string $tokenId The token ID. You may choose an arbitrary value 43 | * for the ID 44 | * 45 | * @return CsrfToken The CSRF token 46 | */ 47 | public function refreshToken($tokenId); 48 | 49 | /** 50 | * Invalidates the CSRF token with the given ID, if one exists. 51 | * 52 | * @param string $tokenId The token ID 53 | * 54 | * @return string|null Returns the removed token value if one existed, NULL 55 | * otherwise 56 | */ 57 | public function removeToken($tokenId); 58 | 59 | /** 60 | * Returns whether the given CSRF token is valid. 61 | * 62 | * @return bool Returns true if the token is valid, false otherwise 63 | */ 64 | public function isTokenValid(CsrfToken $token); 65 | } 66 | -------------------------------------------------------------------------------- /Core/Authorization/Voter/RoleVoter.php: -------------------------------------------------------------------------------- 1 | 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\Authorization\Voter; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Component\Security\Core\Role\Role; 16 | 17 | /** 18 | * RoleVoter votes if any attribute starts with a given prefix. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class RoleVoter implements VoterInterface 23 | { 24 | private $prefix; 25 | 26 | public function __construct(string $prefix = 'ROLE_') 27 | { 28 | $this->prefix = $prefix; 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function vote(TokenInterface $token, $subject, array $attributes) 35 | { 36 | $result = VoterInterface::ACCESS_ABSTAIN; 37 | $roles = $this->extractRoles($token); 38 | 39 | foreach ($attributes as $attribute) { 40 | if ($attribute instanceof Role) { 41 | $attribute = $attribute->getRole(); 42 | } 43 | 44 | if (!\is_string($attribute) || !str_starts_with($attribute, $this->prefix)) { 45 | continue; 46 | } 47 | 48 | $result = VoterInterface::ACCESS_DENIED; 49 | foreach ($roles as $role) { 50 | if ($attribute === $role) { 51 | return VoterInterface::ACCESS_GRANTED; 52 | } 53 | } 54 | } 55 | 56 | return $result; 57 | } 58 | 59 | protected function extractRoles(TokenInterface $token) 60 | { 61 | if (method_exists($token, 'getRoleNames')) { 62 | return $token->getRoleNames(); 63 | } 64 | 65 | @trigger_error(sprintf('Not implementing the "%s::getRoleNames()" method in "%s" is deprecated since Symfony 4.3.', TokenInterface::class, \get_class($token)), \E_USER_DEPRECATED); 66 | 67 | return array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Core/Authentication/Token/Storage/TokenStorage.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Token\Storage; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Contracts\Service\ResetInterface; 16 | 17 | /** 18 | * TokenStorage contains a TokenInterface. 19 | * 20 | * It gives access to the token representing the current user authentication. 21 | * 22 | * @author Fabien Potencier 23 | * @author Johannes M. Schmitt 24 | */ 25 | class TokenStorage implements TokenStorageInterface, ResetInterface 26 | { 27 | private $token; 28 | private $initializer; 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function getToken() 34 | { 35 | if ($initializer = $this->initializer) { 36 | $this->initializer = null; 37 | $initializer(); 38 | } 39 | 40 | return $this->token; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function setToken(TokenInterface $token = null) 47 | { 48 | if (null !== $token && !method_exists($token, 'getRoleNames') && !$token instanceof \PHPUnit\Framework\MockObject\MockObject && !$token instanceof \Prophecy\Prophecy\ProphecySubjectInterface && !$token instanceof \Mockery\MockInterface) { 49 | @trigger_error(sprintf('Not implementing the "%s::getRoleNames()" method in "%s" is deprecated since Symfony 4.3.', TokenInterface::class, \get_class($token)), \E_USER_DEPRECATED); 50 | } 51 | 52 | if ($token) { 53 | // ensure any initializer is called 54 | $this->getToken(); 55 | } 56 | 57 | $this->initializer = null; 58 | $this->token = $token; 59 | } 60 | 61 | public function setInitializer(?callable $initializer): void 62 | { 63 | $this->initializer = $initializer; 64 | } 65 | 66 | public function reset() 67 | { 68 | $this->setToken(null); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Core/Authorization/Voter/RoleHierarchyVoter.php: -------------------------------------------------------------------------------- 1 | 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\Authorization\Voter; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | use Symfony\Component\Security\Core\Role\Role; 16 | use Symfony\Component\Security\Core\Role\RoleHierarchy; 17 | use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; 18 | 19 | /** 20 | * RoleHierarchyVoter uses a RoleHierarchy to determine the roles granted to 21 | * the user before voting. 22 | * 23 | * @author Fabien Potencier 24 | */ 25 | class RoleHierarchyVoter extends RoleVoter 26 | { 27 | private $roleHierarchy; 28 | 29 | public function __construct(RoleHierarchyInterface $roleHierarchy, string $prefix = 'ROLE_') 30 | { 31 | if (!method_exists($roleHierarchy, 'getReachableRoleNames')) { 32 | @trigger_error(sprintf('Not implementing the "%s::getReachableRoleNames()" method in "%s" is deprecated since Symfony 4.3.', RoleHierarchyInterface::class, \get_class($roleHierarchy)), \E_USER_DEPRECATED); 33 | } 34 | 35 | $this->roleHierarchy = $roleHierarchy; 36 | 37 | parent::__construct($prefix); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | protected function extractRoles(TokenInterface $token) 44 | { 45 | if (method_exists($this->roleHierarchy, 'getReachableRoleNames')) { 46 | if (method_exists($token, 'getRoleNames')) { 47 | $roles = $token->getRoleNames(); 48 | } else { 49 | @trigger_error(sprintf('Not implementing the "%s::getRoleNames()" method in "%s" is deprecated since Symfony 4.3.', TokenInterface::class, \get_class($token)), \E_USER_DEPRECATED); 50 | 51 | $roles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false)); 52 | } 53 | 54 | return $this->roleHierarchy->getReachableRoleNames($roles); 55 | } 56 | 57 | return $this->roleHierarchy->getReachableRoles($token->getRoles(false)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Http/Session/SessionAuthenticationStrategy.php: -------------------------------------------------------------------------------- 1 | 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\Http\Session; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface; 17 | 18 | /** 19 | * The default session strategy implementation. 20 | * 21 | * Supports the following strategies: 22 | * NONE: the session is not changed 23 | * MIGRATE: the session id is updated, attributes are kept 24 | * INVALIDATE: the session id is updated, attributes are lost 25 | * 26 | * @author Johannes M. Schmitt 27 | */ 28 | class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInterface 29 | { 30 | public const NONE = 'none'; 31 | public const MIGRATE = 'migrate'; 32 | public const INVALIDATE = 'invalidate'; 33 | 34 | private $strategy; 35 | private $csrfTokenStorage = null; 36 | 37 | public function __construct(string $strategy, ClearableTokenStorageInterface $csrfTokenStorage = null) 38 | { 39 | $this->strategy = $strategy; 40 | 41 | if (self::MIGRATE === $strategy) { 42 | $this->csrfTokenStorage = $csrfTokenStorage; 43 | } 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function onAuthentication(Request $request, TokenInterface $token) 50 | { 51 | switch ($this->strategy) { 52 | case self::NONE: 53 | return; 54 | 55 | case self::MIGRATE: 56 | $request->getSession()->migrate(true); 57 | 58 | if ($this->csrfTokenStorage) { 59 | $this->csrfTokenStorage->clear(); 60 | } 61 | 62 | return; 63 | 64 | case self::INVALIDATE: 65 | $request->getSession()->invalidate(); 66 | 67 | return; 68 | 69 | default: 70 | throw new \RuntimeException(sprintf('Invalid session authentication strategy "%s".', $this->strategy)); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Core/Authentication/RememberMe/PersistentToken.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\RememberMe; 13 | 14 | /** 15 | * @author Johannes M. Schmitt 16 | * 17 | * @internal 18 | */ 19 | final class PersistentToken implements PersistentTokenInterface 20 | { 21 | private $class; 22 | private $username; 23 | private $series; 24 | private $tokenValue; 25 | private $lastUsed; 26 | 27 | public function __construct(string $class, string $username, string $series, string $tokenValue, \DateTime $lastUsed) 28 | { 29 | if (empty($class)) { 30 | throw new \InvalidArgumentException('$class must not be empty.'); 31 | } 32 | if ('' === $username) { 33 | throw new \InvalidArgumentException('$username must not be empty.'); 34 | } 35 | if (empty($series)) { 36 | throw new \InvalidArgumentException('$series must not be empty.'); 37 | } 38 | if (empty($tokenValue)) { 39 | throw new \InvalidArgumentException('$tokenValue must not be empty.'); 40 | } 41 | 42 | $this->class = $class; 43 | $this->username = $username; 44 | $this->series = $series; 45 | $this->tokenValue = $tokenValue; 46 | $this->lastUsed = $lastUsed; 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public function getClass(): string 53 | { 54 | return $this->class; 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function getUsername(): string 61 | { 62 | return $this->username; 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | */ 68 | public function getSeries(): string 69 | { 70 | return $this->series; 71 | } 72 | 73 | /** 74 | * {@inheritdoc} 75 | */ 76 | public function getTokenValue(): string 77 | { 78 | return $this->tokenValue; 79 | } 80 | 81 | /** 82 | * {@inheritdoc} 83 | */ 84 | public function getLastUsed(): \DateTime 85 | { 86 | return $this->lastUsed; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Core/Validator/Constraints/UserPasswordValidator.php: -------------------------------------------------------------------------------- 1 | 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\Validator\Constraints; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 15 | use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; 16 | use Symfony\Component\Security\Core\User\UserInterface; 17 | use Symfony\Component\Validator\Constraint; 18 | use Symfony\Component\Validator\ConstraintValidator; 19 | use Symfony\Component\Validator\Exception\ConstraintDefinitionException; 20 | use Symfony\Component\Validator\Exception\UnexpectedTypeException; 21 | 22 | class UserPasswordValidator extends ConstraintValidator 23 | { 24 | private $tokenStorage; 25 | private $encoderFactory; 26 | 27 | public function __construct(TokenStorageInterface $tokenStorage, EncoderFactoryInterface $encoderFactory) 28 | { 29 | $this->tokenStorage = $tokenStorage; 30 | $this->encoderFactory = $encoderFactory; 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function validate($password, Constraint $constraint) 37 | { 38 | if (!$constraint instanceof UserPassword) { 39 | throw new UnexpectedTypeException($constraint, UserPassword::class); 40 | } 41 | 42 | if (null === $password || '' === $password) { 43 | $this->context->addViolation($constraint->message); 44 | 45 | return; 46 | } 47 | 48 | if (!\is_string($password)) { 49 | throw new UnexpectedTypeException($password, 'string'); 50 | } 51 | 52 | $user = $this->tokenStorage->getToken()->getUser(); 53 | 54 | if (!$user instanceof UserInterface) { 55 | throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.'); 56 | } 57 | 58 | $encoder = $this->encoderFactory->getEncoder($user); 59 | 60 | if (null === $user->getPassword() || !$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) { 61 | $this->context->addViolation($constraint->message); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Core/Exception/CustomUserMessageAuthenticationException.php: -------------------------------------------------------------------------------- 1 | 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\Exception; 13 | 14 | /** 15 | * An authentication exception where you can control the message shown to the user. 16 | * 17 | * Be sure that the message passed to this exception is something that 18 | * can be shown safely to your user. In other words, avoid catching 19 | * other exceptions and passing their message directly to this class. 20 | * 21 | * @author Ryan Weaver 22 | */ 23 | class CustomUserMessageAuthenticationException extends AuthenticationException 24 | { 25 | private $messageKey; 26 | 27 | private $messageData = []; 28 | 29 | public function __construct(string $message = '', array $messageData = [], int $code = 0, \Throwable $previous = null) 30 | { 31 | parent::__construct($message, $code, $previous); 32 | 33 | $this->setSafeMessage($message, $messageData); 34 | } 35 | 36 | /** 37 | * Set a message that will be shown to the user. 38 | * 39 | * @param string $messageKey The message or message key 40 | * @param array $messageData Data to be passed into the translator 41 | */ 42 | public function setSafeMessage($messageKey, array $messageData = []) 43 | { 44 | $this->messageKey = $messageKey; 45 | $this->messageData = $messageData; 46 | } 47 | 48 | public function getMessageKey() 49 | { 50 | return $this->messageKey; 51 | } 52 | 53 | public function getMessageData() 54 | { 55 | return $this->messageData; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function __serialize(): array 62 | { 63 | return [parent::__serialize(), $this->messageKey, $this->messageData]; 64 | } 65 | 66 | /** 67 | * {@inheritdoc} 68 | */ 69 | public function __unserialize(array $data): void 70 | { 71 | [$parentData, $this->messageKey, $this->messageData] = $data; 72 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 73 | parent::__unserialize($parentData); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Http/Firewall/X509AuthenticationListener.php: -------------------------------------------------------------------------------- 1 | 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\Http\Firewall; 13 | 14 | use Psr\Log\LoggerInterface; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; 17 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 18 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 19 | use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; 20 | 21 | /** 22 | * X509 authentication listener. 23 | * 24 | * @author Fabien Potencier 25 | */ 26 | class X509AuthenticationListener extends AbstractPreAuthenticatedListener 27 | { 28 | private $userKey; 29 | private $credentialKey; 30 | 31 | public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, string $providerKey, string $userKey = 'SSL_CLIENT_S_DN_Email', string $credentialKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) 32 | { 33 | parent::__construct($tokenStorage, $authenticationManager, $providerKey, $logger, $dispatcher); 34 | 35 | $this->userKey = $userKey; 36 | $this->credentialKey = $credentialKey; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | protected function getPreAuthenticatedData(Request $request) 43 | { 44 | $user = null; 45 | if ($request->server->has($this->userKey)) { 46 | $user = $request->server->get($this->userKey); 47 | } elseif ( 48 | $request->server->has($this->credentialKey) 49 | && preg_match('#emailAddress=([^,/@]++@[^,/]++)#', $request->server->get($this->credentialKey), $matches) 50 | ) { 51 | $user = $matches[1]; 52 | } 53 | 54 | if (null === $user) { 55 | throw new BadCredentialsException(sprintf('SSL credentials not found: "%s", "%s".', $this->userKey, $this->credentialKey)); 56 | } 57 | 58 | return [$user, $request->server->get($this->credentialKey, '')]; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Core/Security.php: -------------------------------------------------------------------------------- 1 | 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; 13 | 14 | use Psr\Container\ContainerInterface; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Core\User\UserInterface; 17 | 18 | /** 19 | * Helper class for commonly-needed security tasks. 20 | * 21 | * @final 22 | */ 23 | class Security 24 | { 25 | public const ACCESS_DENIED_ERROR = '_security.403_error'; 26 | public const AUTHENTICATION_ERROR = '_security.last_error'; 27 | public const LAST_USERNAME = '_security.last_username'; 28 | public const MAX_USERNAME_LENGTH = 4096; 29 | 30 | private $container; 31 | 32 | public function __construct(ContainerInterface $container) 33 | { 34 | $this->container = $container; 35 | } 36 | 37 | /** 38 | * @return UserInterface|null 39 | */ 40 | public function getUser() 41 | { 42 | if (!$token = $this->getToken()) { 43 | return null; 44 | } 45 | 46 | $user = $token->getUser(); 47 | if (!\is_object($user)) { 48 | return null; 49 | } 50 | 51 | if (!$user instanceof UserInterface) { 52 | @trigger_error(sprintf('Accessing the user object "%s" that is not an instance of "%s" from "%s()" is deprecated since Symfony 4.2, use "getToken()->getUser()" instead.', \get_class($user), UserInterface::class, __METHOD__), \E_USER_DEPRECATED); 53 | // return null; // 5.0 behavior 54 | } 55 | 56 | return $user; 57 | } 58 | 59 | /** 60 | * Checks if the attributes are granted against the current authentication token and optionally supplied subject. 61 | * 62 | * @param mixed $attributes 63 | * @param mixed $subject 64 | */ 65 | public function isGranted($attributes, $subject = null): bool 66 | { 67 | return $this->container->get('security.authorization_checker') 68 | ->isGranted($attributes, $subject); 69 | } 70 | 71 | public function getToken(): ?TokenInterface 72 | { 73 | return $this->container->get('security.token_storage')->getToken(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Core/Authentication/Token/Storage/UsageTrackingTokenStorage.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Token\Storage; 13 | 14 | use Psr\Container\ContainerInterface; 15 | use Symfony\Component\HttpFoundation\Session\SessionInterface; 16 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 17 | use Symfony\Contracts\Service\ServiceSubscriberInterface; 18 | 19 | /** 20 | * A token storage that increments the session usage index when the token is accessed. 21 | * 22 | * @author Nicolas Grekas 23 | */ 24 | final class UsageTrackingTokenStorage implements TokenStorageInterface, ServiceSubscriberInterface 25 | { 26 | private $storage; 27 | private $sessionLocator; 28 | private $enableUsageTracking = false; 29 | 30 | public function __construct(TokenStorageInterface $storage, ContainerInterface $sessionLocator) 31 | { 32 | $this->storage = $storage; 33 | $this->sessionLocator = $sessionLocator; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function getToken(): ?TokenInterface 40 | { 41 | if ($this->enableUsageTracking) { 42 | // increments the internal session usage index 43 | $this->sessionLocator->get('session')->getMetadataBag(); 44 | } 45 | 46 | return $this->storage->getToken(); 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public function setToken(TokenInterface $token = null): void 53 | { 54 | $this->storage->setToken($token); 55 | 56 | if ($token && $this->enableUsageTracking) { 57 | // increments the internal session usage index 58 | $this->sessionLocator->get('session')->getMetadataBag(); 59 | } 60 | } 61 | 62 | public function enableUsageTracking(): void 63 | { 64 | $this->enableUsageTracking = true; 65 | } 66 | 67 | public function disableUsageTracking(): void 68 | { 69 | $this->enableUsageTracking = false; 70 | } 71 | 72 | public static function getSubscribedServices(): array 73 | { 74 | return [ 75 | 'session' => SessionInterface::class, 76 | ]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Core/Authorization/Voter/Voter.php: -------------------------------------------------------------------------------- 1 | 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\Authorization\Voter; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 15 | 16 | /** 17 | * Voter is an abstract default implementation of a voter. 18 | * 19 | * @author Roman Marintšenko 20 | * @author Grégoire Pineau 21 | */ 22 | abstract class Voter implements VoterInterface 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function vote(TokenInterface $token, $subject, array $attributes) 28 | { 29 | // abstain vote by default in case none of the attributes are supported 30 | $vote = self::ACCESS_ABSTAIN; 31 | 32 | foreach ($attributes as $attribute) { 33 | if (!$this->supports($attribute, $subject)) { 34 | continue; 35 | } 36 | 37 | // as soon as at least one attribute is supported, default is to deny access 38 | $vote = self::ACCESS_DENIED; 39 | 40 | if ($this->voteOnAttribute($attribute, $subject, $token)) { 41 | // grant access as soon as at least one attribute returns a positive response 42 | return self::ACCESS_GRANTED; 43 | } 44 | } 45 | 46 | return $vote; 47 | } 48 | 49 | /** 50 | * Determines if the attribute and subject are supported by this voter. 51 | * 52 | * @param string $attribute An attribute 53 | * @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type 54 | * 55 | * @return bool True if the attribute and subject are supported, false otherwise 56 | */ 57 | abstract protected function supports($attribute, $subject); 58 | 59 | /** 60 | * Perform a single access check operation on a given attribute, subject and token. 61 | * It is safe to assume that $attribute and $subject already passed the "supports()" method check. 62 | * 63 | * @param string $attribute 64 | * @param mixed $subject 65 | * 66 | * @return bool 67 | */ 68 | abstract protected function voteOnAttribute($attribute, $subject, TokenInterface $token); 69 | } 70 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/security", 3 | "type": "library", 4 | "description": "Provides a complete security system for your web application", 5 | "keywords": [], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1.3", 20 | "symfony/event-dispatcher-contracts": "^1.1|^2", 21 | "symfony/http-foundation": "^3.4.40|^4.4.7|^5.0.7", 22 | "symfony/http-kernel": "^4.4", 23 | "symfony/polyfill-php80": "^1.16", 24 | "symfony/property-access": "^3.4|^4.0|^5.0", 25 | "symfony/service-contracts": "^1.1|^2" 26 | }, 27 | "replace": { 28 | "symfony/security-core": "self.version", 29 | "symfony/security-csrf": "self.version", 30 | "symfony/security-guard": "self.version", 31 | "symfony/security-http": "self.version" 32 | }, 33 | "require-dev": { 34 | "psr/container": "^1.0|^2.0", 35 | "symfony/finder": "^3.4|^4.0|^5.0", 36 | "symfony/polyfill-ctype": "~1.8", 37 | "symfony/polyfill-intl-icu": "~1.0", 38 | "symfony/routing": "^3.4|^4.0|^5.0", 39 | "symfony/validator": "^3.4.31|^4.3.4|^5.0", 40 | "symfony/expression-language": "^3.4|^4.0|^5.0", 41 | "symfony/ldap": "^4.4|^5.0", 42 | "symfony/translation": "^4.4|^5.0", 43 | "psr/log": "^1|^2|^3" 44 | }, 45 | "conflict": { 46 | "symfony/event-dispatcher": ">=5", 47 | "symfony/ldap": "<4.4" 48 | }, 49 | "suggest": { 50 | "psr/container-implementation": "To instantiate the Security class", 51 | "symfony/form": "", 52 | "symfony/validator": "For using the user password constraint", 53 | "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs", 54 | "symfony/expression-language": "For using the expression voter", 55 | "symfony/ldap": "For using the LDAP user and authentication providers" 56 | }, 57 | "autoload": { 58 | "psr-4": { "Symfony\\Component\\Security\\": "" }, 59 | "exclude-from-classmap": [ 60 | "/Core/Tests/", 61 | "/Csrf/Tests/", 62 | "/Guard/Tests/", 63 | "/Http/Tests/" 64 | ] 65 | }, 66 | "minimum-stability": "dev" 67 | } 68 | -------------------------------------------------------------------------------- /Core/Authentication/Token/PreAuthenticatedToken.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Token; 13 | 14 | use Symfony\Component\Security\Core\User\UserInterface; 15 | 16 | /** 17 | * PreAuthenticatedToken implements a pre-authenticated token. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class PreAuthenticatedToken extends AbstractToken 22 | { 23 | private $credentials; 24 | private $providerKey; 25 | 26 | /** 27 | * @param string|\Stringable|UserInterface $user 28 | * @param mixed $credentials 29 | * @param string[] $roles 30 | */ 31 | public function __construct($user, $credentials, string $providerKey, array $roles = []) 32 | { 33 | parent::__construct($roles); 34 | 35 | if (empty($providerKey)) { 36 | throw new \InvalidArgumentException('$providerKey must not be empty.'); 37 | } 38 | 39 | $this->setUser($user); 40 | $this->credentials = $credentials; 41 | $this->providerKey = $providerKey; 42 | 43 | if ($roles) { 44 | $this->setAuthenticated(true); 45 | } 46 | } 47 | 48 | /** 49 | * Returns the provider key. 50 | * 51 | * @return string The provider key 52 | */ 53 | public function getProviderKey() 54 | { 55 | return $this->providerKey; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function getCredentials() 62 | { 63 | return $this->credentials; 64 | } 65 | 66 | /** 67 | * {@inheritdoc} 68 | */ 69 | public function eraseCredentials() 70 | { 71 | parent::eraseCredentials(); 72 | 73 | $this->credentials = null; 74 | } 75 | 76 | /** 77 | * {@inheritdoc} 78 | */ 79 | public function __serialize(): array 80 | { 81 | return [$this->credentials, $this->providerKey, parent::__serialize()]; 82 | } 83 | 84 | /** 85 | * {@inheritdoc} 86 | */ 87 | public function __unserialize(array $data): void 88 | { 89 | [$this->credentials, $this->providerKey, $parentData] = $data; 90 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 91 | parent::__unserialize($parentData); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Core/User/UserProviderInterface.php: -------------------------------------------------------------------------------- 1 | 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\UnsupportedUserException; 15 | use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 16 | 17 | /** 18 | * Represents a class that loads UserInterface objects from some source for the authentication system. 19 | * 20 | * In a typical authentication configuration, a username (i.e. some unique 21 | * user identifier) credential enters the system (via form login, or any 22 | * method). The user provider that is configured with that authentication 23 | * method is asked to load the UserInterface object for the given username 24 | * (via loadUserByUsername) so that the rest of the process can continue. 25 | * 26 | * Internally, a user provider can load users from any source (databases, 27 | * configuration, web service). This is totally independent of how the authentication 28 | * information is submitted or what the UserInterface object looks like. 29 | * 30 | * @see UserInterface 31 | * 32 | * @author Fabien Potencier 33 | */ 34 | interface UserProviderInterface 35 | { 36 | /** 37 | * Loads the user for the given username. 38 | * 39 | * This method must throw UsernameNotFoundException if the user is not 40 | * found. 41 | * 42 | * @param string $username The username 43 | * 44 | * @return UserInterface 45 | * 46 | * @throws UsernameNotFoundException if the user is not found 47 | */ 48 | public function loadUserByUsername($username); 49 | 50 | /** 51 | * Refreshes the user. 52 | * 53 | * It is up to the implementation to decide if the user data should be 54 | * totally reloaded (e.g. from the database), or if the UserInterface 55 | * object can just be merged into some internal array of users / identity 56 | * map. 57 | * 58 | * @return UserInterface 59 | * 60 | * @throws UnsupportedUserException if the user is not supported 61 | * @throws UsernameNotFoundException if the user is not found 62 | */ 63 | public function refreshUser(UserInterface $user); 64 | 65 | /** 66 | * Whether this provider supports the given user class. 67 | * 68 | * @param string $class 69 | * 70 | * @return bool 71 | */ 72 | public function supportsClass($class); 73 | } 74 | -------------------------------------------------------------------------------- /Http/Authentication/AuthenticationUtils.php: -------------------------------------------------------------------------------- 1 | 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\Http\Authentication; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\RequestStack; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | use Symfony\Component\Security\Core\Security; 18 | 19 | /** 20 | * Extracts Security Errors from Request. 21 | * 22 | * @author Boris Vujicic 23 | */ 24 | class AuthenticationUtils 25 | { 26 | private $requestStack; 27 | 28 | public function __construct(RequestStack $requestStack) 29 | { 30 | $this->requestStack = $requestStack; 31 | } 32 | 33 | /** 34 | * @param bool $clearSession 35 | * 36 | * @return AuthenticationException|null 37 | */ 38 | public function getLastAuthenticationError($clearSession = true) 39 | { 40 | $request = $this->getRequest(); 41 | $authenticationException = null; 42 | 43 | if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) { 44 | $authenticationException = $request->attributes->get(Security::AUTHENTICATION_ERROR); 45 | } elseif ($request->hasSession() && ($session = $request->getSession())->has(Security::AUTHENTICATION_ERROR)) { 46 | $authenticationException = $session->get(Security::AUTHENTICATION_ERROR); 47 | 48 | if ($clearSession) { 49 | $session->remove(Security::AUTHENTICATION_ERROR); 50 | } 51 | } 52 | 53 | return $authenticationException; 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getLastUsername() 60 | { 61 | $request = $this->getRequest(); 62 | 63 | if ($request->attributes->has(Security::LAST_USERNAME)) { 64 | return $request->attributes->get(Security::LAST_USERNAME, ''); 65 | } 66 | 67 | return $request->hasSession() ? $request->getSession()->get(Security::LAST_USERNAME, '') : ''; 68 | } 69 | 70 | /** 71 | * @throws \LogicException 72 | */ 73 | private function getRequest(): Request 74 | { 75 | $request = $this->requestStack->getCurrentRequest(); 76 | 77 | if (null === $request) { 78 | throw new \LogicException('Request should exist so it can be processed for error.'); 79 | } 80 | 81 | return $request; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Core/Authentication/Provider/SimpleAuthenticationProvider.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Provider; 13 | 14 | use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | use Symfony\Component\Security\Core\User\UserChecker; 18 | use Symfony\Component\Security\Core\User\UserCheckerInterface; 19 | use Symfony\Component\Security\Core\User\UserInterface; 20 | use Symfony\Component\Security\Core\User\UserProviderInterface; 21 | 22 | @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2, use Guard instead.', SimpleAuthenticationProvider::class), \E_USER_DEPRECATED); 23 | 24 | /** 25 | * @author Jordi Boggiano 26 | * 27 | * @deprecated since Symfony 4.2, use Guard instead. 28 | */ 29 | class SimpleAuthenticationProvider implements AuthenticationProviderInterface 30 | { 31 | private $simpleAuthenticator; 32 | private $userProvider; 33 | private $providerKey; 34 | private $userChecker; 35 | 36 | public function __construct(SimpleAuthenticatorInterface $simpleAuthenticator, UserProviderInterface $userProvider, string $providerKey, UserCheckerInterface $userChecker = null) 37 | { 38 | $this->simpleAuthenticator = $simpleAuthenticator; 39 | $this->userProvider = $userProvider; 40 | $this->providerKey = $providerKey; 41 | $this->userChecker = $userChecker ?? new UserChecker(); 42 | } 43 | 44 | public function authenticate(TokenInterface $token) 45 | { 46 | $authToken = $this->simpleAuthenticator->authenticateToken($token, $this->userProvider, $this->providerKey); 47 | 48 | if (!$authToken instanceof TokenInterface) { 49 | throw new AuthenticationException('Simple authenticator failed to return an authenticated token.'); 50 | } 51 | 52 | $user = $authToken->getUser(); 53 | 54 | if (!$user instanceof UserInterface) { 55 | return $authToken; 56 | } 57 | 58 | $this->userChecker->checkPreAuth($user); 59 | $this->userChecker->checkPostAuth($user); 60 | 61 | return $authToken; 62 | } 63 | 64 | public function supports(TokenInterface $token) 65 | { 66 | return $this->simpleAuthenticator->supportsToken($token, $this->providerKey); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Core/User/UserInterface.php: -------------------------------------------------------------------------------- 1 | 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\Role\Role; 15 | 16 | /** 17 | * Represents the interface that all user classes must implement. 18 | * 19 | * This interface is useful because the authentication layer can deal with 20 | * the object through its lifecycle, using the object to get the encoded 21 | * password (for checking against a submitted password), assigning roles 22 | * and so on. 23 | * 24 | * Regardless of how your users are loaded or where they come from (a database, 25 | * configuration, web service, etc.), you will have a class that implements 26 | * this interface. Objects that implement this interface are created and 27 | * loaded by different objects that implement UserProviderInterface. 28 | * 29 | * @see UserProviderInterface 30 | * 31 | * @author Fabien Potencier 32 | */ 33 | interface UserInterface 34 | { 35 | /** 36 | * Returns the roles granted to the user. 37 | * 38 | * public function getRoles() 39 | * { 40 | * return ['ROLE_USER']; 41 | * } 42 | * 43 | * Alternatively, the roles might be stored in a ``roles`` property, 44 | * and populated in any number of different ways when the user object 45 | * is created. 46 | * 47 | * @return array The user roles 48 | */ 49 | public function getRoles(); 50 | 51 | /** 52 | * Returns the password used to authenticate the user. 53 | * 54 | * This should be the encoded password. On authentication, a plain-text 55 | * password will be salted, encoded, and then compared to this value. 56 | * 57 | * @return string|null The encoded password if any 58 | */ 59 | public function getPassword(); 60 | 61 | /** 62 | * Returns the salt that was originally used to encode the password. 63 | * 64 | * This can return null if the password was not encoded using a salt. 65 | * 66 | * @return string|null The salt 67 | */ 68 | public function getSalt(); 69 | 70 | /** 71 | * Returns the username used to authenticate the user. 72 | * 73 | * @return string The username 74 | */ 75 | public function getUsername(); 76 | 77 | /** 78 | * Removes sensitive data from the user. 79 | * 80 | * This is important if, at any given point, sensitive information like 81 | * the plain-text password is stored on this object. 82 | */ 83 | public function eraseCredentials(); 84 | } 85 | -------------------------------------------------------------------------------- /Core/User/UserChecker.php: -------------------------------------------------------------------------------- 1 | 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\AccountExpiredException; 15 | use Symfony\Component\Security\Core\Exception\CredentialsExpiredException; 16 | use Symfony\Component\Security\Core\Exception\DisabledException; 17 | use Symfony\Component\Security\Core\Exception\LockedException; 18 | 19 | /** 20 | * UserChecker checks the user account flags. 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | class UserChecker implements UserCheckerInterface 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function checkPreAuth(UserInterface $user) 30 | { 31 | if (!$user instanceof AdvancedUserInterface && !$user instanceof User) { 32 | return; 33 | } 34 | 35 | if ($user instanceof AdvancedUserInterface && !$user instanceof User) { 36 | @trigger_error(sprintf('Calling "%s()" with an AdvancedUserInterface is deprecated since Symfony 4.1. Create a custom user checker if you wish to keep this functionality.', __METHOD__), \E_USER_DEPRECATED); 37 | } 38 | 39 | if (!$user->isAccountNonLocked()) { 40 | $ex = new LockedException('User account is locked.'); 41 | $ex->setUser($user); 42 | throw $ex; 43 | } 44 | 45 | if (!$user->isEnabled()) { 46 | $ex = new DisabledException('User account is disabled.'); 47 | $ex->setUser($user); 48 | throw $ex; 49 | } 50 | 51 | if (!$user->isAccountNonExpired()) { 52 | $ex = new AccountExpiredException('User account has expired.'); 53 | $ex->setUser($user); 54 | throw $ex; 55 | } 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function checkPostAuth(UserInterface $user) 62 | { 63 | if (!$user instanceof AdvancedUserInterface && !$user instanceof User) { 64 | return; 65 | } 66 | 67 | if ($user instanceof AdvancedUserInterface && !$user instanceof User) { 68 | @trigger_error(sprintf('Calling "%s()" with an AdvancedUserInterface is deprecated since Symfony 4.1. Create a custom user checker if you wish to keep this functionality.', __METHOD__), \E_USER_DEPRECATED); 69 | } 70 | 71 | if (!$user->isCredentialsNonExpired()) { 72 | $ex = new CredentialsExpiredException('User credentials have expired.'); 73 | $ex->setUser($user); 74 | throw $ex; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Guard/Token/PostAuthenticationGuardToken.php: -------------------------------------------------------------------------------- 1 | 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\Guard\Token; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; 15 | use Symfony\Component\Security\Core\User\UserInterface; 16 | 17 | /** 18 | * Used as an "authenticated" token, though it could be set to not-authenticated later. 19 | * 20 | * If you're using Guard authentication, you *must* use a class that implements 21 | * GuardTokenInterface as your authenticated token (like this class). 22 | * 23 | * @author Ryan Weaver 24 | */ 25 | class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface 26 | { 27 | private $providerKey; 28 | 29 | /** 30 | * @param string $providerKey The provider (firewall) key 31 | * @param string[] $roles An array of roles 32 | * 33 | * @throws \InvalidArgumentException 34 | */ 35 | public function __construct(UserInterface $user, string $providerKey, array $roles) 36 | { 37 | parent::__construct($roles); 38 | 39 | if (empty($providerKey)) { 40 | throw new \InvalidArgumentException('$providerKey (i.e. firewall key) must not be empty.'); 41 | } 42 | 43 | $this->setUser($user); 44 | $this->providerKey = $providerKey; 45 | 46 | // this token is meant to be used after authentication success, so it is always authenticated 47 | // you could set it as non authenticated later if you need to 48 | $this->setAuthenticated(true); 49 | } 50 | 51 | /** 52 | * This is meant to be only an authenticated token, where credentials 53 | * have already been used and are thus cleared. 54 | * 55 | * {@inheritdoc} 56 | */ 57 | public function getCredentials() 58 | { 59 | return []; 60 | } 61 | 62 | /** 63 | * Returns the provider (firewall) key. 64 | * 65 | * @return string 66 | */ 67 | public function getProviderKey() 68 | { 69 | return $this->providerKey; 70 | } 71 | 72 | /** 73 | * {@inheritdoc} 74 | */ 75 | public function __serialize(): array 76 | { 77 | return [$this->providerKey, parent::__serialize()]; 78 | } 79 | 80 | /** 81 | * {@inheritdoc} 82 | */ 83 | public function __unserialize(array $data): void 84 | { 85 | [$this->providerKey, $parentData] = $data; 86 | $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); 87 | parent::__unserialize($parentData); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Provider; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 18 | use Symfony\Component\Security\Core\User\UserCheckerInterface; 19 | use Symfony\Component\Security\Core\User\UserProviderInterface; 20 | 21 | /** 22 | * Processes a pre-authenticated authentication request. 23 | * 24 | * This authentication provider will not perform any checks on authentication 25 | * requests, as they should already be pre-authenticated. However, the 26 | * UserProviderInterface implementation may still throw a 27 | * UsernameNotFoundException, for example. 28 | * 29 | * @author Fabien Potencier 30 | */ 31 | class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderInterface 32 | { 33 | private $userProvider; 34 | private $userChecker; 35 | private $providerKey; 36 | 37 | public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey) 38 | { 39 | $this->userProvider = $userProvider; 40 | $this->userChecker = $userChecker; 41 | $this->providerKey = $providerKey; 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function authenticate(TokenInterface $token) 48 | { 49 | if (!$this->supports($token)) { 50 | throw new AuthenticationException('The token is not supported by this authentication provider.'); 51 | } 52 | 53 | if (!$user = $token->getUser()) { 54 | throw new BadCredentialsException('No pre-authenticated principal found in request.'); 55 | } 56 | 57 | $user = $this->userProvider->loadUserByUsername($user); 58 | 59 | $this->userChecker->checkPostAuth($user); 60 | 61 | $authenticatedToken = new PreAuthenticatedToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles()); 62 | $authenticatedToken->setAttributes($token->getAttributes()); 63 | 64 | return $authenticatedToken; 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | public function supports(TokenInterface $token) 71 | { 72 | return $token instanceof PreAuthenticatedToken && $this->providerKey === $token->getProviderKey(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Core/Authentication/Provider/RememberMeAuthenticationProvider.php: -------------------------------------------------------------------------------- 1 | 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\Authentication\Provider; 13 | 14 | use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; 15 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationException; 17 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 18 | use Symfony\Component\Security\Core\Exception\LogicException; 19 | use Symfony\Component\Security\Core\User\UserCheckerInterface; 20 | use Symfony\Component\Security\Core\User\UserInterface; 21 | 22 | class RememberMeAuthenticationProvider implements AuthenticationProviderInterface 23 | { 24 | private $userChecker; 25 | private $secret; 26 | private $providerKey; 27 | 28 | /** 29 | * @param string $secret A secret 30 | * @param string $providerKey A provider secret 31 | */ 32 | public function __construct(UserCheckerInterface $userChecker, string $secret, string $providerKey) 33 | { 34 | $this->userChecker = $userChecker; 35 | $this->secret = $secret; 36 | $this->providerKey = $providerKey; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function authenticate(TokenInterface $token) 43 | { 44 | if (!$this->supports($token)) { 45 | throw new AuthenticationException('The token is not supported by this authentication provider.'); 46 | } 47 | 48 | if ($this->secret !== $token->getSecret()) { 49 | throw new BadCredentialsException('The presented secret does not match.'); 50 | } 51 | 52 | $user = $token->getUser(); 53 | 54 | if (!$token->getUser() instanceof UserInterface) { 55 | throw new LogicException(sprintf('Method "%s::getUser()" must return a "%s" instance, "%s" returned.', \get_class($token), UserInterface::class, \is_object($user) ? \get_class($user) : \gettype($user))); 56 | } 57 | 58 | $this->userChecker->checkPreAuth($user); 59 | $this->userChecker->checkPostAuth($user); 60 | 61 | $authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->secret); 62 | $authenticatedToken->setAttributes($token->getAttributes()); 63 | 64 | return $authenticatedToken; 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | public function supports(TokenInterface $token) 71 | { 72 | return $token instanceof RememberMeToken && $token->getProviderKey() === $this->providerKey; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Core/Encoder/MessageDigestPasswordEncoder.php: -------------------------------------------------------------------------------- 1 | 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\Encoder; 13 | 14 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; 15 | 16 | /** 17 | * MessageDigestPasswordEncoder uses a message digest algorithm. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class MessageDigestPasswordEncoder extends BasePasswordEncoder 22 | { 23 | private $algorithm; 24 | private $encodeHashAsBase64; 25 | private $iterations = 1; 26 | private $encodedLength = -1; 27 | 28 | /** 29 | * @param string $algorithm The digest algorithm to use 30 | * @param bool $encodeHashAsBase64 Whether to base64 encode the password hash 31 | * @param int $iterations The number of iterations to use to stretch the password hash 32 | */ 33 | public function __construct(string $algorithm = 'sha512', bool $encodeHashAsBase64 = true, int $iterations = 5000) 34 | { 35 | $this->algorithm = $algorithm; 36 | $this->encodeHashAsBase64 = $encodeHashAsBase64; 37 | 38 | try { 39 | $this->encodedLength = \strlen($this->encodePassword('', 'salt')); 40 | } catch (\LogicException $e) { 41 | // ignore algorithm not supported 42 | } 43 | 44 | $this->iterations = $iterations; 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function encodePassword($raw, $salt) 51 | { 52 | if ($this->isPasswordTooLong($raw)) { 53 | throw new BadCredentialsException('Invalid password.'); 54 | } 55 | 56 | if (!\in_array($this->algorithm, hash_algos(), true)) { 57 | throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); 58 | } 59 | 60 | $salted = $this->mergePasswordAndSalt($raw, $salt); 61 | $digest = hash($this->algorithm, $salted, true); 62 | 63 | // "stretch" hash 64 | for ($i = 1; $i < $this->iterations; ++$i) { 65 | $digest = hash($this->algorithm, $digest.$salted, true); 66 | } 67 | 68 | return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest); 69 | } 70 | 71 | /** 72 | * {@inheritdoc} 73 | */ 74 | public function isPasswordValid($encoded, $raw, $salt) 75 | { 76 | if (\strlen($encoded) !== $this->encodedLength || str_contains($encoded, '$')) { 77 | return false; 78 | } 79 | 80 | return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Core/Authorization/AuthorizationChecker.php: -------------------------------------------------------------------------------- 1 | 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\Authorization; 13 | 14 | use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; 15 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 16 | use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; 17 | 18 | /** 19 | * AuthorizationChecker is the main authorization point of the Security component. 20 | * 21 | * It gives access to the token representing the current user authentication. 22 | * 23 | * @author Fabien Potencier 24 | * @author Johannes M. Schmitt 25 | */ 26 | class AuthorizationChecker implements AuthorizationCheckerInterface 27 | { 28 | private $tokenStorage; 29 | private $accessDecisionManager; 30 | private $authenticationManager; 31 | private $alwaysAuthenticate; 32 | 33 | public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager, bool $alwaysAuthenticate = false) 34 | { 35 | $this->tokenStorage = $tokenStorage; 36 | $this->authenticationManager = $authenticationManager; 37 | $this->accessDecisionManager = $accessDecisionManager; 38 | $this->alwaysAuthenticate = $alwaysAuthenticate; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | * 44 | * @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token 45 | */ 46 | final public function isGranted($attributes, $subject = null): bool 47 | { 48 | if (null === ($token = $this->tokenStorage->getToken())) { 49 | throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.'); 50 | } 51 | 52 | if ($this->alwaysAuthenticate || !$token->isAuthenticated()) { 53 | $this->tokenStorage->setToken($token = $this->authenticationManager->authenticate($token)); 54 | } 55 | 56 | if (!\is_array($attributes)) { 57 | $attributes = [$attributes]; 58 | } else { 59 | @trigger_error(sprintf('Passing an array of Security attributes to %s() is deprecated since Symfony 4.4. Use multiple isGranted() calls or the expression language (e.g. "is_granted(...) or is_granted(...)") instead.', __METHOD__), \E_USER_DEPRECATED); 60 | } 61 | 62 | return $this->accessDecisionManager->decide($token, $attributes, $subject); 63 | } 64 | } 65 | --------------------------------------------------------------------------------