allow_if语句中的Unparse-able IP列表

时间:2017-02-02 09:30:53

标签: php symfony symfony-2.8 symfony-security

我有以下安全配置:

security:

    # .....

    access_control:
        -
            path: ^/path/to/resource
            allow_if: "request.getClientIp() in %my.ips%"

parameters:
    my.ips:
        - '129.0.0.1'
        - '55.12.99.100'

基本上我想根据IP列表允许/拒绝。

此IP列表根据一些业务规则并基于环境(测试,开发,产品等)不断变化/增长/缩小。这就是为什么我必须像allow_if规则那样写它。我不能只做ip=X or ip=Y or ip=Z or...之类的事情。

现在,这不起作用。我得到一个错误:

  

字符串值必须由字符串和/或数字组成,但必须找到   字符串值内的数组类型的参数“my.ips”。

我尝试了各种各样的组合,例如:

allow_if: "request.getClientIp() in '%my.ips%'"

allow_if: "request.getClientIp() in ['%my.ips%']"

...

我得到了同样的错误。

我怀疑这是使用Expression-Language组件解析和解释的。因此,根据here所描述的语法,我也尝试过这样做:

allow_if: "request.getClientIp() in parameter('my.ips')"

但它再次因错误而失败:

  

位置26周围不存在“参数”功能。

现在我有点卡住了。有什么方法可以让我的工作吗?

1 个答案:

答案 0 :(得分:1)

好的,所以我无法使表达式解析/接受常规参数,但我能够解决它。

这就是我的所作所为:

security:

    # .....

    access_control:
        -
            path: ^/path/to/resource
            ips: '%my.ips%'
            roles: ['ROLE_MY_ROLE']

        -
            path: ^/path/to/resource
            allow_if: 'false'

parameters:
    my.ips:
        - '129.0.0.1'
        - '55.12.0.0/16'

所以它的工作方式是这样的:

  • 尝试匹配第一个访问控制条目。
  • 如果我有其中一个IP,请检查我是否访问了正确的路径
  • 如果确实如此,那么检查我是否有其中一个角色
  • 如果我的路径或我的IP不匹配,请转到第二个条目
  • 如果它是相同的路径,则拒绝访问(因为allow_if始终是false

因此,只有当他来自特定的IP并且他有一个允许的角色时,用户才有义务访问该路由。

我发现有趣的是你可以将子网用于允许的IP列表,这非常酷,因为这意味着你也可以添加IP范围。也许这应该添加到文档中,因为它非常有用(我有时间在GitHub上制作公关)。