再次问好StackExchange用户。今天的问题比平时更加复杂。我正在为我公司刚刚设置的服务器开发一个基于Web的托管面板,他们希望从互联网上管理网页。控制面板的其余部分工作得很好但是这个第三方应用程序真的很烦我,那个应用程序是phpMyAdmin!
我希望用户能够登录他们网站的“cPanel”(注意:我们没有使用cPanel或任何以前的软件),只需单击phpMyAdmin链接并登录到他们自己的特定数据库。当他们登录时,我使用与phpMyAdmin相同的加密类型将他们的sql数据库帐户详细信息传递到cookie中。查看cookie表明cookie格式正确,应该登录到系统
问题是当他们点击链接转到phpMyAdmin页面时,他们仍然会获得登录表单,即使cookie已经设置并且看起来是正确的。系统中没有错误消息,甚至没有请重新登录消息。
我已经为我的CookieAuth类包含了我的代码,所以你们可以查看它。这真的令人沮丧,因为cookie似乎是我能正确记录它们的唯一方法,并且没有很多关于如何在其他任何地方执行此操作的文档示例。
class CookieAuth {
private $_cookie_iv = null;
public function createPMAsession($username, $password, $blowfish_key) {
setCookie('pmaUser-1', $this->cookieEncrypt($username, $blowfish_key), time()+3600, "/phpmyadmin/");
setCookie('pmaAuth-1', $this->cookieEncrypt($password, $blowfish_key), null, "/phpmyadmin/");
}
private function _useOpenSSL() {
return (function_exists('openssl_encrypt') && function_exists('openssl_decrypt') && function_exists('openssl_random_pseudo_bytes') && PHP_VERSION_ID >= 50304);
}
public function enlargeKey($key) {
while(strlen($key) < 16) {
$key .= $key;
}
return substr($key, 0, 16);
}
public function getMAC($key) {
$length = strlen($key);
if($length > 16) {
return substr($key, 0, 16);
}
return $this->enlargeKey($length == 1 ? $key : substr($key, 0, -1));
}
public function getAES($key) {
$length = strlen($key);
if($length > 16) {
return substr($key, 0, 16);
}
return $this->enlargeKey($length == 1 ? $key : substr($key, 0, -1));
}
public function cookieEncrypt($data, $key) {
$mac = $this->getMAC($key);
$aes = $this->getAES($key);
$iv = $this->createIV();
if($this->_useOpenSSL()) {
$result = openssl_encrypt(
$data,
'AES-128-CBC',
$key,
0,
$iv
);
} else {
$cipher = new Crypt\AES(Crypt\Base::MODE_CBC);
$cipher->setIV($iv);
$cipher->setKey($aes);
$result = base64_encode($cipher->encrypt($data));
}
$iv = base64_encode($iv);
return json_encode(
array(
'iv' => $iv,
'mac' => hash_hmac('sha1', $iv . $result, $mac),
'payload' => $result,
)
);
}
public function getIVSize() {
if($this->_useOpenSSL()) {
return openssl_cipher_iv_length('AES-128-CBC');
}
$cipher = new Crypt\AES(Crypt\Base::MODE_CBC);
return $cipher->block_size;
}
public function createIV() {
if(!is_null($this->_cookie_iv)) {
return $this->_cookie_iv;
}
if($this->_useOpenSSL()) {
return openssl_random_pseudo_bytes($this->getIVSize());
} else {
return Crypt\Random::string($this->getIVSize());
}
}
public function setIV($vector) {
$this->_cookie_iv = $vector;
}
}
感谢您花时间阅读我的问题,希望有人能指出我正确的方向。
答案 0 :(得分:1)
这听起来与auth_type登录旨在解决的问题完全相同。你有没有特别的原因使用它?
如果失败,documentation会显示如何将用户名和密码作为查询字符串的一部分传递,从安全角度来看,这可能并不理想,但可能会为您提供进行修改的起点。
您是否尝试过将正确的用户名和密码直接发布到index.php?我不确定这是否会因安全令牌而起作用,但值得一试。
答案 1 :(得分:0)
我现在感到很愚蠢。使用signon会话,您必须在配置中声明phpMyAdmin的会话变量。我显然没有意识到这一点,在更改此会话变量后,我能够对用户进行单点登录。
答案 2 :(得分:0)
如果要使用示例文件夹中记录的 signon.php 来使用登录身份验证模式,请不要忘记在config.inc.php中更改auth_type >
更改
$cfg['Servers'][$i]['auth_type'] = 'signon';
至
$cfg['Servers'][$i]['SignonSession'] = 'SignonSession';
$cfg['Servers'][$i]['SignonURL'] = 'examples/signon.php';
还添加以下内容
{{1}}