Last active
February 4, 2020 16:32
-
-
Save Pierstoval/1e29a9badab1cba03e45a306aa658c83 to your computer and use it in GitHub Desktop.
(for stackoverflow)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This file is part of the corahn_rin package. | |
* | |
* (c) Alexandre Rock Ancelet <alex@orbitale.io> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace User\Security; | |
use Symfony\Component\HttpFoundation\RedirectResponse; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpKernel\HttpKernelInterface; | |
use Symfony\Component\Routing\RouterInterface; | |
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | |
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; | |
use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
use Symfony\Component\Security\Core\Exception\BadCredentialsException; | |
use Symfony\Component\Security\Core\Security; | |
use Symfony\Component\Security\Core\User\UserInterface; | |
use Symfony\Component\Security\Core\User\UserProviderInterface; | |
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator; | |
use Symfony\Component\Security\Http\HttpUtils; | |
use Symfony\Component\Security\Http\Util\TargetPathTrait; | |
use User\Entity\User; | |
use User\Repository\UserRepository; | |
final class FormLoginAuthenticator extends AbstractFormLoginAuthenticator | |
{ | |
use TargetPathTrait; | |
public const USERNAME_OR_EMAIL_FORM_FIELD = '_username_or_email'; | |
public const PASSWORD_FORM_FIELD = '_password'; | |
private const PROVIDER_KEY = 'main'; // Firewall name | |
private const LOGIN_ROUTE = 'user_login'; | |
private const NO_REFERER_ROUTES = [ | |
self::LOGIN_ROUTE, | |
'user_login_check', | |
'user_register', | |
'user_logout', | |
'user_check_email', | |
'user_registration_confirm', | |
'user_registration_confirmed', | |
'user_resetting_request', | |
'user_resetting_send_email', | |
'user_resetting_check_email', | |
'user_resetting_reset', | |
'user_change_password', | |
]; | |
private $httpKernel; | |
private $httpUtils; | |
private $router; | |
private $encoder; | |
private $defaultLocale; | |
public function __construct( | |
HttpKernelInterface $kernel, | |
HttpUtils $httpUtils, | |
RouterInterface $router, | |
UserPasswordEncoderInterface $encoder, | |
string $defaultLocale | |
) { | |
$this->httpKernel = $kernel; | |
$this->httpUtils = $httpUtils; | |
$this->router = $router; | |
$this->encoder = $encoder; | |
$this->defaultLocale = $defaultLocale; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function start(Request $request, AuthenticationException $authException = null) | |
{ | |
if (\in_array($request->attributes->get('_route'), static::NO_REFERER_ROUTES, true)) { | |
$this->removeTargetPath($request->getSession(), static::PROVIDER_KEY); | |
} elseif (!$this->getTargetPath($request->getSession(), static::PROVIDER_KEY)) { | |
$this->saveTargetPath($request->getSession(), static::PROVIDER_KEY, $request->getUri()); | |
} | |
// Forward the request to the login controller, to avoid too many redirections. | |
$subRequest = $this->httpUtils->createRequest($request, $this->getLoginUrl()); | |
$response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST); | |
if (200 === $response->getStatusCode()) { | |
$response->setStatusCode(401); | |
} | |
return $response; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function supports(Request $request) | |
{ | |
return | |
$request->isMethod('POST') | |
&& $request->request->has(self::USERNAME_OR_EMAIL_FORM_FIELD) | |
&& $request->request->has(self::PASSWORD_FORM_FIELD) | |
&& $request->getPathInfo() === $this->router->generate('user_login_check') | |
; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
protected function getLoginUrl() | |
{ | |
return $this->router->generate(static::LOGIN_ROUTE); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getCredentials(Request $request) | |
{ | |
$usernameOrEmail = $request->request->get(self::USERNAME_OR_EMAIL_FORM_FIELD); | |
$request->getSession()->set(Security::LAST_USERNAME, $usernameOrEmail); | |
$password = $request->request->get(self::PASSWORD_FORM_FIELD); | |
return UsernamePasswordCredentials::create( | |
$usernameOrEmail, | |
$password | |
); | |
} | |
/** | |
* {@inheritdoc} | |
* | |
* @param UsernamePasswordCredentials $credentials | |
* @param UserRepository $userProvider | |
*/ | |
public function getUser($credentials, UserProviderInterface $userProvider) | |
{ | |
$user = $userProvider->loadUserByUsername($credentials->getUsernameOrEmail()); | |
if (!$user) { | |
throw new AuthenticationException('security.bad_credentials'); | |
} | |
if ($user && !$user->isEmailConfirmed()) { | |
throw new AuthenticationException('security.email_not_confirmed'); | |
} | |
return $user; | |
} | |
/** | |
* {@inheritdoc} | |
* | |
* @param UsernamePasswordCredentials $credentials | |
* @param UserInterface|User $user | |
*/ | |
public function checkCredentials($credentials, UserInterface $user) | |
{ | |
if (!$this->encoder->isPasswordValid($user, $credentials->getPassword())) { | |
throw new BadCredentialsException('security.bad_credentials'); | |
} | |
return true; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) | |
{ | |
$session = $request->getSession(); | |
$targetPath = $this->getTargetPath($session, $providerKey); | |
if (!$targetPath) { | |
$targetPath = \rtrim($this->router->generate('root', ['_locale' => $request->getLocale() ?: $this->defaultLocale]), '/').'/'; | |
} | |
// Make sure username is not stored for next login | |
$session->remove(Security::LAST_USERNAME); | |
$this->removeTargetPath($session, $providerKey); | |
return new RedirectResponse($targetPath); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
framework: | |
#esi: ~ | |
#fragments: ~ | |
secret: '%env(APP_SECRET)%' | |
csrf_protection: ~ | |
http_method_override: true | |
form: ~ | |
validation: { enable_annotations: true } | |
php_errors: | |
log: true | |
assets: | |
version: '%version_code%' | |
version_format: '%%s?assetv=%%s' | |
trusted_hosts: | |
- '%env(ESTEREN_DOMAIN)%$' | |
- '%env(AGATE_DOMAIN)%$' | |
- '%env(DRAGONS_DOMAIN)%$' | |
- '%env(VERMINE_DOMAIN)%$' | |
session: | |
# http://symfony.com/doc/current/reference/configuration/framework.html#handler-id | |
handler_id: session.handler.native_file | |
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%' | |
enabled: true | |
name: AgateSessionCookie | |
gc_maxlifetime: 864000 | |
cookie_httponly: true | |
cookie_lifetime: 86400 | |
# To add when SF 4.2 releases | |
#cookie_samesite: lax |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# To get started with security, check out the documentation: | |
# http://symfony.com/doc/current/security.html | |
security: | |
# http://symfony.com/doc/current/security.html#encoding-the-user-s-password | |
encoders: | |
Symfony\Component\Security\Core\User\UserInterface: bcrypt | |
# http://symfony.com/doc/current/security.html#hierarchical-roles | |
role_hierarchy: | |
# Anyone who is a backer from Kickstarter or Ulule. | |
ROLE_BACKER: ROLE_USER | |
# A user that can view the map is automatically a user. | |
ROLE_MAPS_VIEW: ROLE_USER | |
# Backers "Travels" reedition | |
ROLE_BACKER_TRAVELS: | |
- ROLE_BACKER | |
- ROLE_MAPS_VIEW | |
# Content managers (access to backend) | |
ROLE_MANAGER: ROLE_USER | |
# Maps | |
ROLE_ADMIN_MAPS: ROLE_MANAGER | |
# Character Generator | |
ROLE_ADMIN_GENERATOR: ROLE_MANAGER | |
# Translator | |
ROLE_ADMIN_TRANSLATOR: ROLE_MANAGER | |
# Admins | |
ROLE_ADMIN: | |
- ROLE_MANAGER | |
- ROLE_ADMIN_GENERATOR | |
- ROLE_ADMIN_MAPS | |
- ROLE_ADMIN_TRANSLATOR | |
ROLE_SUPER_ADMIN: | |
- ROLE_BACKER_TRAVELS | |
- ROLE_ADMIN | |
- ROLE_ALLOWED_TO_SWITCH | |
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded | |
providers: | |
user_provider: | |
id: User\Repository\UserRepository | |
firewalls: | |
# disables authentication for assets and the profiler, adapt it according to your needs | |
dev: | |
pattern: '^/(_(profiler|wdt)|css|images|img|fonts|map_tiles|uploads|components|bundles|js|(%locales_regex%)/js/translations)/' | |
security: false | |
# http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate | |
# http://symfony.com/doc/current/security/form_login_setup.html | |
main: | |
pattern: ^/ | |
anonymous: ~ | |
provider: user_provider | |
remember_me: | |
secret: '%env(APP_SECRET)%' | |
path: / | |
name: EsterenRememberMe | |
logout: | |
invalidate_session: false | |
path: user_logout | |
target: root | |
guard: | |
authenticators: | |
- User\Security\FormLoginAuthenticator | |
# with these settings you can restrict or allow access for different parts | |
# of your application based on roles, ip, host or methods | |
# http://symfony.com/doc/current/security.html#security-book-access-control-matching-options | |
access_control: | |
- { path: '^/(?:%locales_regex%)/login', role: IS_AUTHENTICATED_ANONYMOUSLY } | |
- { path: '^/(?:%locales_regex%)/register', role: IS_AUTHENTICATED_ANONYMOUSLY } | |
- { path: '^/(?:%locales_regex%)/resetting', role: IS_AUTHENTICATED_ANONYMOUSLY } | |
- { path: '^/(?:%locales_regex%)/profile', role: ROLE_USER } | |
- { path: '^/(?:%locales_regex%)/characters', role: ROLE_USER } | |
- { path: '^/(?:%locales_regex%)/map-.*$', host: '%esteren_domains.esterenmaps%', role: ROLE_MAPS_VIEW } | |
- { path: '^/', host: '%esteren_domains.backoffice%', role: ROLE_MANAGER } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment