如何测试认证系统?
编辑:在抱怨为自己分配答案后,我想更新一下所提供的答案并不令人满意。没有人站出来明确表示这是你的问题,这样做你就会有解决方案。仅仅提出建议并不足以获得赏金。最后,问题出在服务器设置上,在对服务器会话进行一些研究并查看 Stackoverflow/Serverfault 后,我能够确定如何最好地解决此问题。因此,我并不觉得将自己的答案标记为正确答案是不公平的。
我有一个基于 php 的身份验证系统,它依赖 LDAP 来验证身份,并使用会话来维护用户的身份验证状态。
最近我注意到它似乎将我推回登录页面,就像我的会话已过期一样。问题是,它似乎不是出于我注意到的任何特定原因,并且我不确定如何调试/测试这样的东西。
这是我启动会话的身份验证函数:
function authenticateUser($user, $password){
//assuming ldap connection and verification of user login/pass
//this is what will happen with authenticate user which is called
//when user submits login/pass on authentication form.
$_SESSION['id'] = $uID;
$time = time();
$_SESSION['time'] = $time;
$_SESSION['lastActivity'] = $time;
$_SESSION['expiration'] = $time+$cookieExpiration;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['secret'] = md5(rand());
$_SESSION['userHash'] = getSessionHash();
$_SESSION['firstLogin'] = isFirstLogin($user);
//assign cookie to user and log authentication
giveCookie("userHash", $_SESSION['userHash'],0);
logAuthenticationAttempt($user, $_SERVER['REMOTE_ADDR'], 1);
return true;
}//end authenticateUser
提供 cookie 函数:
function giveCookie($name, $value, $expiration=0){
global $path, $site;
setcookie("userHash", $_SESSION['userHash'], $expiration, $path, $site, true, true);
}//end giveCookie
这是我在每个页面上调用的函数,以验证用户是否已通过身份验证,然后允许他们继续进行需要身份验证状态的操作:
function isValidUser(){
global $links; global $userName; global $userID; global $cookieExpiration;
if(isset($_COOKIE['userHash']) and isset($_SESSION['userHash'])){
if($_COOKIE['userHash'] == $_SESSION['userHash']){
$userName = $_SESSION['nameN'];
$userID = $_SESSION['id'];
//update userHash cookie for additinoal expiration time this way session
$time = time();
$expiration = $time+$cookieExpiration;
$_SESSION['lastActivity'] = $time;
giveCookie("userHash", $_SESSION['userHash'],0);
$_SESSION['expiration'] = $expiration;
return true;
}
}
return false;
}//end isvalidUser()
有关如何测试此功能的任何建议或反馈将不胜感激。我想弄清楚为什么有时在执行某些操作后我会被推回到登录页面。
在请求身份验证的页面上,我在顶部执行的操作如下:
if(!isValidUser()){changePage($links['login']."?refer=".$links['requestHelp']);}
//note: changePage is just a function for header("location: somepage.php");
EDIT: After a complaint about assigning myself the answer, I want to update that the answers provided were not satisfactory. No one came out and explicitly said this is your problem, do this and you will have a resolution. Mere suggestions are not sufficient to merit a bounty award. Lastly, the problem was with server settings and after doing some research on server sessions and looking at Stackoverflow/Serverfault I was able to determine how to best resolve this problem. Therefore, I did not feel it was unjust to mark my own answer as the correct one.
I have a php based authentication system which relies on LDAP to verify identity and uses sessions to maintain users authenticated status.
Lately I noticed that it appears to be pushing me back to the login page like my session expired. The problem is that it does not appear to be for any specific reason that I have noticed and I am not sure how to debug/test something like this.
Here is my authentication function which starts the session:
function authenticateUser($user, $password){
//assuming ldap connection and verification of user login/pass
//this is what will happen with authenticate user which is called
//when user submits login/pass on authentication form.
$_SESSION['id'] = $uID;
$time = time();
$_SESSION['time'] = $time;
$_SESSION['lastActivity'] = $time;
$_SESSION['expiration'] = $time+$cookieExpiration;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['secret'] = md5(rand());
$_SESSION['userHash'] = getSessionHash();
$_SESSION['firstLogin'] = isFirstLogin($user);
//assign cookie to user and log authentication
giveCookie("userHash", $_SESSION['userHash'],0);
logAuthenticationAttempt($user, $_SERVER['REMOTE_ADDR'], 1);
return true;
}//end authenticateUser
Give cookie function:
function giveCookie($name, $value, $expiration=0){
global $path, $site;
setcookie("userHash", $_SESSION['userHash'], $expiration, $path, $site, true, true);
}//end giveCookie
Here is my function which is called on each page to verify the user is authenticated before allowing them to proceed with action requiring authenticated status:
function isValidUser(){
global $links; global $userName; global $userID; global $cookieExpiration;
if(isset($_COOKIE['userHash']) and isset($_SESSION['userHash'])){
if($_COOKIE['userHash'] == $_SESSION['userHash']){
$userName = $_SESSION['nameN'];
$userID = $_SESSION['id'];
//update userHash cookie for additinoal expiration time this way session
$time = time();
$expiration = $time+$cookieExpiration;
$_SESSION['lastActivity'] = $time;
giveCookie("userHash", $_SESSION['userHash'],0);
$_SESSION['expiration'] = $expiration;
return true;
}
}
return false;
}//end isvalidUser()
Any advice or feedback on how to test this would be appreciated. I am looking to figure out why occasionally after performing some action I get pushed back to the login page.
On a page which request authentication what I do at the top is the following:
if(!isValidUser()){changePage($links['login']."?refer=".$links['requestHelp']);}
//note: changePage is just a function for header("location: somepage.php");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您似乎混淆了身份验证、授权和会话管理。如果您想测试所有 3 个功能,那么您将需要某种能够进行脚本化、有状态 HTTP 会话重放的自动化测试工具(例如使用 Perl 的 http::recorder / www::mechaninze)。
OTOH,如果您想使用已部署的应用程序调查会话管理,那么我建议您检测登录页面以捕获有关当前会话以及用户如何路由到那里的信息。您还应该考虑在网络服务器上记录会话 cookie。
You seem to be confusing authentication, authorization and session management. If you want to test all 3 then you'll need some sort of automated test tool capable of scriptable, stateful HTTP session replay (e.g. http::recorder / www::mechaninze with Perl).
OTOH if you want to investigate the session management using your deployed application, then I'd recommend instrumenting the login page to capture information about the current session and how the user got routed there. You should also consider logging the session cookie on the webserver.
不确定您目前使用什么测试软件,但我强烈推荐 Selenium。它允许您通过浏览器运行脚本测试,有效地模拟最终用户将执行的操作和看到的内容。
Not sure what testing software you use at the moment, but I'd strongly recommend Selenium. It allows you to run scripted tests through the browser, effectively simulating what an end user would do and see.
编写功能测试。您可以使用 SimpleTest 的 WebTestCase 来完成类似的事情。请参阅文档:http://www.simpletest.org/en/web_tester_documentation.html
当然,您也可以尝试将代码分解为更小的部分,以便更容易单独测试。现在,您的身份验证系统与服务器状态紧密耦合(例如会话管理)。您可以将两者解耦,从而能够在单元测试中测试身份验证系统,而不是功能测试。
Write a functional test. You can use SimpleTest's WebTestCase for stuff like this. See the documentation at: http://www.simpletest.org/en/web_tester_documentation.html
Of course, you could also try to break the code down into smaller bits that can easier be tested individually. Right now, your authentication system is tightly coupled to the server state (eg. the session management). You could decouple the two and thus be able to test the authentication system in a unit test, rather than a functional test.
服务器可能会覆盖他们的会话 cookie,这将更改会话哈希,然后它将不等于他们拥有客户端的 cookie。看来你想太多了。您不需要在他们的系统上设置 cookie 来验证它们。 $_SESSION var 将为您处理这一切。
如果他们通过了挑战,那么他们就会设置一个 $_SESSION 变量来赋予他们身份验证级别。
不要像你一样将 $_SESSION 传递给其他变量。不要使用 $username = $_SESSION['username'] 因为现在您有一个不安全的 var ($username),其中可能包含安全数据。但也可能不会。
每当您显示会话信息时,请确保它来自马口。
The server is probably overwriting their session cookie, which will change the session hash and then it won't equal the cookie they have clientside. You appear to be overthinking this. You don't need to set a cookie on their system to verify them. The $_SESSION var will handle it all for you.
If they pass the challenge, then they have a $_SESSION var that is set that gives them auth levels.
Don't pass $_SESSION off to other vars like you are. Don't go $username = $_SESSION['username'] because now you have a var that is nonsecure ($username) that could have secured data in it. But it might not.
Whenever you are displaying session info, make sure it came from the horse's mouth.
深入了解 session.configuration
我会(如果你不愿意考虑您的概念)更改
isValidUser
以记录您在return false
之前可以获得的内容并且您确定您调用了
session_start()
在isValidUser()
之前Take a deep look at session.configuration
i would (if your not willing to think over your concept) change the
isValidUser
to log what ever you can get beforereturn false
And are you sure you called
session_start()
beforeisValidUser()
看来这是服务器本身的简单配置错误。由于该服务器环境是数百个站点的共享环境,因此我无法修改 php.ini 等中的服务器范围设置。
我能做的是......
这已经解决了问题,它出现在会话过期之前没有正确设置,这将针对这个特定的应用程序进行相应的设置。
It appears that this was a simple misconfiguration of the server itself. Being that this server environment is a shared environment for hundreds of sites, I do not have ability to modify server wide settings in php.ini and the like.
What I was able to do though is...
This has resolved the issue, it appears before the session expiration was not set properly and this will set it accordingly for this specific application.