Apache mod_session_dbd - 有人让它工作吗?

标签 apache httpd.conf

我正在将 apache mod_auth_form 从 2.0.5 升级到 2.4。配置 mod_session_dbd 时遇到问题。需要帮忙!!

我的 httpd.conf 配置 - 即使在用户通过 login.php 进行身份验证后,也无法重定向到 protected main/main.php 页面。

代码:

CREATE TABLE `session` ( 
  `id` bigint unsigned      NOT NULL auto_increment, 
  `value`   varchar(512)    NOT NULL DEFAULT '', 
  `expiry`  bigint unsigned       NOT NULL DEFAULT 0, 
  `key`     varchar(256)    NOT NULL DEFAULT '', 
  primary key (id) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

DBDriver mysql 
DBDParams "host=127.0.0.1 port=3306 dbname=aware_db user=apache pass=dhishkhk" 
DBDMin  4 
DBDKeep 8 
DBDMax  20 
DBDExptime 300 
DBDPrepareSQL "select value from session where `key` = %s and (expiry = 0 or expiry > %lld)" selectsession 
DBDPrepareSQL "delete from session where `key` = %s" deletesession 
DBDPrepareSQL "insert into session (value, expiry, `key`) values (%s, %lld,  %s)" insertsession 
DBDPrepareSQL "update session set value = %s, expiry =  %lld, `key` = %s where `key` = %s" updatesession 

<Directory "/var/www/html/main"> 
        Options         -Indexes +FollowSymLinks 

        SSLRequireSSL 
    SetHandler form-login-handler 
    AuthFormLoginRequiredLocation /login.php 
    AuthFormLoginSuccessLocation /main/main.php 
    AuthFormProvider dbd 
AuthFormUsername uid 
AuthFormPassword password 

    AuthType form 
    AuthName "My Login" 
ErrorDocument 401 /login.php 
Session On 
#SessionDBDPerUser On 
SessionDBDCookieName session path=/; 
SessionDBDSelectLabel selectsession 
SessionDBDDeleteLabel deletesession 
SessionDBDInsertLabel insertsession 
SessionDBDUpdateLabel updatesession 

        SessionDBDCookieRemove Off 

        Require                 valid-user 

    ExpiresActive       On 
    ExpiresByType       application/x-java-jnlp-file    "now" 

</Directory>

我们编写自定义的login.php 脚本,该脚本在客户端首次访问主页时调用。该脚本显示一个登录 HTML 表单,然后采用用户输入(uid 和密码)来针对 SQL 用户数据库以及 LDAP 用户帐户进行身份验证。一旦 uid/密码通过身份验证,mod_session 似乎能够设置“ session ”cookie,但无法将 session 存储到我创建的“ session ”表中。我的理解是 mod_session_dbd 会将 cookie 中的“ session ”与 session 数据库表中的信息进行匹配(通过 selectsession DBDPrepareSQL),并查看用户已经经过身份验证,并让它进入主页,而不是登录。再次检查 php 就好像它没有经过身份验证(这就是我上面的配置所发生的情况)。

mod_session_dbd 的 apache 文档很少且不完整,而且我无法在网络上的任何地方找到可供引用的 mod_session_dbd 的任何工作示例。甚至不知道如何调试 mod_session_dbd (LogLevel 设置似乎没有得到痕迹)...任何帮助/建议将不胜感激!!

最佳答案

我认为这里的问题是您的外部登录脚本不是 mod_auth_form 的“身份验证提供程序”,无法直接与 mod_auth_form 通信身份验证已成功。 (只有在此之后 session 才会被插入到数据库中)。然而,这种通信可以间接完成。继续阅读...

我也有类似的设置。我最终做的是让我的外部登录脚本模仿 mod_session_dbd 并在成功身份验证后自行插入数据库条目。之后,再次将页面重定向到同一保护区。使用类似的东西(这是 PHP 代码)

header("Location: $toURL");

为了 mod_session_dbd 的目的,您的 session 表必须至少有三列:uuid、session 和 expiry。 (但是 session 表也将兼作 mod_authn_dbd 的 session 密码表。请参阅下面的讨论。)

mod_auth_form 会在 cookie 中为您生成 uuid,只要您有以下指令。您的脚本可以从 cookie 中读取值(例如,从您的 PHP 脚本中)

SessionDBDCookieName uuid

mod_auth_form 期望 session 具有三个键值对,如下所示:

Realm-user=foo&Realm-pw=bar&expiry=1453231822000000

(过期时间是自 Epoch 以来的微秒数:即 unix 时间乘以 1,000,000)

上面还假设您已将 AuthName 配置为“Realm”

AuthName "Realm"

现在,虽然登录脚本无法将成功的身份验证结果传达给 mod_auth_form,但它可以通过将 uuid 的 cookie 与 session 表的匹配行来间接实现此目的。

接下来,我将 mod_auth_form 配置为使用 mod_authn_dbd 作为“身份验证提供程序”。然而,后者并不进行真正的身份验证(登录脚本已经完成了身份验证)。相反,它只是检查请求中是否存在 session (uuid 的 cookie 与 session 表中的匹配行)。

因此,我所做的就是向 session 表中再添加一列(称为“session_pw”),然后配置 mod_authn_dbd 以使用以下查询进行密码查找(我使用的是 MySQL):

AuthFormProvider dbd
AuthDBDUserPWQuery "SELECT session_pw FROM web_sessions WHERE uuid = %s and expiry>unix_timestamp()*1000000"

关键是要知道 mod_authn_dbd 期望什么,而这并没有很好的记录 - 它期望上述查询中的密码 (session_pw) 值已通过 Apache 允许的格式之一加密(请参阅 this )。就我而言,我决定使用 crypt,因此在 session 表中,我的登录脚本实际上为 session_pw 插入以下值

convert(encrypt(?, 'Cm') using ascii)

哪里?绑定(bind)到我生成的 session 密码(只是一个随机数)——这个相同的值也必须放入上面显示的 session 值中(即替换“Realm-”的键值对的占位符“bar”)密码”)。

一旦mod_authn_dbd发现密码匹配,它会让mod_auth_form知道,后者会让请求进入保护区。 (所以这里我所做的是使用密码检查来测试 session 是否存在)

我需要的另一个技巧是禁用 session 插入并更新 mod_session_dbd 的查询(因为我的登录脚本现在执行插入)。我通过以下两个指令做到了这一点:

# we disable session insertion by mod_auth_form/mod_session_dbd -- login.php will insert the session
DBDPrepareSQL "select %s, %lld,  %s" insertsession
# we disable session update by mod_auth_form/mod_session_dbd
DBDPrepareSQL "select %s, %lld,  %s, %s" updatesession

最后,我想我可以分享我的 session 表的架构,以防万一这可以帮助某人:

CREATE TABLE `web_sessions` (
  `id` int(11)  NOT NULL AUTO_INCREMENT,
  `u_name`      varchar(31) NOT NULL,   -- used for debugging only
  `session_pw`  varchar(256) NOT NULL,  -- encrypte by convert(encrypt(?, 'Cm') using ascii)
  `session`     varchar(256) NOT NULL,  -- mod_session_dbd's value
  `expiry`      bigint NOT NULL,        -- mod_session_dbd's expiry: microsecs since Epoch
  `uuid`        varchar(256) NOT NULL,  -- mod_session_dbd's key: uuid
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `uuid` (`uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

希望这有帮助!

关于Apache mod_session_dbd - 有人让它工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34755791/

相关文章:

Apache HTTP 服务器 : How to restrict access to directory listings to some ip ranges?

Apache Web服务器: AH00125: Request exceeded the limit of 10 subrequest with FallbackResource

apache - 节点红色 - 从端口 1880 重定向到子目录后丢失连接

php - 权限被拒绝 : httpd: could not open error log file/etc/httpd/logs/error_log

php - 在 htdocs 文件夹之外制作 XAMPP/Apache 服务文件

python - 如何在 apache 上配置 django 并在 apache 中创建 https 以便 django url 应使用 https ://<ip>:80 port 打开

apache - 将所有 URL 重定向到 httpd.conf 中的单个页面

php - Apache 404 文件匹配

java - 处理由图像标记引起的过多 HTTPRequest

Apache 和 Tomcat 代理