From dde49061954c4c11c134575122564b1e793f7b64 Mon Sep 17 00:00:00 2001 From: "mariano.iglesias" Date: Mon, 10 Nov 2008 17:18:00 +0000 Subject: [PATCH] Adding patch by dardosordi. Making all calls to header in SecurityComponent go through Controller. Fixing issue where invalid basic auth credentials would not trigger another login request. Added tests, fixes #5732 git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7858 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/controller/components/security.php | 9 ++--- .../controller/components/security.test.php | 38 ++++++++++++++++++- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/cake/libs/controller/components/security.php b/cake/libs/controller/components/security.php index 921616ef2..077883c3b 100644 --- a/cake/libs/controller/components/security.php +++ b/cake/libs/controller/components/security.php @@ -309,7 +309,7 @@ class SecurityComponent extends Object { return null; } /** - * Generates the text of an HTTP-authentication request header from an array of options.. + * Generates the text of an HTTP-authentication request header from an array of options. * * @param array $options Set of options for header * @return string HTTP-authentication request header @@ -323,7 +323,7 @@ class SecurityComponent extends Object { if (strtolower($options['type']) == 'digest') { $out[] = 'qop="auth"'; - $out[] = 'nonce="' . uniqid() . '"'; //str_replace('-', '', String::uuid()) + $out[] = 'nonce="' . uniqid() . '"'; $out[] = 'opaque="' . md5($options['realm']).'"'; } @@ -387,6 +387,7 @@ class SecurityComponent extends Object { $code = 404; if ($error == 'login') { $code = 401; + $controller->header($this->loginRequest()); } $controller->redirect(null, $code, true); } else { @@ -499,8 +500,7 @@ class SecurityComponent extends Object { $login = $this->loginCredentials($this->loginOptions['type']); if ($login == null) { - // User hasn't been authenticated yet - header($this->loginRequest()); + $controller->header($this->loginRequest()); if (!empty($this->loginOptions['prompt'])) { $this->_callback($controller, $this->loginOptions['prompt']); @@ -512,7 +512,6 @@ class SecurityComponent extends Object { $this->_callback($controller, $this->loginOptions['login'], array($login)); } else { if (strtolower($this->loginOptions['type']) == 'digest') { - // Do digest authentication if ($login && isset($this->loginUsers[$login['username']])) { if ($login['response'] == $this->generateDigestResponseHash($login)) { return true; diff --git a/cake/tests/cases/libs/controller/components/security.test.php b/cake/tests/cases/libs/controller/components/security.test.php index c405f696b..c0b2924b4 100644 --- a/cake/tests/cases/libs/controller/components/security.test.php +++ b/cake/tests/cases/libs/controller/components/security.test.php @@ -66,6 +66,13 @@ class SecurityTestController extends Controller { * @access public */ var $failed = false; +/** + * Used for keeping track of headers in test + * + * @var array + * @access public + */ + var $testHeaders = array(); /** * fail method * @@ -87,6 +94,16 @@ class SecurityTestController extends Controller { function redirect($option, $code, $exit) { return $code; } +/** + * Conveinence method for header() + * + * @param string $status + * @return void + * @access public + */ + function header($status) { + $this->testHeaders[] = $status; + } } /** @@ -551,7 +568,7 @@ DIGEST; $result = $this->Controller->Security->validatePost($this->Controller); $this->assertTrue($result); } - + /** * test ValidatePost with multiple select elements. * @@ -988,6 +1005,25 @@ DIGEST; $result = $this->Controller->Security->validatePost($this->Controller); $this->assertTrue($result); } +/** + * testInvalidAuthHeaders method + * + * @access public + * @return void + */ + function testInvalidAuthHeaders() { + $this->Controller->Security->blackHoleCallback = null; + $_SERVER['PHP_AUTH_USER'] = 'admin'; + $_SERVER['PHP_AUTH_PW'] = 'password'; + $realm = 'cakephp.org'; + $loginData = array('type' => 'basic', 'realm' => $realm); + $this->Controller->Security->requireLogin($loginData); + $this->Controller->Security->startup($this->Controller); + + $expected = 'WWW-Authenticate: Basic realm="'.$realm.'"'; + $this->assertEqual(count($this->Controller->testHeaders), 1); + $this->assertEqual(current($this->Controller->testHeaders), $expected); + } } ?> \ No newline at end of file