diff options
author | wei <> | 2006-07-05 07:35:50 +0000 |
---|---|---|
committer | wei <> | 2006-07-05 07:35:50 +0000 |
commit | b6dfb6c447cf502e694d299dbda1b2e092c3312d (patch) | |
tree | b1bbd0abf857cca4b297d575942efa60edd12480 /test_tools/simpletest/docs/en/authentication_documentation.html | |
parent | b5c7c7b77d33aa3e04ed6c16a489a2076a30f57a (diff) |
move tests to test_tools
Diffstat (limited to 'test_tools/simpletest/docs/en/authentication_documentation.html')
-rwxr-xr-x | test_tools/simpletest/docs/en/authentication_documentation.html | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/test_tools/simpletest/docs/en/authentication_documentation.html b/test_tools/simpletest/docs/en/authentication_documentation.html new file mode 100755 index 00000000..0623023c --- /dev/null +++ b/test_tools/simpletest/docs/en/authentication_documentation.html @@ -0,0 +1,320 @@ +<html> +<head> +<META http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>SimpleTest documentation for testing log-in and authentication</title> +<link rel="stylesheet" type="text/css" href="docs.css" title="Styles"> +</head> +<body> +<div class="menu_back"> +<div class="menu"> +<h2> +<a href="index.html">SimpleTest</a> +</h2> +<ul> +<li> +<a href="overview.html">Overview</a> +</li> +<li> +<a href="unit_test_documentation.html">Unit tester</a> +</li> +<li> +<a href="group_test_documentation.html">Group tests</a> +</li> +<li> +<a href="server_stubs_documentation.html">Server stubs</a> +</li> +<li> +<a href="mock_objects_documentation.html">Mock objects</a> +</li> +<li> +<a href="partial_mocks_documentation.html">Partial mocks</a> +</li> +<li> +<a href="reporter_documentation.html">Reporting</a> +</li> +<li> +<a href="expectation_documentation.html">Expectations</a> +</li> +<li> +<a href="web_tester_documentation.html">Web tester</a> +</li> +<li> +<a href="form_testing_documentation.html">Testing forms</a> +</li> +<li> +<span class="chosen">Authentication</span> +</li> +<li> +<a href="browser_documentation.html">Scriptable browser</a> +</li> +</ul> +</div> +</div> +<h1>Authentication documentation</h1> +<div class="content"> + + <p> + One of the trickiest, and yet most important, areas + of testing web sites is the security. + Testing these schemes is one of the core goals of + the SimpleTest web tester. + </p> + + <p> +<a class="target" name="basic"> +<h2>Basic HTTP authentication</h2> +</a> +</p> + <p> + If you fetch a page protected by basic authentication then + rather than receiving content, you will instead get a 401 + header. + We can illustrate this with this test... +<pre> +class AuthenticationTest extends WebTestCase {<strong> + function test401Header() { + $this->get('http://www.lastcraft.com/protected/'); + $this->showHeaders(); + }</strong> +} +</pre> + This allows us to see the challenge header... + <div class="demo"> + <h1>File test</h1> +<pre style="background-color: lightgray; color: black"> +HTTP/1.1 401 Authorization Required +Date: Sat, 18 Sep 2004 19:25:18 GMT +Server: Apache/1.3.29 (Unix) PHP/4.3.4 +WWW-Authenticate: Basic realm="SimpleTest basic authentication" +Connection: close +Content-Type: text/html; charset=iso-8859-1 +</pre> + <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete. + <strong>0</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div> + </div> + We are trying to get away from visual inspection though, and so SimpleTest + allows to make automated assertions against the challenge. + Here is a thorough test of our header... +<pre> +class AuthenticationTest extends WebTestCase { + function test401Header() { + $this->get('http://www.lastcraft.com/protected/');<strong> + $this->assertAuthentication('Basic'); + $this->assertResponse(401); + $this->assertRealm('SimpleTest basic authentication');</strong> + } +} +</pre> + Any one of these tests would normally do on it's own depending + on the amount of detail you want to see. + </p> + <p> + Most of the time we are not interested in testing the + authentication itself, but want to get past it to test + the pages underneath. + As soon as the challenge has been issued we can reply with + an authentication response... +<pre> +class AuthenticationTest extends WebTestCase { + function testAuthentication() { + $this->get('http://www.lastcraft.com/protected/');<strong> + $this->authenticate('Me', 'Secret');</strong> + $this->assertTitle(...); + } +} +</pre> + The username and password will now be sent with every + subsequent request to that directory and subdirectories. + You will have to authenticate again if you step outside + the authenticated directory, but SimpleTest is smart enough + to merge subdirectories into a common realm. + </p> + <p> + You can shortcut this step further by encoding the log in + details straight into the URL... +<pre> +class AuthenticationTest extends WebTestCase { + function testCanReadAuthenticatedPages() { + $this->get('http://<strong>Me:Secret@</strong>www.lastcraft.com/protected/'); + $this->assertTitle(...); + } +} +</pre> + If your username or password has special characters, then you + will have to URL encode them or the request will not be parsed + correctly. + Also this header will not be sent on subsequent requests if + you request a page with a fully qualified URL. + If you navigate with relative URLs though, the authentication + information will be preserved. + </p> + <p> + Only basic authentication is currently supported and this is + only really secure in tandem with HTTPS connections. + This is usually enough to protect test server from prying eyes, + however. + Digest authentication and NTLM authentication may be added + in the future. + </p> + + <p> +<a class="target" name="cookies"> +<h2>Cookies</h2> +</a> +</p> + <p> + Basic authentication doesn't give enough control over the + user interface for web developers. + More likely this functionality will be coded directly into + the web architecture using cookies and complicated timeouts. + </p> + <p> + Starting with a simple log-in form... +<pre> +<form> + Username: + <input type="text" name="u" value="" /><br /> + Password: + <input type="password" name="p" value="" /><br /> + <input type="submit" value="Log in" /> +</form> +</pre> + Which looks like... + </p> + <p> + <form class="demo"> + Username: + <input type="text" name="u" value=""> +<br> + Password: + <input type="password" name="p" value=""> +<br> + <input type="submit" value="Log in"> + </form> + </p> + <p> + Let's suppose that in fetching this page a cookie has been + set with a session ID. + We are not going to fill the form in yet, just test that + we are tracking the user. + Here is the test... +<pre> +class LogInTest extends WebTestCase { + function testSessionCookieSetBeforeForm() { + $this->get('http://www.my-site.com/login.php');<strong> + $this->assertCookie('SID');</strong> + } +} +</pre> + All we are doing is confirming that the cookie is set. + As the value is likely to be rather cryptic it's not + really worth testing this. + </p> + <p> + The rest of the test would be the same as any other form, + but we might want to confirm that we still have the same + cookie after log-in as before we entered. + We wouldn't want to lose track of this after all. + Here is a possible test for this... +<pre> +class LogInTest extends WebTestCase { + ... + function testSessionCookieSameAfterLogIn() { + $this->get('http://www.my-site.com/login.php');<strong> + $session = $this->getCookie('SID'); + $this->setField('u', 'Me'); + $this->setField('p', 'Secret'); + $this->clickSubmit('Log in'); + $this->assertWantedPattern('/Welcome Me/'); + $this->assertCookie('SID', $session);</strong> + } +} +</pre> + This confirms that the session identifier is maintained + afer log-in. + </p> + <p> + We could even attempt to spoof our own system by setting + arbitrary cookies to gain access... +<pre> +class LogInTest extends WebTestCase { + ... + function testSessionCookieSameAfterLogIn() { + $this->get('http://www.my-site.com/login.php');<strong> + $this->setCookie('SID', 'Some other session'); + $this->get('http://www.my-site.com/restricted.php');</strong> + $this->assertWantedPattern('/Access denied/'); + } +} +</pre> + Is your site protected from this attack? + </p> + + <p> +<a class="target" name="session"> +<h2>Browser sessions</h2> +</a> +</p> + <p> + If you are testing an authentication system a critical piece + of behaviour is what happens when a user logs back in. + We would like to simulate closing and reopening a browser... +<pre> +class LogInTest extends WebTestCase { + ... + function testLoseAuthenticationAfterBrowserClose() { + $this->get('http://www.my-site.com/login.php'); + $this->setField('u', 'Me'); + $this->setField('p', 'Secret'); + $this->clickSubmit('Log in'); + $this->assertWantedPattern('/Welcome Me/');<strong> + + $this->restart(); + $this->get('http://www.my-site.com/restricted.php'); + $this->assertWantedPattern('/Access denied/');</strong> + } +} +</pre> + The <span class="new_code">WebTestCase::restart()</span> method will + preserve cookies that have unexpired timeouts, but throw away + those that are temporary or expired. + You can optionally specify the time and date that the restart + happened. + </p> + <p> + Expiring cookies can be a problem. + After all, if you have a cookie that expires after an hour, + you don't want to stall the test for an hour while the + cookie passes it's timeout. + </p> + <p> + To push the cookies over the hour limit you can age them + before you restart the session... +<pre> +class LogInTest extends WebTestCase { + ... + function testLoseAuthenticationAfterOneHour() { + $this->get('http://www.my-site.com/login.php'); + $this->setField('u', 'Me'); + $this->setField('p', 'Secret'); + $this->clickSubmit('Log in'); + $this->assertWantedPattern('/Welcome Me/'); + <strong> + $this->ageCookies(3600);</strong> + $this->restart(); + $this->get('http://www.my-site.com/restricted.php'); + $this->assertWantedPattern('/Access denied/'); + } +} +</pre> + After the restart it will appear that cookies are an + hour older and any that pass their expiry will have + disappeared. + </p> + + </div> +<div class="copyright"> + Copyright<br>Marcus Baker, Jason Sweat, Perrick Penet 2004 + </div> +</body> +</html> |