【问题标题】:Symfony 2.8 : dynamic containers parameters at compiler pass and used in security.ymlSymfony 2.8:编译器传递的动态容器参数并在 security.yml 中使用
【发布时间】:2017-10-07 14:26:53
【问题描述】:

我在我的 Symfony 2.8 API 项目中遇到了一个我自己无法解决的问题:

我在我的一个包的 DependencyInjection 中通过编译器加载了一些参数:

class ParametersCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        //loads api version from database when container gets built.
        $api_version = $container->get('doctrine')->getRepository('MyAppEntityBundle:Parameter')
            ->findOneBy(['name' => 'api_version']);
        if (!$api_version) {
            throw new MyAppException('api_version couldnt be found in database during container build process.');
        }
        $container->setParameter('api_version', $api_version);
    }
}

我不想在 paramters_*.yml 文件中使用这个参数,以确保它总是从 db 中检索到 + 我在 security.yml 文件中使用它,例如:

security:
    firewalls:
        api:
            pattern:   ^/api/%api_version%/

我怎样才能做到这一点?

显然,$container->setParameter('name', $value);如果 parameter_*.yml 文件中没有参数且parameters.yml 中有虚拟值,则不起作用 + 我需要在 security.yml 被解析和加载之前设置这些值。 我研究了 symfony 核心几个小时,发现了从 kernel->boot() 进程加载安全配置的位置,但我不知道如何正确实现我想要的。

任何有关正确方法的帮助或提示将不胜感激:)

【问题讨论】:

  • 所有配置文件解析都在调用任何通道之前完成。所以是的,你总是需要一个虚拟值。与 setParameter 无关。您可以查看 SecurityBundle 传递如何使其成为服务,并可能更改传递中的定义。但是从 pass 内部访问数据库是不寻常的。我怀疑它是否会起作用。
  • 防火墙的目标是什么?如前所述,使用编译器通道将在编译时充当 db 值的缓存app/console cache:warmup,并且不会在 db 值发生变化时更改,除非您重新编译您的应用程序。这在生产中会令人困惑和不受欢迎。使用security provider 在访问时而不是在编译时验证用户更有意义。然后,您可以执行自己的查询来验证每个请求的 api_version
  • @Cerad,我从我的源代码中删除了这个,但我很确定它是,也许是因为运气好,学说是在我的包通过之前在容器中构建的?还是每个供应商的捆绑包都是在我之前构建的?抱歉,这些都是假设。好的,我知道如何更改安全服务定义,但对于我想要实现的目标来说,它过于复杂,无论如何感谢您的提示!
  • @fyrye 这不是关于制作防火墙(= 检查授权,就像你说的安全提供商,我有适当的 JWT 系统),我正在寻找一种通过设置自动化 API 部署的方法从管理应用程序中,将新版本的 api 部署到数据库中(简而言之,它比这更复杂,+ 移动应用程序更新需要)然后部署它。感谢您的提示,但我认为检查每个请求的 api_version 对性能不利:)
  • @yfhrpcx 防火墙的目的是确定“何时发生身份验证”。我认为这将取决于您想要的结果。因为所有^/api 请求都应该进行身份验证。然后,版本的路由将由 API 控制器/api/{version} 处理。当api_version 更改时,您当前的方法将禁用身份验证。例如当api_version: 'v2' 是您想要的结果时,请求/api/v1

标签: php symfony parameters compiler-construction containers


【解决方案1】:

它可以工作,但我不知道是否是一个好习惯...... SecurityExtension 为每个防火墙请求匹配器创建一个动态服务,并且 id 由 md5 和 sha1 加密......您可以覆盖参数。

在 Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension 中查看方法 createRequestMatcher

【讨论】:

  • * 移至回答结束问题 *
  • 我同意,对我来说最好的解决方案也在配置文件中
【解决方案2】:

这显然不是一个好的做法,正如我在回复之前的 cmets 时所说的,我承认,对于一个简单的 API 版本管理问题来说,这在复杂性上是多余的。我最终在parameters.yml文件中设置了参数,所以当处理security.yml文件时,这不是问题,并将我的API管理逻辑放在CI的构建过程中。更有意义。 @Mocrates 非常感谢您的回答:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 2015-10-29
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多