我正在尝试设置一个 WebDAV 服务器,该服务器使用用户名重定向到私有 DAV 目录。每个私有目录中还有一个名为共享文件夹。
这个想法是,当用户登录时,他首先会被重定向到他的私人目录。使用重写模块,URL 中不会显示任何路径,只有主机名,这可以防止用户进入另一个私人目录。当用户打开名为共享文件夹,mod_rewrite 将在匹配的 RewriteCond 文件夹名称上触发,并重定向到 RewriteMap 中指定的相应共享文件夹。
我的虚拟主机配置:
LoadModule dbd_module modules/mod_dbd.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
DBDriver mysql
DBDParams "host=db.example.com user=username pass=password dbname=webdav"
<VirtualHost *:80>
Servername webdav.example.com
DocumentRoot /var/www
Options +FollowSymlinks
RewriteLog "/var/log/httpd/rewrite.log"
RewriteLogLevel 5
RewriteEngine on
RewriteRule ^(.*) /webdav/%{LA-U:REMOTE_USER}$1
RewriteMap usergroup txt:/etc/httpd/usersingroups
RewriteCond %{REQUEST_URI} ^/SharedFolder/ [NC]
RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}} [L]
<Directory "/var/www">
DAV on
Options +Indexes
AuthName "example.com"
AuthType Digest
AuthDigestDomain /
AuthDigestProvider dbd
AuthDBDUserRealmQuery "SELECT digest FROM users WHERE username = %s AND unix_timestamp() < (ts+900) "
Require valid-user
</Directory>
</VirtualHost>
的内容重写映射如下:
fred sales/indoor/
bob sales/outdoor/
alice production/warehouse
文件系统的布局都在文档根目录/var/www。/var/www 中有两个文件夹。一个名为 /var/www/webdav,其中包含所有私有目录。另一个文件夹名为 /var/www/sharedfolders,其中包含属于不同组的目录。通过在重写映射我可以确定用户中显示哪个组目录共享文件夹。
我面临的问题是,重定向到 SharedFolder 无法正常工作。用户私有目录中的每个文件或文件夹都可以访问和使用。除了共享文件夹。当我打开它共享文件夹,我可以看到它的内容(一个 txt 文件和一个文件夹),但我无法打开该文件(我的桌面上就是这么显示的)。重写日志显示:
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) rewrite '/webdav/fred/SharedFolder/Readme.txt/' -> '/sharedfolders/sales/indoor/'
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) local path result: /sharedfolders/sales/indoor/
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) prefixed with document_root to /var/www/sharedfolders/sales/indoor/
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (1) go-ahead with /var/www/sharedfolders/sales/indoor/ [OK]
当我阅读重写日志时,它告诉我该文件(Readme.txt)最终没有被重写而无法打开。
另一个问题是打开共享文件夹.我不断看到的内容共享文件夹在其内部。来自 WebDAV 磁盘:SharedFolder/folder a/folder a/folder a/folder a
等等。在每个“文件夹 a”内,我还会看到文件“Readme.txt”。以下是重写日志对此的说明:
[webdav.example.com/sid#8ffd998][rid#905d898/initial] (2) rewrite '/SharedFolder/bla/bla/bla/' -> '/webdav/fred/SharedFolder/bla/bla/bla/'
[webdav.example.com/sid#8ffd998][rid#904b850/subreq] (2) init rewrite engine with requested uri /webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) init rewrite engine with requested uri /webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) rewrite '/webdav/fred/SharedFolder/bla/bla/bla/' -> '/webdav//webdav/fred/SharedFolder/bla/bla/bla/'
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) local path result: /webdav//webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) prefixed with document_root to /var/www/webdav/webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (1) go-ahead with /var/www/webdav/webdav/fred/SharedFolder/bla/bla/bla/ [OK]
我相信我已经向前迈出了几步,但还不够:-)
一些背景信息:我最初尝试使用符号链接通过 SharedFolder 实现相同的目标,但是与启用的 WebDAV 结合似乎是不可能的(我无法使其工作)。
操作系统:RHEL5.8 Apache 版本:2.2.3
提前致谢
更新
根据 @Jenny_D 的建议,我做了一些更改。我已在code
本问题的部分中更新了我当前的配置。我已更改的内容:
- 删除了末尾的 $1
RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}
- 添加
[L]
到同一行的末尾。 - 将其更改
<Directory "/var/www/webdav">
为<Directory "/var/www">
,以便重写路径 (/var/www/sharedfolders) 也支持 DAV。
最后一个变化(第 3 个变化)带来了很大的变化:我现在可以看到共享文件夹我之前放置过(没有 WebDAV)。
答案1
问题在于:
RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}$1
您要做的是捕获 URL 中使用的目录,将其存储在 $1 中,然后将 $1 附加到行尾。如果您不知道附加的 URL 部分是什么,只需删除末尾的 $1 即可。
要在共享文件夹规则后停止重写,请在末尾添加标志 [L]。
因此规则最终应如下所示:
RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}} [L]
答案2
我找到了一个可行的配置。我现在使用以下内容:
LoadModule dbd_module modules/mod_dbd.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
DBDriver mysql
DBDParams "host=db.example.com user=username pass=password dbname=webdav"
<VirtualHost *:80>
Servername webdav.example.com
DocumentRoot /var/www
Options +FollowSymlinks
RewriteLog "/var/log/httpd/rewrite.log"
RewriteLogLevel 2
RewriteEngine on
RewriteMap usergroup txt:/etc/httpd/usersingroups
RewriteCond %{REQUEST_URI} !^/SharedFolder [NC]
RewriteRule .? - [S=2]
RewriteRule ^/SharedFolder/(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}$1
RewriteRule .? - [S=2]
RewriteCond %{REQUEST_URI} !^/SharedFolder [NC]
RewriteRule ^(.*)$ /webdav/%{LA-U:REMOTE_USER}$1
<Directory "/var/www">
DAV on
Options +Indexes
AuthName "example.com"
AuthType Digest
AuthDigestDomain /
AuthDigestProvider dbd
AuthDBDUserRealmQuery "SELECT digest FROM users WHERE username = %s AND unix_timestamp() < (ts+900) "
Require valid-user
</Directory>
</VirtualHost>
我创建了一个 if-then-else 结构,如果满足某个条件,则跳过相应行。除此之外,我还制作了重写规则为了共享文件夹更具体一点。这基本上奏效了。之后,我被流量管理器(反向代理)搞得一团糟,它把 SSL 卸载到这个主机(因此:80在<VirtualHost *:80>
。查看、上传和删除都很好,除了重命名。事实证明,当您在 WebDAV 中重命名文件或文件夹时,全部的上传或删除文件或文件夹时,会发送目标标头,而不仅仅是路径。因此,在执行某种形式的 SSL 卸载时,请记住这一点。