Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #18952 [Security] Add a JSON authentication listener (dunglas)
This PR was squashed before being merged into the 3.3-dev branch (closes #18952). Discussion ---------- [Security] Add a JSON authentication listener | Q | A | | --- | --- | | Branch? | master | | Bug fix? | no | | New feature? | yes | | BC breaks? | no | | Deprecations? | no | | Tests pass? | yes | | Fixed tickets | n/a | | License | MIT | | Doc PR | symfony/symfony-docs#7081 | Add a new authentication listener allowing to login by sending a JSON document like: `{"_username": "dunglas", "_password": "foo"}`. It is similar to the traditional form login (but take a JSON document as entry) and is convenient for APIs, especially used in combination with JWT. See api-platform/core#563 and lexik/LexikJWTAuthenticationBundle#123 (comment) for previous discussions. - [x] Add functional tests in security bundle Commits ------- 02178bc [Security] Add a JSON authentication listener
- Loading branch information
Showing
12 changed files
with
531 additions
and
2 deletions.
There are no files selected for viewing
96 changes: 96 additions & 0 deletions
96
src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\DefinitionDecorator; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
|
||
/** | ||
* JsonLoginFactory creates services for JSON login authentication. | ||
* | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class JsonLoginFactory extends AbstractFactory | ||
{ | ||
public function __construct() | ||
{ | ||
$this->addOption('username_path', 'username'); | ||
$this->addOption('password_path', 'password'); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getPosition() | ||
{ | ||
return 'form'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getKey() | ||
{ | ||
return 'json-login'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId) | ||
{ | ||
$provider = 'security.authentication.provider.dao.'.$id; | ||
$container | ||
->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) | ||
->replaceArgument(0, new Reference($userProviderId)) | ||
->replaceArgument(1, new Reference('security.user_checker.'.$id)) | ||
->replaceArgument(2, $id) | ||
; | ||
|
||
return $provider; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getListenerId() | ||
{ | ||
return 'security.authentication.listener.json'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function isRememberMeAware($config) | ||
{ | ||
return false; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function createListener($container, $id, $config, $userProvider) | ||
{ | ||
$listenerId = $this->getListenerId(); | ||
$listener = new DefinitionDecorator($listenerId); | ||
$listener->replaceArgument(2, $id); | ||
$listener->replaceArgument(3, new Reference($this->createAuthenticationSuccessHandler($container, $id, $config))); | ||
$listener->replaceArgument(4, new Reference($this->createAuthenticationFailureHandler($container, $id, $config))); | ||
$listener->replaceArgument(5, array_intersect_key($config, $this->options)); | ||
|
||
$listenerId .= '.'.$id; | ||
$container->setDefinition($listenerId, $listener); | ||
|
||
return $listenerId; | ||
} | ||
} |
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
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
23 changes: 23 additions & 0 deletions
23
...ndle/SecurityBundle/Tests/Functional/Bundle/JsonLoginBundle/Controller/TestController.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\JsonLoginBundle\Controller; | ||
|
||
/** | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class TestController | ||
{ | ||
public function loginCheckAction() | ||
{ | ||
throw new \RuntimeException(sprintf('%s should never be called.', __FUNCTION__)); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/JsonLoginBundle/JsonLoginBundle.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\JsonLoginBundle; | ||
|
||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
/** | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class JsonLoginBundle extends Bundle | ||
{ | ||
} |
32 changes: 32 additions & 0 deletions
32
src/Symfony/Bundle/SecurityBundle/Tests/Functional/JsonLoginTest.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\SecurityBundle\Tests\Functional; | ||
|
||
/** | ||
* @author Kévin Dunglas <dunglas@gmail.com> | ||
*/ | ||
class JsonLoginTest extends WebTestCase | ||
{ | ||
public function testJsonLoginSuccess() | ||
{ | ||
$client = $this->createClient(array('test_case' => 'JsonLogin', 'root_config' => 'config.yml')); | ||
$client->request('POST', '/chk', array(), array(), array(), '{"user": {"login": "dunglas", "password": "foo"}}'); | ||
$this->assertEquals('http://localhost/', $client->getResponse()->headers->get('location')); | ||
} | ||
|
||
public function testJsonLoginFailure() | ||
{ | ||
$client = $this->createClient(array('test_case' => 'JsonLogin', 'root_config' => 'config.yml')); | ||
$client->request('POST', '/chk', array(), array(), array(), '{"user": {"login": "dunglas", "password": "bad"}}'); | ||
$this->assertEquals('http://localhost/login', $client->getResponse()->headers->get('location')); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/bundles.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
return array( | ||
new Symfony\Bundle\SecurityBundle\SecurityBundle(), | ||
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), | ||
new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\JsonLoginBundle\JsonLoginBundle(), | ||
); |
24 changes: 24 additions & 0 deletions
24
src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/config.yml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
imports: | ||
- { resource: ./../config/framework.yml } | ||
|
||
security: | ||
encoders: | ||
Symfony\Component\Security\Core\User\User: plaintext | ||
|
||
providers: | ||
in_memory: | ||
memory: | ||
users: | ||
dunglas: { password: foo, roles: [ROLE_USER] } | ||
|
||
firewalls: | ||
main: | ||
pattern: ^/ | ||
anonymous: true | ||
json_login: | ||
check_path: /mychk | ||
username_path: user.login | ||
password_path: user.password | ||
|
||
access_control: | ||
- { path: ^/foo, roles: ROLE_USER } |
3 changes: 3 additions & 0 deletions
3
src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/routing.yml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
login_check: | ||
path: /chk | ||
defaults: { _controller: JsonLoginBundle:Test:loginCheck } |
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
Oops, something went wrong.