The start of something beautiful
This commit is contained in:
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
<?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\AccessToken;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\Security\Http\AccessToken\Cas\Cas2Handler;
|
||||
|
||||
class CasTokenHandlerFactory implements TokenHandlerFactoryInterface
|
||||
{
|
||||
public function create(ContainerBuilder $container, string $id, array|string $config): void
|
||||
{
|
||||
$container->setDefinition($id, new ChildDefinition('security.access_token_handler.cas'));
|
||||
|
||||
$container
|
||||
->register('security.access_token_handler.cas', Cas2Handler::class)
|
||||
->setArguments([
|
||||
new Reference('request_stack'),
|
||||
$config['validation_url'],
|
||||
$config['prefix'],
|
||||
$config['http_client'] ? new Reference($config['http_client']) : null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return 'cas';
|
||||
}
|
||||
|
||||
public function addConfiguration(NodeBuilder $node): void
|
||||
{
|
||||
$node
|
||||
->arrayNode($this->getKey())
|
||||
->fixXmlConfig($this->getKey())
|
||||
->children()
|
||||
->scalarNode('validation_url')
|
||||
->info('CAS server validation URL')
|
||||
->isRequired()
|
||||
->end()
|
||||
->scalarNode('prefix')
|
||||
->info('CAS prefix')
|
||||
->defaultValue('cas')
|
||||
->end()
|
||||
->scalarNode('http_client')
|
||||
->info('HTTP Client service')
|
||||
->defaultNull()
|
||||
->end()
|
||||
->end()
|
||||
->end();
|
||||
}
|
||||
}
|
||||
Vendored
+122
@@ -0,0 +1,122 @@
|
||||
<?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\AccessToken;
|
||||
|
||||
use Jose\Component\Core\Algorithm;
|
||||
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* Configures a token handler for decoding and validating an OIDC token.
|
||||
*/
|
||||
class OidcTokenHandlerFactory implements TokenHandlerFactoryInterface
|
||||
{
|
||||
public function create(ContainerBuilder $container, string $id, array|string $config): void
|
||||
{
|
||||
$tokenHandlerDefinition = $container->setDefinition($id, (new ChildDefinition('security.access_token_handler.oidc'))
|
||||
->replaceArgument(2, $config['audience'])
|
||||
->replaceArgument(3, $config['issuers'])
|
||||
->replaceArgument(4, $config['claim'])
|
||||
);
|
||||
|
||||
if (!ContainerBuilder::willBeAvailable('web-token/jwt-library', Algorithm::class, ['symfony/security-bundle'])) {
|
||||
throw new LogicException('You cannot use the "oidc" token handler since "web-token/jwt-library" is not installed. Try running "composer require web-token/jwt-library".');
|
||||
}
|
||||
|
||||
$tokenHandlerDefinition->replaceArgument(0, (new ChildDefinition('security.access_token_handler.oidc.signature'))
|
||||
->replaceArgument(0, $config['algorithms']));
|
||||
|
||||
$tokenHandlerDefinition->replaceArgument(1, (new ChildDefinition('security.access_token_handler.oidc.jwkset'))
|
||||
->replaceArgument(0, $config['keyset'])
|
||||
);
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return 'oidc';
|
||||
}
|
||||
|
||||
public function addConfiguration(NodeBuilder $node): void
|
||||
{
|
||||
$node
|
||||
->arrayNode($this->getKey())
|
||||
->fixXmlConfig($this->getKey())
|
||||
->validate()
|
||||
->ifTrue(static fn ($v) => !isset($v['algorithm']) && !isset($v['algorithms']))
|
||||
->thenInvalid('You must set either "algorithm" or "algorithms".')
|
||||
->end()
|
||||
->validate()
|
||||
->ifTrue(static fn ($v) => !isset($v['key']) && !isset($v['keyset']))
|
||||
->thenInvalid('You must set either "key" or "keyset".')
|
||||
->end()
|
||||
->beforeNormalization()
|
||||
->ifTrue(static fn ($v) => isset($v['algorithm']) && \is_string($v['algorithm']))
|
||||
->then(static function ($v) {
|
||||
if (isset($v['algorithms'])) {
|
||||
throw new InvalidConfigurationException('You cannot use both "algorithm" and "algorithms" at the same time.');
|
||||
}
|
||||
$v['algorithms'] = [$v['algorithm']];
|
||||
unset($v['algorithm']);
|
||||
|
||||
return $v;
|
||||
})
|
||||
->end()
|
||||
->beforeNormalization()
|
||||
->ifTrue(static fn ($v) => isset($v['key']) && \is_string($v['key']))
|
||||
->then(static function ($v) {
|
||||
if (isset($v['keyset'])) {
|
||||
throw new InvalidConfigurationException('You cannot use both "key" and "keyset" at the same time.');
|
||||
}
|
||||
$v['keyset'] = sprintf('{"keys":[%s]}', $v['key']);
|
||||
|
||||
return $v;
|
||||
})
|
||||
->end()
|
||||
->children()
|
||||
->scalarNode('claim')
|
||||
->info('Claim which contains the user identifier (e.g.: sub, email..).')
|
||||
->defaultValue('sub')
|
||||
->end()
|
||||
->scalarNode('audience')
|
||||
->info('Audience set in the token, for validation purpose.')
|
||||
->isRequired()
|
||||
->end()
|
||||
->arrayNode('issuers')
|
||||
->info('Issuers allowed to generate the token, for validation purpose.')
|
||||
->isRequired()
|
||||
->scalarPrototype()->end()
|
||||
->end()
|
||||
->arrayNode('algorithm')
|
||||
->info('Algorithm used to sign the token.')
|
||||
->setDeprecated('symfony/security-bundle', '7.1', 'The "%node%" option is deprecated and will be removed in 8.0. Use the "algorithms" option instead.')
|
||||
->end()
|
||||
->arrayNode('algorithms')
|
||||
->info('Algorithms used to sign the token.')
|
||||
->isRequired()
|
||||
->scalarPrototype()->end()
|
||||
->end()
|
||||
->scalarNode('key')
|
||||
->info('JSON-encoded JWK used to sign the token (must contain a "kty" key).')
|
||||
->setDeprecated('symfony/security-bundle', '7.1', 'The "%node%" option is deprecated and will be removed in 8.0. Use the "keyset" option instead.')
|
||||
->end()
|
||||
->scalarNode('keyset')
|
||||
->info('JSON-encoded JWKSet used to sign the token (must contain a list of valid keys).')
|
||||
->isRequired()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<?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\AccessToken;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
/**
|
||||
* Configures a token handler for an OIDC server.
|
||||
*/
|
||||
class OidcUserInfoTokenHandlerFactory implements TokenHandlerFactoryInterface
|
||||
{
|
||||
public function create(ContainerBuilder $container, string $id, array|string $config): void
|
||||
{
|
||||
$clientDefinition = (new ChildDefinition('security.access_token_handler.oidc_user_info.http_client'))
|
||||
->replaceArgument(0, ['base_uri' => $config['base_uri']]);
|
||||
|
||||
if (isset($config['client'])) {
|
||||
$clientDefinition->setFactory([new Reference($config['client']), 'withOptions']);
|
||||
} elseif (!ContainerBuilder::willBeAvailable('symfony/http-client', HttpClientInterface::class, ['symfony/security-bundle'])) {
|
||||
throw new LogicException('You cannot use the "oidc_user_info" token handler since the HttpClient component is not installed. Try running "composer require symfony/http-client".');
|
||||
}
|
||||
|
||||
$container->setDefinition($id, new ChildDefinition('security.access_token_handler.oidc_user_info'))
|
||||
->replaceArgument(0, $clientDefinition)
|
||||
->replaceArgument(2, $config['claim']);
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return 'oidc_user_info';
|
||||
}
|
||||
|
||||
public function addConfiguration(NodeBuilder $node): void
|
||||
{
|
||||
$node
|
||||
->arrayNode($this->getKey())
|
||||
->fixXmlConfig($this->getKey())
|
||||
->beforeNormalization()
|
||||
->ifString()
|
||||
->then(fn ($v) => ['claim' => 'sub', 'base_uri' => $v])
|
||||
->end()
|
||||
->children()
|
||||
->scalarNode('base_uri')
|
||||
->info('Base URI of the userinfo endpoint on the OIDC server.')
|
||||
->isRequired()
|
||||
->cannotBeEmpty()
|
||||
->end()
|
||||
->scalarNode('claim')
|
||||
->info('Claim which contains the user identifier (e.g. sub, email, etc.).')
|
||||
->defaultValue('sub')
|
||||
->cannotBeEmpty()
|
||||
->end()
|
||||
->scalarNode('client')
|
||||
->info('HttpClient service id to use to call the OIDC server.')
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?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\AccessToken;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Configures a token handler from a service id.
|
||||
*
|
||||
* @see \Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Security\Factory\AccessTokenFactoryTest
|
||||
*/
|
||||
class ServiceTokenHandlerFactory implements TokenHandlerFactoryInterface
|
||||
{
|
||||
public function create(ContainerBuilder $container, string $id, array|string $config): void
|
||||
{
|
||||
$container->setDefinition($id, new ChildDefinition($config));
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return 'id';
|
||||
}
|
||||
|
||||
public function addConfiguration(NodeBuilder $node): void
|
||||
{
|
||||
$node->scalarNode($this->getKey())->end();
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?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\AccessToken;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Allows creating configurable token handlers.
|
||||
*/
|
||||
interface TokenHandlerFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a generic token handler service.
|
||||
*/
|
||||
public function create(ContainerBuilder $container, string $id, array|string $config): void;
|
||||
|
||||
/**
|
||||
* Gets a generic token handler configuration key.
|
||||
*/
|
||||
public function getKey(): string;
|
||||
|
||||
/**
|
||||
* Adds a generic token handler configuration.
|
||||
*/
|
||||
public function addConfiguration(NodeBuilder $node): void;
|
||||
}
|
||||
Reference in New Issue
Block a user