Symfony2: 如何通过 IP 地址限制 / 拒绝访问特定路由?

7
我希望禁止客户端IP地址被封禁的访问/login/register
被封禁的IP地址黑名单存储在数据库中。
我该如何解决这个问题?
2个回答

6
自从symfony 2.4版本以来,您可以在配置文件中使用表达式语言组件(Expression Language Component)
现在,实现一个简单的IP检查很容易:
  • 创建一个服务(例如access_manager),其中包含一个方法(例如getBannedIPs()),该方法从存储层获取禁止访问的IP列表
  • 在安全配置中添加一个表达式,将返回的数组与客户端的IP地址进行比较
  • 就这样。

示例

# app/config/security.yml
security:
    # ...
    access_control:
        - path: ^/(login|register)$
          allow_if: "request.getClientIp() not in @=service('access_manager').getBannedIPs()"

你说得对,但如果我想用消息通知用户该怎么办? - gp_sflover
1
我尝试提供最简单的解决方案......但对于这种高级情况,您需要添加一个kernel.request监听器来匹配IP并将flashmessage添加到会话flashbag中......或者只需使用三元运算符和一个条件,该条件添加flashmessage并始终返回true.... (request.getClientIp()不在@=service('access_manager').getBannedIPs()中)?(@=service('session').getFlashBag().add('warning','您已被禁止。')!= false):false。明白了吗? - Nicolai Fröhlich
是的,谢谢!我之前从未使用过表达式,但我会开始尝试它们,以发现它们的使用限制以及它们在哪些情况下比其他解决方案更好或更简单。 - gp_sflover
3
我尝试了这个解决方案,但在security.yml中出现错误意外字符“@” - Einius

2

使用控制器事件(首选)

您可以订阅注册控制器上的事件。

对于注册,您可以订阅REGISTRATION_INITIALIZE事件。

这是控制器事件 的文档。

覆盖控制器方法

第二个解决方案是覆盖登录和注册控制器方法,但您将不得不复制登录/注册操作的所有代码。


不需要事件监听器或控制器覆盖来解决这个问题。只需利用 security.ymlaccess_control 下的表达式语言组件即可。请参见我的答案 :) - Nicolai Fröhlich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接