不管我们是否应该进行此更改(情况有点复杂,可能在我的保密协议中有所涵盖),我们的客户希望我们要求访问我们正在构建的网站的访问者必须来自他们的其他网站。如果用户从其他地方访问我们,他们应该被发送到该其他网站的登录屏幕。
感觉最简单的方法是使用既不mod_rewrite
是我们网站也不是其他网站的引荐来源来重定向任何内容。
我现在的想法是
在httpd.conf
RewriteMap deflector txt:/path/to/deflector.map
RewriteCond %{HTTP_REFERER} !=""
RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} =NOT-FOUND
RewriteRule ^ http://www.theothersite.com/login.jsp [R=307,L]
在deflector.map
//www.oursite.com/ -
//oursite.com/ -
//www.theothersite.com/ -
//theothersite.com/ -
这将使我们能够轻松扩展“允许的引荐来源”列表,这听起来是个好主意。
我有三个问题:
mod_rewrite
(我们已经广泛使用了) 这是实现这一目标的最佳方法吗?- 如果是,那么
307 Temporary Redirect
回应是处理它的最佳方式吗? - 由于我主要不是 LAMP 开发人员/管理员,我是否在这些重写规则中犯了任何愚蠢的拼写错误?;o)
我觉得307 Temporary Redirect
或者403 Forbidden
最合适状态代码Location:
并且我认为发送带有响应的重定向标头是一件坏事™ 4xx
。
这一切都有道理吗?
编辑:地图搜索是否支持大写字母?在默认是区分大小写的吗?这里我还需要担心大小写吗?
编辑2:地图搜索是正则表达式搜索还是全键匹配?如果地图包含www.foo.com
并且Referer:
标题读取,http://www.foo.com/bar.php
它会匹配吗?
答案1
我认为地图将区分大小写,并且您还需要从中提取主机名Referer
。我根本没有测试过,但类似这样的方法可能会有效:
RewriteMap deflector txt:/path/to/deflector.map
RewriteMap lc int:tolower
RewriteCond %{HTTP_REFERER} ^https?://([^:/?]+)
RewriteCond ${lc:%1} (.+)
RewriteCond ${deflector:%1|NOT-FOUND} =NOT-FOUND
RewriteRule ^ http://example.com/ [L]
不要对不寻常的响应代码感到困惑;默认值 302 就可以了。
答案2
我们最终实际做的事情如下:
RewriteCond %{REMOTE_HOST} !A.B.C.(D|E)
RewriteCond %{HTTP_HOST}==%{HTTP_REFERER} !^(.*?)==https?://\1/ [NC]
RewriteCond %{HTTP_REFERER} !https?://referring.domain.com/ [NC]
RewriteRule ^ https://referring.domain.com/path/to/login/script [R,L]
第一行RewriteCond
(以及类似的几行)的意思是开发人员和客户不受此引荐来源检查的限制(因为在访问我们的网站之前必须先去那里真的很累)。
第二个RewriteCond
是天才之举,检查引用者是否与Host:
请求中的相同。这是基于特里的回答 SO#7398191:通用 mod_rewrite 引荐来源检查— 因为mod_rewrite
只在测试字符串中进行变量插值,所以不能有一行读
RewriteCond %{HTTP_HOST} !^https?://%{HTTP_REFERER}/ [NC]
因为它根本就不会做那项检查。
显然我们“永远”不需要允许任何其他引荐来源。如果我们这样做,我想我只需要将最后一行设置RewriteCond
为结束[NC,OR]
并链接更多条件。
一切顺利。谢谢大家的帮助!