EC-CUBE4は認可アクセスコントロールをDIの拡張機能を利用して設定しています。
namespace Eccube\DependencyInjection;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Configuration as DoctrineBundleConfiguration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class EccubeExtension extends Extension implements PrependExtensionInterface
{
/**
* Loads a specific configuration.
*
* @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $configs, ContainerBuilder $container)
{
}
/**
* Allow an extension to prepend the extension configurations.
*/
public function prepend(ContainerBuilder $container)
{
// FrameworkBundleの設定を動的に変更する.
$this->configureFramework($container);
// プラグインの有効無効判定および初期化を行う.
$this->configurePlugins($container);
}
protected function configureFramework(ContainerBuilder $container)
{
$forceSSL = $container->resolveEnvPlaceholders('%env(ECCUBE_FORCE_SSL)%', true);
// envから取得した内容が文字列のため, booleanに変換
if ('true' === $forceSSL) {
$forceSSL = true;
} elseif ('false' === $forceSSL) {
$forceSSL = false;
}
// SSL強制時は, httpsのみにアクセス制限する
$accessControl = [
['path' => '^/%eccube_admin_route%/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
['path' => '^/%eccube_admin_route%/', 'roles' => 'ROLE_ADMIN'],
['path' => '^/mypage/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
['path' => '^/mypage/withdraw_complete', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
['path' => '^/mypage/change', 'roles' => 'IS_AUTHENTICATED_FULLY'],
['path' => '^/mypage/', 'roles' => 'ROLE_USER'],
];
if ($forceSSL) {
foreach ($accessControl as &$control) {
$control['requires_channel'] = 'https';
}
}
// security.ymlでは制御できないため, ここで定義する.
$container->prependExtensionConfig('security', [
'access_control' => $accessControl,
]);
}
おそらくSSL強制の切り替えを動的に行いたいためだと思いますが、SSL強制の動的切り替えはyamlファイルでも設定可能です。
設定方法は以下の通りです。
security:
access_control:
- { path: ^/%eccube_admin_route%/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: "@=container.getParameter('eccube_force_ssl') ? 'https' : 'http'"}
- { path: ^/%eccube_admin_route%/, roles: ROLE_ADMIN, requires_channel: "@=container.getParameter('eccube_force_ssl') 'https' : 'http'"}
- { path: ^/mypage/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: "@=container.getParameter('eccube_force_ssl') 'https' : 'http'"}
- { path: ^/mypage/withdraw_complete, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: "@=container.getParameter('eccube_force_ssl') ? 'https' : 'http'"}
- { path: ^/mypage/change, roles: IS_AUTHENTICATED_FULLY, requires_channel: "@=container.getParameter('eccube_force_ssl') ? 'https' : 'http'"}
- { path: ^/mypage/, roles: ROLE_USER, requires_channel: "@=container.getParameter('eccube_force_ssl') ? 'https' : 'http'"}
.envで設定されたSSL強制の有効・無効は以下の式で取得しています。
@=container.getParameter('eccube_force_ssl')
Symfonyのサービスコンテナは特定の値をサービスに挿入できる「式」をサポートしていて、yamlファイルで式を使用する場合は「@=」のプレフィックスを付ける必要があります。
詳しくはSymfonyドキュメントの「How to Inject Values Based on Complex Expressions」をご確認ください。
コンテナにアクセスする場合は、先頭に@=
をついてcontainer
を指定するだけです。
上記の式ではcontainer
のgetParameter
メソッドで.envに設定されたECCUBE_FORCE_SSL
の値を取得しています。
security.yamlファイルで設定したほうがシンプルで見やすいと思います。
販売管理システム(別サーバーのDB)から顧客情報をAPIで取得してその情報でマイページにログインしたいのですが、認証に引っかかって失敗してしまいます。とりあえず認証をパスしたい場合は何を変更すればいいんでしょうか?