Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RTM] Use Symfony Security for authentication purposes in Contao #685

Merged
merged 170 commits into from
Dec 12, 2017
Merged
Show file tree
Hide file tree
Changes from 76 commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
ac790b4
First draft of refactored symfony authentication (see #559)
bytehead Jan 24, 2017
3ea15ca
Don't serialize inverted value
bytehead Jan 24, 2017
0113a77
Author annotation and code optimization
bytehead Jan 24, 2017
2431793
Revert ContaoUserProvider, use ContaoBackendUserProvider
bytehead Jan 24, 2017
78a1897
Refactored
bytehead Jan 24, 2017
39a79f4
Code style
bytehead Jan 24, 2017
3854353
Code style
bytehead Jan 24, 2017
0789538
Check instanceof BackendUser
bytehead Jan 24, 2017
f3c619d
Added tests
bytehead Jan 24, 2017
5eab0d1
Fix rebase (changes from @ausi)
bytehead Jan 24, 2017
876847e
Renamed firewalls
bytehead Feb 3, 2017
f528fd4
Merge branch 'develop' of github.com:contao/core-bundle into feature/…
bytehead Apr 20, 2017
360d19b
Implemented user impersonation / role switcher
bytehead Apr 23, 2017
7dd796c
CS
bytehead Apr 23, 2017
9bce732
Fixes
bytehead Apr 23, 2017
18084a9
Merge branch 'develop' of github.com:contao/core-bundle into feature/…
bytehead Apr 24, 2017
200045f
Replace old code by new user switcher service
bytehead Apr 25, 2017
87840fd
Use correct channel for logging, added PsrLogMessageProcessor
bytehead Apr 25, 2017
0d47546
Fixed context
bytehead Apr 25, 2017
c9f8633
Merge branch 'develop' of github.com:contao/core-bundle into feature/…
bytehead Jun 15, 2017
bc6e898
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Sep 11, 2017
bceaf66
Fixed template
bytehead Sep 11, 2017
13cc0e4
WIP
bytehead Sep 12, 2017
d747fca
Implemented symfony security for frontend user
bytehead Sep 12, 2017
16fb23a
Frontend remember me service
bytehead Sep 13, 2017
c71f39b
Cleanup
bytehead Sep 13, 2017
b4b7f4d
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Sep 13, 2017
96cbedb
Cleanup
bytehead Sep 13, 2017
4c1b626
CS
bytehead Sep 13, 2017
6da2c56
Fixed legacy tab
bytehead Sep 13, 2017
bcc5e50
Legacy tabs
bytehead Sep 13, 2017
bb20abb
CS
bytehead Sep 13, 2017
725c8b2
Renamed method
bytehead Sep 16, 2017
3630e21
CS
bytehead Sep 18, 2017
cf76623
Removed dump
bytehead Sep 18, 2017
b1c361a
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Sep 18, 2017
16206ea
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Oct 7, 2017
de865c5
Add the missing argument for the fragments mapper.
leofeyer Oct 7, 2017
be4bcf4
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Oct 7, 2017
d3a9cde
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Oct 7, 2017
67d006e
Various fixes
bytehead Oct 8, 2017
ed3ac8a
Added deprecation notices
bytehead Oct 8, 2017
c317778
postAuthenticate replacements
bytehead Oct 8, 2017
a17f1c1
Removed old code
bytehead Oct 8, 2017
9a426eb
importUser replacements
bytehead Oct 8, 2017
8f0769f
importUser refactored
bytehead Oct 8, 2017
4f228a6
Fix wrong parenthesis
bytehead Oct 8, 2017
238a9da
postLogin replacements
bytehead Oct 8, 2017
e4fd8a7
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Nov 3, 2017
fa2af65
checkCredentials replacements
bytehead Nov 3, 2017
a56eefa
Require security-bundle instead of security component
bytehead Nov 3, 2017
b107eba
Refactored legacy hooks, cleaned up unused code
bytehead Nov 5, 2017
d847d9c
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Nov 5, 2017
0de317b
Check if roles is actually of type array
bytehead Nov 6, 2017
fc9595a
Correctly cast to array
bytehead Nov 6, 2017
3712045
Prefix native functions that can be optimized by the Zend OPcache.
leofeyer Nov 7, 2017
961935f
Refactored some stuff
bytehead Nov 7, 2017
1ca16b6
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Nov 7, 2017
5d0a343
CS
bytehead Nov 7, 2017
55518fb
Reduce duplication smell
bytehead Nov 7, 2017
3eb7189
Simplified
bytehead Nov 7, 2017
a1bac26
Fixes and deprecations
bytehead Nov 7, 2017
678212d
Frontend preview implemented, added more deprecations
bytehead Nov 8, 2017
0482709
Fix PHPDoc
bytehead Nov 8, 2017
31f3ad0
Fixed BackendControllerTest
bytehead Nov 8, 2017
be2481c
Test logoutAction
bytehead Nov 8, 2017
e549ad0
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Nov 8, 2017
7f2b668
Fixed FrontendControllerTest
bytehead Nov 8, 2017
00e4f14
Renamed LegacyEncoder class
bytehead Nov 8, 2017
263cc99
Completed BackendUserProviderTest
bytehead Nov 8, 2017
4a35987
Fully test coverage for BackendUserProvider
bytehead Nov 8, 2017
3712a92
Tests for src/Security/User
bytehead Nov 8, 2017
fa2e084
Refactored test
bytehead Nov 9, 2017
e472fbd
Refactored 2nd
bytehead Nov 9, 2017
6dab3cc
CS
bytehead Nov 9, 2017
72867a7
Deprecate all old authentication stuff
bytehead Nov 9, 2017
4337acc
Added more tests
bytehead Nov 9, 2017
3de4503
Hardened test for SwitchUserButtonGenerator
bytehead Nov 9, 2017
8763fb0
Typo
bytehead Nov 9, 2017
9dce2a0
Added LogoutHandlerTest
bytehead Nov 10, 2017
44af5a4
Test if correct instance of object in hook callback
bytehead Nov 10, 2017
c5a7a3e
FrontendPreviewAuthenticatorTest added
bytehead Nov 10, 2017
41dd3d5
Added SwitchUserListenerTest
bytehead Nov 10, 2017
ffac0a1
Added InteractiveLoginListenerTest
bytehead Nov 10, 2017
c65efc3
Fixes
bytehead Nov 12, 2017
d10a32a
Added AuthenticationHandler tests
bytehead Nov 12, 2017
a8826ea
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Nov 12, 2017
2e25552
Added tests for ContaoAuthenticationProvider
bytehead Nov 12, 2017
708bfec
CS
bytehead Nov 12, 2017
2a3d325
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 16, 2017
544280b
Tests for UserChecker added
bytehead Nov 16, 2017
691b1c7
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 16, 2017
f30d590
Fixed UserCheckerTest
bytehead Nov 16, 2017
ff6f897
Fixed services.yml
bytehead Nov 17, 2017
4bcf95a
Fixed deprecation warnings in tests
bytehead Nov 17, 2017
bb01162
Added logger
bytehead Nov 17, 2017
9dbe2b8
Added custom events for deprecated hooks
bytehead Nov 17, 2017
15ded55
Deprecation notices
bytehead Nov 17, 2017
6046ca2
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 17, 2017
296ec83
Small fixes
bytehead Nov 17, 2017
d80b817
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 17, 2017
e1eb575
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 20, 2017
26d6d83
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 20, 2017
4ff9e28
Implemented missingbackend login error messages
bytehead Nov 20, 2017
643d38f
Removed unused
bytehead Nov 20, 2017
e33fdb0
Fixed AuthenticationSuccessHandler
bytehead Nov 20, 2017
280a9c4
Removed unused (error handling done in AuthenticationFailureHandler)
bytehead Nov 21, 2017
9c0777f
Use HttpUtils::createRedirectResponse
bytehead Nov 21, 2017
5adf2f8
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 21, 2017
6d3abe5
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 22, 2017
c78b641
Removed unused
bytehead Nov 22, 2017
d95d82f
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 22, 2017
6fe5203
Fixes
bytehead Nov 23, 2017
4715abe
Revert changes
bytehead Nov 23, 2017
23979ff
CS
bytehead Nov 23, 2017
51e1af5
Dispatch ImportUserEvent / trigger ImportUser hook only on POST requests
bytehead Nov 23, 2017
1c06515
Added missing messages to exceptions
bytehead Nov 23, 2017
8128d0b
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 23, 2017
c63eb2f
Replaced static classes in InteractiveLoginListener
bytehead Nov 23, 2017
9e93699
Surround the breadcrumb menus with a nav element (see #1036).
cliffparnitzky Nov 27, 2017
b1378c5
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 27, 2017
f9641c0
Fixed auto merge faults
bytehead Nov 27, 2017
8a47be0
Get rid of static class calls part 1
bytehead Nov 29, 2017
09c68b8
Merge branch 'develop' of github.com:contao/core-bundle into develop
bytehead Nov 29, 2017
27d8765
Merge branch 'develop' into feature/symfony-authentication-2
bytehead Nov 29, 2017
221e7fc
Fixed type hints
bytehead Nov 29, 2017
d75adc0
Get rid of static class calls part 2
bytehead Nov 29, 2017
40812b8
Use symfony/security-bundle instead of symfony/security component
bytehead Nov 29, 2017
917b510
Fixed service definition
bytehead Nov 29, 2017
0493219
Use htmlspecialchars instead of StringUtil::specialchars
bytehead Nov 29, 2017
8682185
Get rid of static class calls part 3
bytehead Nov 29, 2017
97e0443
Don't escape because twig.
bytehead Nov 30, 2017
4bedee8
Get rid of static class calls part 4
bytehead Nov 30, 2017
06fc704
Still use \StringUtil::specialchars
bytehead Dec 1, 2017
559cb3a
Correctly initialize the framework before calling legacy hooks and stuff
bytehead Dec 1, 2017
76d683b
Correctly set lastLogin time on interactive login
bytehead Dec 3, 2017
423d5bb
Serialize also actual tstamp on the User object
bytehead Dec 3, 2017
4c78db7
Added TokenLifetimeListener
bytehead Dec 3, 2017
0f136b6
CS
bytehead Dec 3, 2017
4615ca3
Implemented the EquatableInterface, compare tstamp and roles of the o…
bytehead Dec 4, 2017
9053eb0
Check if ContaoMasterRequest
bytehead Dec 4, 2017
2dff80a
Be sure it's always a string
bytehead Dec 7, 2017
40385f7
Merge remote-tracking branch 'upstream/develop' into feature/symfony-…
bytehead Dec 7, 2017
1e57b81
Re-add rehashing section
bytehead Dec 7, 2017
7ede0c2
CS
bytehead Dec 7, 2017
2435404
Disable built-in logout_on_user_change (deprecation warning)
bytehead Dec 7, 2017
e3f4376
Fixes
bytehead Dec 7, 2017
91209fa
Get user from session on getInstance, if available
bytehead Dec 7, 2017
82bbb66
Consistently use security session key constant
bytehead Dec 7, 2017
fe7fdb7
Set logout_on_user_change always to true (see
bytehead Dec 8, 2017
e2bed63
Add new label for exit impersonation button
bytehead Dec 8, 2017
2646812
Prefixed install firewall with contao_
bytehead Dec 8, 2017
c57d4b3
Fixed bc break
bytehead Dec 8, 2017
a356b2b
Load user complete, if session has a token
bytehead Dec 8, 2017
4f33be5
Fix the coding style (part 1).
leofeyer Dec 8, 2017
514f3fb
Use the correct casing for the new events.
leofeyer Dec 8, 2017
316eabd
Fixes
bytehead Dec 8, 2017
1b65631
Fixes
bytehead Dec 8, 2017
1fae07d
CS
bytehead Dec 8, 2017
7e9ecad
Fix the coding style (part 2).
leofeyer Dec 11, 2017
99c1ece
Always check if a password needs to be rehashed.
leofeyer Dec 11, 2017
88860b8
Redirect to the back end login screen when logging out in the back end.
leofeyer Dec 11, 2017
77b94f3
Added LogoutSuccessHandlerTest test case for backend request
bytehead Dec 11, 2017
a3be2b0
Update the README file and add a change log entry.
leofeyer Dec 11, 2017
f9fed70
Fix the coding style (part 3).
leofeyer Dec 12, 2017
b766f17
Adjust the log messages.
leofeyer Dec 12, 2017
3328398
Do not add events for old hooks.
leofeyer Dec 12, 2017
4444e7d
Remove the switch user button generator.
leofeyer Dec 12, 2017
94916b8
Revert some unrelated changes.
leofeyer Dec 12, 2017
975070e
Encode the target path in the login form.
leofeyer Dec 12, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"symfony/http-foundation": "^3.4",
"symfony/lock": "^3.4",
"symfony/proxy-manager-bridge": "^3.4",
"symfony/security": "^3.4",
"symfony/security-bundle": "^3.4",
"symfony/yaml": "^3.4",
"sensio/framework-extra-bundle": "^3.0.2",
"symfony/swiftmailer-bundle": "^2.3.10",
Expand Down
12 changes: 12 additions & 0 deletions src/Controller/BackendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ public function passwordAction(): Response
*/
public function previewAction(): Response
{
$request = $this->container->get('request_stack')->getCurrentRequest();

$this->container->get('contao.framework')->initialize();
$this->container->get('contao.security.frontend_preview_authenticator')->authenticateFrontendUser($request->get('user'));

$controller = new BackendPreview();

Expand Down Expand Up @@ -224,4 +227,13 @@ public function pickerAction(Request $request): RedirectResponse

return new RedirectResponse($picker->getCurrentUrl());
}

/**
* Symfony will un-authenticate the user automatically by calling this route.
*
* @Route("/contao/logout", name="contao_backend_logout")
*/
public function logoutAction(): void
{
}
}
18 changes: 18 additions & 0 deletions src/Controller/FrontendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,22 @@ public function shareAction(): RedirectResponse

return $controller->run();
}

/**
* Symfony will un-authenticate the user automatically by calling this route.
*
* @Route("/_contao/logout", name="contao_frontend_logout")
*/
public function logoutAction(): void
{
}

/**
* Symfony will authenticate the user automatically by calling this route.
*
* @Route("/_contao/login", name="contao_frontend_login")
*/
public function loginAction(): void
{
}
}
71 changes: 71 additions & 0 deletions src/EventListener/InteractiveLoginListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* Copyright (c) 2005-2017 Leo Feyer
*
* @license LGPL-3.0+
*/

namespace Contao\CoreBundle\EventListener;

use Contao\CoreBundle\Monolog\ContaoContext;
use Contao\System;
use Contao\User;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

/**
* Interactive login listener to log successful login attempts.
*/
class InteractiveLoginListener
{
protected $logger;

public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}

public function onInteractiveLogin(InteractiveLoginEvent $event): void
{
/** @var UserInterface $user */
$user = $event->getAuthenticationToken()->getUser();

if (!$user instanceof User) {
return;
}

$this->logger->info(
sprintf('User %s has logged in.', $user->username),
['contao' => new ContaoContext(__METHOD__, ContaoContext::ACCESS)]
);

$this->triggerLegacyPostLoginHook($user);
}

/**
* The postLogin hook is triggered after a user has logged in. This can be either in the back end or the front end.
* It passes the user object as argument and does not expect a return value.
*
* @param User $user
*
* @deprecated Deprecated since Contao 4.x, to be removed in Contao 5.0.
*/
protected function triggerLegacyPostLoginHook(User $user): void
{
@trigger_error('Using InteractiveLoginListener::triggerLegacyPostLoginHook() has been deprecated and will no longer work in Contao 5.0. Use the security.interactive_login event instead.', E_USER_DEPRECATED);

// HOOK: post login callback
if (isset($GLOBALS['TL_HOOKS']['postLogin']) && is_array($GLOBALS['TL_HOOKS']['postLogin'])) {
foreach ($GLOBALS['TL_HOOKS']['postLogin'] as $callback) {
$user->objLogin = System::importStatic($callback[0], 'objLogin', true);
$user->objLogin->{$callback[1]}($user);
}
}
}
}
54 changes: 54 additions & 0 deletions src/EventListener/SwitchUserListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* Copyright (c) 2005-2017 Leo Feyer
*
* @license LGPL-3.0+
*/

namespace Contao\CoreBundle\EventListener;

use Contao\BackendUser;
use Contao\CoreBundle\Monolog\ContaoContext;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;

/**
* SwitchUserListener allows a user to impersonate another one temporarily
* (like the Unix su command).
*/
class SwitchUserListener
{
protected $logger;
protected $tokenStorage;

public function __construct(LoggerInterface $logger, TokenStorageInterface $tokenStorage)
{
$this->logger = $logger;
$this->tokenStorage = $tokenStorage;
}

/**
* Logs the switch to another user.
*
* @param SwitchUserEvent $event
*/
public function onSwitchUser(SwitchUserEvent $event): void
{
/** @var BackendUser $user */
$user = $this->tokenStorage->getToken()->getUser();

/** @var BackendUser $targetUser */
$targetUser = $event->getTargetUser();

$this->logger->info(
sprintf('User %s has switched to user %s.', $user->username, $targetUser->username),
['contao' => new ContaoContext(__METHOD__, ContaoContext::ACCESS)]
);
}
}
20 changes: 20 additions & 0 deletions src/Exception/UserNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* Copyright (c) 2005-2017 Leo Feyer
*
* @license LGPL-3.0+
*/

namespace Contao\CoreBundle\Exception;

/**
* UserNotFoundException is thrown if a User cannot be found.
*/
class UserNotFoundException extends \RuntimeException
{
}
16 changes: 16 additions & 0 deletions src/Resources/config/listener.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,19 @@ services:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }

contao.security.switch_user_listener:
class: Contao\CoreBundle\EventListener\SwitchUserListener
arguments:
- "@logger"
- "@security.token_storage"
tags:
- { name: kernel.event_listener, event: security.switch_user, method: onSwitchUser }
- { name: monolog.logger, channel: contao }

contao.security.interactive_login_listener:
class: Contao\CoreBundle\EventListener\InteractiveLoginListener
arguments:
- "@logger"
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }
76 changes: 76 additions & 0 deletions src/Resources/config/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
security:
providers:
contao.security.backend_user_provider:
id: contao.security.backend_user_provider

contao.security.frontend_user_provider:
id: contao.security.frontend_user_provider

encoders:
default:
algorithm: bcrypt

legacy:
id: contao.security.legacy_password_encoder

firewalls:
dev:
pattern: ^/(_(profiler|wdt|error)|css|images|js)/
security: false

install:
pattern: ^/contao/install
security: false

contao_backend:
request_matcher: contao.routing.backend_matcher
provider: contao.security.backend_user_provider
user_checker: contao.security.user_checker
anonymous: ~
switch_user: true

form_login:
login_path: contao_backend_login
check_path: contao_backend_login
default_target_path: contao_backend
success_handler: contao.security.authentication_success_handler
username_parameter: username
password_parameter: password

logout:
path: contao_backend_logout
target: contao_backend
success_handler: contao.security.logout_success_handler
handlers:
- contao.security.logout_handler

contao_frontend:
request_matcher: contao.routing.frontend_matcher
provider: contao.security.frontend_user_provider
user_checker: contao.security.user_checker
anonymous: ~
switch_user: false

form_login:
login_path: contao_frontend_login
check_path: contao_frontend_login
default_target_path: contao_index
failure_handler: contao.security.authentication_failure_handler
success_handler: contao.security.authentication_success_handler
username_parameter: username
password_parameter: password
remember_me: true

remember_me:
secret: '%secret%'
remember_me_parameter: autologin

logout:
path: contao_frontend_logout
success_handler: contao.security.logout_success_handler
handlers:
- contao.security.logout_handler

access_control:
- { path: ^/contao/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/contao, roles: ROLE_USER }
Loading